From 6db535a34086c978301ce6e2c6d48ae7c4e60d35 Mon Sep 17 00:00:00 2001
From: Richie McIlroy <33632126+richiemcilroy@users.noreply.github.com>
Date: Fri, 31 Oct 2025 16:01:00 -0700
Subject: [PATCH 01/56] wip: Web recorder
---
apps/desktop/src/routes/editor/Player.tsx | 822 +++---
.../src/routes/editor/Timeline/ClipTrack.tsx | 1532 +++++-----
apps/web/app/(org)/dashboard/caps/Caps.tsx | 2 +
.../caps/components/EmptyCapState.tsx | 5 +-
.../caps/components/UploadCapButton.tsx | 27 +-
.../WebRecorderDialog/CameraPreviewWindow.tsx | 311 +++
.../WebRecorderDialog/CameraSelector.tsx | 139 +
.../WebRecorderDialog/MicrophoneSelector.tsx | 141 +
.../WebRecorderDialog/RecordingButton.tsx | 40 +
.../RecordingModeSelector.tsx | 88 +
.../WebRecorderDialog/WebRecorderDialog.tsx | 287 ++
.../WebRecorderDialogHeader.tsx | 98 +
.../WebRecorderDialog/useCameraDevices.ts | 56 +
.../WebRecorderDialog/useMediaPermission.ts | 106 +
.../WebRecorderDialog/useMicrophoneDevices.ts | 56 +
.../WebRecorderDialog/useWebRecorder.ts | 766 +++++
.../web-recorder-constants.ts | 32 +
.../WebRecorderDialog/web-recorder-types.ts | 15 +
.../(org)/dashboard/caps/components/index.ts | 1 +
.../caps/components/sendProgressUpdate.ts | 23 +
packages/web-backend/src/Videos/VideosRpcs.ts | 121 +-
packages/web-backend/src/Videos/index.ts | 176 +-
packages/web-domain/src/Video.ts | 44 +
pnpm-lock.yaml | 2470 ++---------------
24 files changed, 3827 insertions(+), 3531 deletions(-)
create mode 100644 apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/CameraPreviewWindow.tsx
create mode 100644 apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/CameraSelector.tsx
create mode 100644 apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/MicrophoneSelector.tsx
create mode 100644 apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/RecordingButton.tsx
create mode 100644 apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/RecordingModeSelector.tsx
create mode 100644 apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/WebRecorderDialog.tsx
create mode 100644 apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/WebRecorderDialogHeader.tsx
create mode 100644 apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/useCameraDevices.ts
create mode 100644 apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/useMediaPermission.ts
create mode 100644 apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/useMicrophoneDevices.ts
create mode 100644 apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/useWebRecorder.ts
create mode 100644 apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/web-recorder-constants.ts
create mode 100644 apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/web-recorder-types.ts
create mode 100644 apps/web/app/(org)/dashboard/caps/components/sendProgressUpdate.ts
diff --git a/apps/desktop/src/routes/editor/Player.tsx b/apps/desktop/src/routes/editor/Player.tsx
index 79f8820ae2..c97e23c6a8 100644
--- a/apps/desktop/src/routes/editor/Player.tsx
+++ b/apps/desktop/src/routes/editor/Player.tsx
@@ -13,425 +13,425 @@ import { useEditorShortcuts } from "./useEditorShortcuts";
import { formatTime } from "./utils";
export function Player() {
- const {
- project,
- editorInstance,
- setDialog,
- totalDuration,
- editorState,
- setEditorState,
- zoomOutLimit,
- setProject,
- } = useEditorContext();
-
- // Load captions on mount
- onMount(async () => {
- if (editorInstance && editorInstance.path) {
- // Still load captions into the store since they will be used by the GPU renderer
- await captionsStore.loadCaptions(editorInstance.path);
-
- // Synchronize captions settings with project configuration
- // This ensures the GPU renderer will receive the caption settings
- if (editorInstance && project) {
- const updatedProject = { ...project };
-
- // Add captions data to project configuration if it doesn't exist
- if (
- !updatedProject.captions &&
- captionsStore.state.segments.length > 0
- ) {
- updatedProject.captions = {
- segments: captionsStore.state.segments.map((segment) => ({
- id: segment.id,
- start: segment.start,
- end: segment.end,
- text: segment.text,
- })),
- settings: {
- enabled: captionsStore.state.settings.enabled,
- font: captionsStore.state.settings.font,
- size: captionsStore.state.settings.size,
- color: captionsStore.state.settings.color,
- backgroundColor: captionsStore.state.settings.backgroundColor,
- backgroundOpacity: captionsStore.state.settings.backgroundOpacity,
- position: captionsStore.state.settings.position,
- bold: captionsStore.state.settings.bold,
- italic: captionsStore.state.settings.italic,
- outline: captionsStore.state.settings.outline,
- outlineColor: captionsStore.state.settings.outlineColor,
- exportWithSubtitles:
- captionsStore.state.settings.exportWithSubtitles,
- },
- };
-
- // Update the project with captions data
- setProject(updatedProject);
-
- // Save the updated project configuration
- await commands.setProjectConfig(updatedProject);
- }
- }
- }
- });
-
- // Continue to update current caption when playback time changes
- // This is still needed for CaptionsTab to highlight the current caption
- createEffect(() => {
- const time = editorState.playbackTime;
- // Only update captions if we have a valid time and segments exist
- if (
- time !== undefined &&
- time >= 0 &&
- captionsStore.state.segments.length > 0
- ) {
- captionsStore.updateCurrentCaption(time);
- }
- });
-
- const [canvasContainerRef, setCanvasContainerRef] =
- createSignal();
- const containerBounds = createElementBounds(canvasContainerRef);
-
- const isAtEnd = () => {
- const total = totalDuration();
- return total > 0 && total - editorState.playbackTime <= 0.1;
- };
-
- const cropDialogHandler = () => {
- const display = editorInstance.recordings.segments[0].display;
- setDialog({
- open: true,
- type: "crop",
- position: {
- ...(project.background.crop?.position ?? { x: 0, y: 0 }),
- },
- size: {
- ...(project.background.crop?.size ?? {
- x: display.width,
- y: display.height,
- }),
- },
- });
- };
-
- createEffect(() => {
- if (isAtEnd() && editorState.playing) {
- commands.stopPlayback();
- setEditorState("playing", false);
- }
- });
-
- const handlePlayPauseClick = async () => {
- try {
- if (isAtEnd()) {
- await commands.stopPlayback();
- setEditorState("playbackTime", 0);
- await commands.seekTo(0);
- await commands.startPlayback(FPS, OUTPUT_SIZE);
- setEditorState("playing", true);
- } else if (editorState.playing) {
- await commands.stopPlayback();
- setEditorState("playing", false);
- } else {
- // Ensure we seek to the current playback time before starting playback
- await commands.seekTo(Math.floor(editorState.playbackTime * FPS));
- await commands.startPlayback(FPS, OUTPUT_SIZE);
- setEditorState("playing", true);
- }
- if (editorState.playing) setEditorState("previewTime", null);
- } catch (error) {
- console.error("Error handling play/pause:", error);
- setEditorState("playing", false);
- }
- };
-
- // Register keyboard shortcuts in one place
- useEditorShortcuts(() => {
- const el = document.activeElement;
- if (!el) return true;
- const tagName = el.tagName.toLowerCase();
- const isContentEditable = el.getAttribute("contenteditable") === "true";
- return !(
- tagName === "input" ||
- tagName === "textarea" ||
- isContentEditable
- );
- }, [
- {
- combo: "S",
- handler: () =>
- setEditorState(
- "timeline",
- "interactMode",
- editorState.timeline.interactMode === "split" ? "seek" : "split",
- ),
- },
- {
- combo: "Mod+=",
- handler: () =>
- editorState.timeline.transform.updateZoom(
- editorState.timeline.transform.zoom / 1.1,
- editorState.playbackTime,
- ),
- },
- {
- combo: "Mod+-",
- handler: () =>
- editorState.timeline.transform.updateZoom(
- editorState.timeline.transform.zoom * 1.1,
- editorState.playbackTime,
- ),
- },
- {
- combo: "Space",
- handler: async () => {
- const prevTime = editorState.previewTime;
-
- if (!editorState.playing) {
- if (prevTime !== null) setEditorState("playbackTime", prevTime);
-
- await commands.seekTo(Math.floor(editorState.playbackTime * FPS));
- }
-
- await handlePlayPauseClick();
- },
- },
- ]);
-
- return (
-
-
-
-
cropDialogHandler()}
- leftIcon={}
- >
- Crop
-
-
-
-
-
-
- /
-
-
-
-
-
-
-
-
-
-
-
-
- tooltipText="Toggle Split"
- kbd={["S"]}
- pressed={editorState.timeline.interactMode === "split"}
- onChange={(v: boolean) =>
- setEditorState("timeline", "interactMode", v ? "split" : "seek")
- }
- as={KToggleButton}
- variant="danger"
- leftIcon={
-
- }
- />
-
-
- {
- editorState.timeline.transform.updateZoom(
- editorState.timeline.transform.zoom * 1.1,
- editorState.playbackTime,
- );
- }}
- class="text-gray-12 size-5 will-change-[opacity] transition-opacity hover:opacity-70"
- />
-
-
- {
- editorState.timeline.transform.updateZoom(
- editorState.timeline.transform.zoom / 1.1,
- editorState.playbackTime,
- );
- }}
- class="text-gray-12 size-5 will-change-[opacity] transition-opacity hover:opacity-70"
- />
-
- {
- editorState.timeline.transform.updateZoom(
- (1 - v) * zoomOutLimit(),
- editorState.playbackTime,
- );
- }}
- formatTooltip={() =>
- `${editorState.timeline.transform.zoom.toFixed(
- 0,
- )} seconds visible`
- }
- />
-
-
-
- );
+ const {
+ project,
+ editorInstance,
+ setDialog,
+ totalDuration,
+ editorState,
+ setEditorState,
+ zoomOutLimit,
+ setProject,
+ } = useEditorContext();
+
+ // Load captions on mount
+ onMount(async () => {
+ if (editorInstance && editorInstance.path) {
+ // Still load captions into the store since they will be used by the GPU renderer
+ await captionsStore.loadCaptions(editorInstance.path);
+
+ // Synchronize captions settings with project configuration
+ // This ensures the GPU renderer will receive the caption settings
+ if (editorInstance && project) {
+ const updatedProject = { ...project };
+
+ // Add captions data to project configuration if it doesn't exist
+ if (
+ !updatedProject.captions &&
+ captionsStore.state.segments.length > 0
+ ) {
+ updatedProject.captions = {
+ segments: captionsStore.state.segments.map((segment) => ({
+ id: segment.id,
+ start: segment.start,
+ end: segment.end,
+ text: segment.text,
+ })),
+ settings: {
+ enabled: captionsStore.state.settings.enabled,
+ font: captionsStore.state.settings.font,
+ size: captionsStore.state.settings.size,
+ color: captionsStore.state.settings.color,
+ backgroundColor: captionsStore.state.settings.backgroundColor,
+ backgroundOpacity: captionsStore.state.settings.backgroundOpacity,
+ position: captionsStore.state.settings.position,
+ bold: captionsStore.state.settings.bold,
+ italic: captionsStore.state.settings.italic,
+ outline: captionsStore.state.settings.outline,
+ outlineColor: captionsStore.state.settings.outlineColor,
+ exportWithSubtitles:
+ captionsStore.state.settings.exportWithSubtitles,
+ },
+ };
+
+ // Update the project with captions data
+ setProject(updatedProject);
+
+ // Save the updated project configuration
+ await commands.setProjectConfig(updatedProject);
+ }
+ }
+ }
+ });
+
+ // Continue to update current caption when playback time changes
+ // This is still needed for CaptionsTab to highlight the current caption
+ createEffect(() => {
+ const time = editorState.playbackTime;
+ // Only update captions if we have a valid time and segments exist
+ if (
+ time !== undefined &&
+ time >= 0 &&
+ captionsStore.state.segments.length > 0
+ ) {
+ captionsStore.updateCurrentCaption(time);
+ }
+ });
+
+ const [canvasContainerRef, setCanvasContainerRef] =
+ createSignal();
+ const containerBounds = createElementBounds(canvasContainerRef);
+
+ const isAtEnd = () => {
+ const total = totalDuration();
+ return total > 0 && total - editorState.playbackTime <= 0.1;
+ };
+
+ const cropDialogHandler = () => {
+ const display = editorInstance.recordings.segments[0].display;
+ setDialog({
+ open: true,
+ type: "crop",
+ position: {
+ ...(project.background.crop?.position ?? { x: 0, y: 0 }),
+ },
+ size: {
+ ...(project.background.crop?.size ?? {
+ x: display.width,
+ y: display.height,
+ }),
+ },
+ });
+ };
+
+ createEffect(() => {
+ if (isAtEnd() && editorState.playing) {
+ commands.stopPlayback();
+ setEditorState("playing", false);
+ }
+ });
+
+ const handlePlayPauseClick = async () => {
+ try {
+ if (isAtEnd()) {
+ await commands.stopPlayback();
+ setEditorState("playbackTime", 0);
+ await commands.seekTo(0);
+ await commands.startPlayback(FPS, OUTPUT_SIZE);
+ setEditorState("playing", true);
+ } else if (editorState.playing) {
+ await commands.stopPlayback();
+ setEditorState("playing", false);
+ } else {
+ // Ensure we seek to the current playback time before starting playback
+ await commands.seekTo(Math.floor(editorState.playbackTime * FPS));
+ await commands.startPlayback(FPS, OUTPUT_SIZE);
+ setEditorState("playing", true);
+ }
+ if (editorState.playing) setEditorState("previewTime", null);
+ } catch (error) {
+ console.error("Error handling play/pause:", error);
+ setEditorState("playing", false);
+ }
+ };
+
+ // Register keyboard shortcuts in one place
+ useEditorShortcuts(() => {
+ const el = document.activeElement;
+ if (!el) return true;
+ const tagName = el.tagName.toLowerCase();
+ const isContentEditable = el.getAttribute("contenteditable") === "true";
+ return !(
+ tagName === "input" ||
+ tagName === "textarea" ||
+ isContentEditable
+ );
+ }, [
+ {
+ combo: "S",
+ handler: () =>
+ setEditorState(
+ "timeline",
+ "interactMode",
+ editorState.timeline.interactMode === "split" ? "seek" : "split"
+ ),
+ },
+ {
+ combo: "Mod+=",
+ handler: () =>
+ editorState.timeline.transform.updateZoom(
+ editorState.timeline.transform.zoom / 1.1,
+ editorState.playbackTime
+ ),
+ },
+ {
+ combo: "Mod+-",
+ handler: () =>
+ editorState.timeline.transform.updateZoom(
+ editorState.timeline.transform.zoom * 1.1,
+ editorState.playbackTime
+ ),
+ },
+ {
+ combo: "Space",
+ handler: async () => {
+ const prevTime = editorState.previewTime;
+
+ if (!editorState.playing) {
+ if (prevTime !== null) setEditorState("playbackTime", prevTime);
+
+ await commands.seekTo(Math.floor(editorState.playbackTime * FPS));
+ }
+
+ await handlePlayPauseClick();
+ },
+ },
+ ]);
+
+ return (
+
+
+
+
cropDialogHandler()}
+ leftIcon={}
+ >
+ Crop
+
+
+
+
+
+
+ /
+
+
+
+
+
+
+
+
+
+
+
+
+ tooltipText="Toggle Split"
+ kbd={["S"]}
+ pressed={editorState.timeline.interactMode === "split"}
+ onChange={(v: boolean) =>
+ setEditorState("timeline", "interactMode", v ? "split" : "seek")
+ }
+ as={KToggleButton}
+ variant="danger"
+ leftIcon={
+
+ }
+ />
+
+
+ {
+ editorState.timeline.transform.updateZoom(
+ editorState.timeline.transform.zoom * 1.1,
+ editorState.playbackTime
+ );
+ }}
+ class="text-gray-12 size-5 will-change-[opacity] transition-opacity hover:opacity-70"
+ />
+
+
+ {
+ editorState.timeline.transform.updateZoom(
+ editorState.timeline.transform.zoom / 1.1,
+ editorState.playbackTime
+ );
+ }}
+ class="text-gray-12 size-5 will-change-[opacity] transition-opacity hover:opacity-70"
+ />
+
+ {
+ editorState.timeline.transform.updateZoom(
+ (1 - v) * zoomOutLimit(),
+ editorState.playbackTime
+ );
+ }}
+ formatTooltip={() =>
+ `${editorState.timeline.transform.zoom.toFixed(
+ 0
+ )} seconds visible`
+ }
+ />
+
+
+
+ );
}
// CSS for checkerboard grid (adaptive to light/dark mode)
const gridStyle = {
- "background-image":
- "linear-gradient(45deg, rgba(128,128,128,0.12) 25%, transparent 25%), " +
- "linear-gradient(-45deg, rgba(128,128,128,0.12) 25%, transparent 25%), " +
- "linear-gradient(45deg, transparent 75%, rgba(128,128,128,0.12) 75%), " +
- "linear-gradient(-45deg, transparent 75%, rgba(128,128,128,0.12) 75%)",
- "background-size": "40px 40px",
- "background-position": "0 0, 0 20px, 20px -20px, -20px 0px",
- "background-color": "rgba(200,200,200,0.08)",
+ "background-image":
+ "linear-gradient(45deg, rgba(128,128,128,0.12) 25%, transparent 25%), " +
+ "linear-gradient(-45deg, rgba(128,128,128,0.12) 25%, transparent 25%), " +
+ "linear-gradient(45deg, transparent 75%, rgba(128,128,128,0.12) 75%), " +
+ "linear-gradient(-45deg, transparent 75%, rgba(128,128,128,0.12) 75%)",
+ "background-size": "40px 40px",
+ "background-position": "0 0, 0 20px, 20px -20px, -20px 0px",
+ "background-color": "rgba(200,200,200,0.08)",
};
function PreviewCanvas() {
- const { latestFrame } = useEditorContext();
-
- let canvasRef: HTMLCanvasElement | undefined;
-
- const [canvasContainerRef, setCanvasContainerRef] =
- createSignal();
- const containerBounds = createElementBounds(canvasContainerRef);
-
- createEffect(() => {
- const frame = latestFrame();
- if (!frame) return;
- if (!canvasRef) return;
- const ctx = canvasRef.getContext("2d");
- ctx?.putImageData(frame.data, 0, 0);
- });
-
- return (
-
-
- {(currentFrame) => {
- const padding = 4;
-
- const containerAspect = () => {
- if (containerBounds.width && containerBounds.height) {
- return (
- (containerBounds.width - padding * 2) /
- (containerBounds.height - padding * 2)
- );
- }
-
- return 1;
- };
-
- const frameAspect = () =>
- currentFrame().width / currentFrame().data.height;
-
- const size = () => {
- if (frameAspect() < containerAspect()) {
- const height = (containerBounds.height ?? 0) - padding * 1;
-
- return {
- width: height * frameAspect(),
- height,
- };
- }
-
- const width = (containerBounds.width ?? 0) - padding * 2;
-
- return {
- width,
- height: width / frameAspect(),
- };
- };
-
- return (
-
-
-
- );
- }}
-
-
- );
+ const { latestFrame } = useEditorContext();
+
+ let canvasRef: HTMLCanvasElement | undefined;
+
+ const [canvasContainerRef, setCanvasContainerRef] =
+ createSignal();
+ const containerBounds = createElementBounds(canvasContainerRef);
+
+ createEffect(() => {
+ const frame = latestFrame();
+ if (!frame) return;
+ if (!canvasRef) return;
+ const ctx = canvasRef.getContext("2d");
+ ctx?.putImageData(frame.data, 0, 0);
+ });
+
+ return (
+
+
+ {(currentFrame) => {
+ const padding = 4;
+
+ const containerAspect = () => {
+ if (containerBounds.width && containerBounds.height) {
+ return (
+ (containerBounds.width - padding * 2) /
+ (containerBounds.height - padding * 2)
+ );
+ }
+
+ return 1;
+ };
+
+ const frameAspect = () =>
+ currentFrame().width / currentFrame().data.height;
+
+ const size = () => {
+ if (frameAspect() < containerAspect()) {
+ const height = (containerBounds.height ?? 0) - padding * 1;
+
+ return {
+ width: height * frameAspect(),
+ height,
+ };
+ }
+
+ const width = (containerBounds.width ?? 0) - padding * 2;
+
+ return {
+ width,
+ height: width / frameAspect(),
+ };
+ };
+
+ return (
+
+
+
+ );
+ }}
+
+
+ );
}
function Time(props: { seconds: number; fps?: number; class?: string }) {
- return (
-
- {formatTime(props.seconds, props.fps ?? FPS)}
-
- );
+ return (
+
+ {formatTime(props.seconds, props.fps ?? FPS)}
+
+ );
}
diff --git a/apps/desktop/src/routes/editor/Timeline/ClipTrack.tsx b/apps/desktop/src/routes/editor/Timeline/ClipTrack.tsx
index 6e7c324236..51be547ac5 100644
--- a/apps/desktop/src/routes/editor/Timeline/ClipTrack.tsx
+++ b/apps/desktop/src/routes/editor/Timeline/ClipTrack.tsx
@@ -1,19 +1,19 @@
import {
- createEventListener,
- createEventListenerMap,
+ createEventListener,
+ createEventListenerMap,
} from "@solid-primitives/event-listener";
import { cx } from "cva";
import {
- type ComponentProps,
- createEffect,
- createMemo,
- createRoot,
- createSignal,
- For,
- Match,
- onCleanup,
- Show,
- Switch,
+ type ComponentProps,
+ createEffect,
+ createMemo,
+ createRoot,
+ createSignal,
+ For,
+ Match,
+ onCleanup,
+ Show,
+ Switch,
} from "solid-js";
import { produce } from "solid-js/store";
@@ -22,780 +22,782 @@ import { useEditorContext } from "../context";
import { useSegmentContext, useTimelineContext } from "./context";
import { getSectionMarker } from "./sectionMarker";
import {
- SegmentContent,
- SegmentHandle,
- SegmentRoot,
- TrackRoot,
- useSegmentTranslateX,
- useSegmentWidth,
+ SegmentContent,
+ SegmentHandle,
+ SegmentRoot,
+ TrackRoot,
+ useSegmentTranslateX,
+ useSegmentWidth,
} from "./Track";
function formatTime(totalSeconds: number): string {
- const hours = Math.floor(totalSeconds / 3600);
- const minutes = Math.floor((totalSeconds % 3600) / 60);
- const seconds = Math.floor(totalSeconds % 60);
-
- if (hours > 0) {
- return `${hours}h ${minutes}m ${seconds}s`;
- } else if (minutes > 0) {
- return `${minutes}m ${seconds}s`;
- } else {
- return `${seconds}s`;
- }
+ const hours = Math.floor(totalSeconds / 3600);
+ const minutes = Math.floor((totalSeconds % 3600) / 60);
+ const seconds = Math.floor(totalSeconds % 60);
+
+ if (hours > 0) {
+ return `${hours}h ${minutes}m ${seconds}s`;
+ } else if (minutes > 0) {
+ return `${minutes}m ${seconds}s`;
+ } else {
+ return `${seconds}s`;
+ }
}
function WaveformCanvas(props: {
- systemWaveform?: number[];
- micWaveform?: number[];
- segment: { start: number; end: number };
- secsPerPixel: number;
+ systemWaveform?: number[];
+ micWaveform?: number[];
+ segment: { start: number; end: number };
+ secsPerPixel: number;
}) {
- const { project } = useEditorContext();
-
- let canvas: HTMLCanvasElement | undefined;
- const { width } = useSegmentContext();
- const { secsPerPixel } = useTimelineContext();
-
- const render = (
- ctx: CanvasRenderingContext2D,
- h: number,
- waveform: number[],
- color: string,
- gain = 0,
- ) => {
- const maxAmplitude = h;
-
- // yellow please
- ctx.fillStyle = color;
- ctx.beginPath();
-
- const step = 0.05 / secsPerPixel();
-
- ctx.moveTo(0, h);
-
- const norm = (w: number) => {
- const ww = Number.isFinite(w) ? w : -60;
- return 1.0 - Math.max(ww + gain, -60) / -60;
- };
-
- for (
- let segmentTime = props.segment.start;
- segmentTime <= props.segment.end + 0.1;
- segmentTime += 0.1
- ) {
- const index = Math.floor(segmentTime * 10);
- const xTime = index / 10;
-
- const currentDb =
- typeof waveform[index] === "number" ? waveform[index] : -60;
- const amplitude = norm(currentDb) * maxAmplitude;
-
- const x = (xTime - props.segment.start) / secsPerPixel();
- const y = h - amplitude;
-
- const prevX = (xTime - 0.1 - props.segment.start) / secsPerPixel();
- const prevDb =
- typeof waveform[index - 1] === "number" ? waveform[index - 1] : -60;
- const prevAmplitude = norm(prevDb) * maxAmplitude;
- const prevY = h - prevAmplitude;
-
- const cpX1 = prevX + step / 2;
- const cpX2 = x - step / 2;
-
- ctx.bezierCurveTo(cpX1, prevY, cpX2, y, x, y);
- }
-
- ctx.lineTo(
- (props.segment.end + 0.3 - props.segment.start) / secsPerPixel(),
- h,
- );
-
- ctx.closePath();
- ctx.fill();
- };
-
- function renderWaveforms() {
- if (!canvas) return;
- const ctx = canvas.getContext("2d");
- if (!ctx) return;
-
- const w = width();
- if (w <= 0) return;
-
- const h = canvas.height;
- canvas.width = w;
- ctx.clearRect(0, 0, w, h);
-
- if (props.micWaveform)
- render(
- ctx,
- h,
- props.micWaveform,
- "rgba(255,255,255,0.4)",
- project.audio.micVolumeDb,
- );
-
- if (props.systemWaveform)
- render(
- ctx,
- h,
- props.systemWaveform,
- "rgba(255,150,0,0.5)",
- project.audio.systemVolumeDb,
- );
- }
-
- createEffect(() => {
- renderWaveforms();
- });
-
- return (
-
-
+
or
+
+
or
diff --git a/apps/web/app/(org)/dashboard/caps/components/UploadCapButton.tsx b/apps/web/app/(org)/dashboard/caps/components/UploadCapButton.tsx
index 885642e06c..7be95c89de 100644
--- a/apps/web/app/(org)/dashboard/caps/components/UploadCapButton.tsx
+++ b/apps/web/app/(org)/dashboard/caps/components/UploadCapButton.tsx
@@ -18,6 +18,7 @@ import {
} from "@/app/(org)/dashboard/caps/UploadingContext";
import { UpgradeModal } from "@/components/UpgradeModal";
import { ThumbnailRequest } from "@/lib/Requests/ThumbnailRequest";
+import { sendProgressUpdate } from "./sendProgressUpdate";
export const UploadCapButton = ({
size = "md",
@@ -517,29 +518,3 @@ async function legacyUploadCap(
setUploadStatus(undefined);
return false;
}
-
-const sendProgressUpdate = async (
- videoId: string,
- uploaded: number,
- total: number,
-) => {
- try {
- const response = await fetch("/api/desktop/video/progress", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({
- videoId,
- uploaded,
- total,
- updatedAt: new Date().toISOString(),
- }),
- });
-
- if (!response.ok)
- console.error("Failed to send progress update:", response.status);
- } catch (err) {
- console.error("Error sending progress update:", err);
- }
-};
diff --git a/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/CameraPreviewWindow.tsx b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/CameraPreviewWindow.tsx
new file mode 100644
index 0000000000..a695943901
--- /dev/null
+++ b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/CameraPreviewWindow.tsx
@@ -0,0 +1,311 @@
+"use client";
+
+import { X, Maximize2, Circle, Square, RectangleHorizontal, FlipHorizontal } from "lucide-react";
+import { useCallback, useEffect, useRef, useState } from "react";
+import { createPortal } from "react-dom";
+import clsx from "clsx";
+
+type CameraPreviewSize = "sm" | "lg";
+type CameraPreviewShape = "round" | "square" | "full";
+
+interface CameraPreviewWindowProps {
+ cameraId: string;
+ onClose: () => void;
+}
+
+export const CameraPreviewWindow = ({
+ cameraId,
+ onClose,
+}: CameraPreviewWindowProps) => {
+ const [size, setSize] = useState("sm");
+ const [shape, setShape] = useState("round");
+ const [mirrored, setMirrored] = useState(false);
+ const [position, setPosition] = useState<{ x: number; y: number } | null>(null);
+ const [isDragging, setIsDragging] = useState(false);
+ const [dragStart, setDragStart] = useState({ x: 0, y: 0 });
+ const videoRef = useRef(null);
+ const streamRef = useRef(null);
+ const containerRef = useRef(null);
+ const [videoDimensions, setVideoDimensions] = useState<{ width: number; height: number } | null>(null);
+ const [mounted, setMounted] = useState(false);
+
+ useEffect(() => {
+ setMounted(true);
+ return () => {
+ setMounted(false);
+ };
+ }, []);
+
+ useEffect(() => {
+ const startCamera = async () => {
+ try {
+ const stream = await navigator.mediaDevices.getUserMedia({
+ video: {
+ deviceId: { exact: cameraId },
+ },
+ });
+
+ streamRef.current = stream;
+
+ if (videoRef.current) {
+ videoRef.current.srcObject = stream;
+ }
+
+ const calculateInitialPosition = () => {
+ const padding = 20;
+ const base = size === "sm" ? 230 : 400;
+ const barHeight = 52;
+ const windowWidth = base;
+ const windowHeight = base + barHeight;
+ const x = padding;
+ const y = window.innerHeight - windowHeight - padding;
+ setPosition({ x, y });
+ };
+
+ setTimeout(calculateInitialPosition, 100);
+ } catch (err) {
+ console.error("Failed to start camera", err);
+ }
+ };
+
+ startCamera();
+
+ return () => {
+ if (streamRef.current) {
+ streamRef.current.getTracks().forEach((track) => track.stop());
+ }
+ };
+ }, [cameraId]);
+
+ useEffect(() => {
+ if (videoRef.current && streamRef.current && !videoRef.current.srcObject) {
+ videoRef.current.srcObject = streamRef.current;
+ }
+ }, [position]);
+
+ useEffect(() => {
+ if (position) {
+ const padding = 20;
+ const base = size === "sm" ? 230 : 400;
+ const barHeight = 52;
+ const windowWidth = base;
+ const windowHeight = base + barHeight;
+
+ setPosition((prev) => {
+ if (!prev) return { x: padding, y: window.innerHeight - windowHeight - padding };
+ const maxX = window.innerWidth - windowWidth;
+ const maxY = window.innerHeight - windowHeight;
+ return {
+ x: Math.max(0, Math.min(prev.x, maxX)),
+ y: Math.max(0, Math.min(prev.y, maxY)),
+ };
+ });
+ }
+ }, [size]);
+
+ const handleMouseDown = useCallback((e: React.MouseEvent) => {
+ if ((e.target as HTMLElement).closest('[data-controls]')) {
+ return;
+ }
+ e.stopPropagation();
+ e.preventDefault();
+ setIsDragging(true);
+ setDragStart({
+ x: e.clientX - (position?.x || 0),
+ y: e.clientY - (position?.y || 0),
+ });
+ }, [position]);
+
+ const handleMouseMove = useCallback((e: MouseEvent) => {
+ if (!isDragging) return;
+
+ const newX = e.clientX - dragStart.x;
+ const newY = e.clientY - dragStart.y;
+
+ const base = size === "sm" ? 230 : 400;
+ const barHeight = 52;
+ const aspectRatio = videoDimensions
+ ? videoDimensions.width / videoDimensions.height
+ : 1;
+ const windowWidth =
+ shape === "full" ? (aspectRatio >= 1 ? base * aspectRatio : base) : base;
+ const windowHeight =
+ shape === "full" ? (aspectRatio >= 1 ? base : base / aspectRatio) : base;
+ const totalWidth = windowWidth;
+ const totalHeight = windowHeight + barHeight;
+ const maxX = window.innerWidth - totalWidth;
+ const maxY = window.innerHeight - totalHeight;
+
+ setPosition({
+ x: Math.max(0, Math.min(newX, maxX)),
+ y: Math.max(0, Math.min(newY, maxY)),
+ });
+ }, [isDragging, dragStart, size, shape, videoDimensions]);
+
+ const handleMouseUp = useCallback(() => {
+ setIsDragging(false);
+ }, []);
+
+ useEffect(() => {
+ if (isDragging) {
+ window.addEventListener("mousemove", handleMouseMove);
+ window.addEventListener("mouseup", handleMouseUp);
+ return () => {
+ window.removeEventListener("mousemove", handleMouseMove);
+ window.removeEventListener("mouseup", handleMouseUp);
+ };
+ }
+ }, [isDragging, handleMouseMove, handleMouseUp]);
+
+ if (!mounted || !position) {
+ return null;
+ }
+
+ const base = size === "sm" ? 230 : 400;
+ const barHeight = 52;
+ const aspectRatio = videoDimensions
+ ? videoDimensions.width / videoDimensions.height
+ : 1;
+
+ const windowWidth =
+ shape === "full" ? (aspectRatio >= 1 ? base * aspectRatio : base) : base;
+ const windowHeight =
+ shape === "full" ? (aspectRatio >= 1 ? base : base / aspectRatio) : base;
+ const totalHeight = windowHeight + barHeight;
+
+ const borderRadius =
+ shape === "round" ? "9999px" : size === "sm" ? "3rem" : "4rem";
+
+
+ return createPortal(
+ {
+ e.stopPropagation();
+ e.preventDefault();
+ handleMouseDown(e);
+ }}
+ onClick={(e) => {
+ e.stopPropagation();
+ }}
+ >
+
+
+
+
e.stopPropagation()}
+ onClick={(e) => e.stopPropagation()}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+ , document.body);
+};
+
diff --git a/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/CameraSelector.tsx b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/CameraSelector.tsx
new file mode 100644
index 0000000000..4cd639df3f
--- /dev/null
+++ b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/CameraSelector.tsx
@@ -0,0 +1,139 @@
+"use client";
+
+import {
+ SelectRoot,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@cap/ui";
+import clsx from "clsx";
+import { CameraIcon, CameraOffIcon } from "lucide-react";
+import { toast } from "sonner";
+import { NO_CAMERA, NO_CAMERA_VALUE } from "./web-recorder-constants";
+import { useMediaPermission } from "./useMediaPermission";
+
+import type { KeyboardEvent, MouseEvent } from "react";
+
+interface CameraSelectorProps {
+ selectedCameraId: string | null;
+ availableCameras: MediaDeviceInfo[];
+ dialogOpen: boolean;
+ disabled?: boolean;
+ onCameraChange: (cameraId: string | null) => void;
+ onRefreshDevices: () => Promise | void;
+}
+
+export const CameraSelector = ({
+ selectedCameraId,
+ availableCameras,
+ dialogOpen,
+ disabled = false,
+ onCameraChange,
+ onRefreshDevices,
+}: CameraSelectorProps) => {
+ const cameraEnabled = selectedCameraId !== null;
+ const { state: permissionState, requestPermission } = useMediaPermission(
+ "camera",
+ dialogOpen
+ );
+
+ const permissionSupported = permissionState !== "unsupported";
+ const shouldRequestPermission =
+ permissionSupported && permissionState !== "granted";
+
+ const statusPillClassName = clsx(
+ "px-[0.375rem] h-[1.25rem] min-w-[2.5rem] rounded-full text-[0.75rem] leading-[1.25rem] flex items-center justify-center font-normal transition-colors duration-200 disabled:opacity-100 disabled:pointer-events-none",
+ shouldRequestPermission
+ ? "bg-[var(--red-3)] text-[var(--red-11)] dark:bg-[var(--red-4)] dark:text-[var(--red-12)]"
+ : cameraEnabled
+ ? "bg-[var(--blue-3)] text-[var(--blue-11)] dark:bg-[var(--blue-4)] dark:text-[var(--blue-12)]"
+ : "bg-[var(--red-3)] text-[var(--red-11)] dark:bg-[var(--red-4)] dark:text-[var(--red-12)]"
+ );
+
+ const handleStatusPillClick = async (
+ event: MouseEvent
+ ) => {
+ if (!shouldRequestPermission) return;
+ event.preventDefault();
+ event.stopPropagation();
+
+ try {
+ const granted = await requestPermission();
+ if (granted) {
+ await Promise.resolve(onRefreshDevices());
+ }
+ } catch (error) {
+ console.error("Camera permission request failed", error);
+ toast.error("Unable to access your camera. Check browser permissions.");
+ }
+ };
+
+ return (
+
+ {
+ onCameraChange(value === NO_CAMERA_VALUE ? null : value);
+ }}
+ disabled={disabled}
+ >
+ svg]:hidden",
+ disabled || shouldRequestPermission ? "cursor-default" : undefined
+ )}
+ onPointerDown={(event) => {
+ if (shouldRequestPermission) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }}
+ onKeyDown={(event: KeyboardEvent) => {
+ if (shouldRequestPermission) {
+ const keys = ["Enter", " ", "ArrowDown", "ArrowUp"];
+ if (keys.includes(event.key)) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+ }}
+ aria-disabled={disabled || shouldRequestPermission}
+ >
+
+
+
+
+
+
+
+ {NO_CAMERA}
+
+
+ {availableCameras.map((camera, index) => (
+
+
+
+ {camera.label?.trim() || `Camera ${index + 1}`}
+
+
+ ))}
+
+
+
+ );
+};
diff --git a/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/MicrophoneSelector.tsx b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/MicrophoneSelector.tsx
new file mode 100644
index 0000000000..a6a9083c80
--- /dev/null
+++ b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/MicrophoneSelector.tsx
@@ -0,0 +1,141 @@
+"use client";
+
+import {
+ SelectRoot,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@cap/ui";
+import clsx from "clsx";
+import { MicIcon, MicOffIcon } from "lucide-react";
+import { toast } from "sonner";
+import { NO_MICROPHONE, NO_MICROPHONE_VALUE } from "./web-recorder-constants";
+import { useMediaPermission } from "./useMediaPermission";
+
+import type { KeyboardEvent, MouseEvent } from "react";
+
+interface MicrophoneSelectorProps {
+ selectedMicId: string | null;
+ availableMics: MediaDeviceInfo[];
+ dialogOpen: boolean;
+ disabled?: boolean;
+ onMicChange: (micId: string | null) => void;
+ onRefreshDevices: () => Promise | void;
+}
+
+export const MicrophoneSelector = ({
+ selectedMicId,
+ availableMics,
+ dialogOpen,
+ disabled = false,
+ onMicChange,
+ onRefreshDevices,
+}: MicrophoneSelectorProps) => {
+ const micEnabled = selectedMicId !== null;
+ const { state: permissionState, requestPermission } = useMediaPermission(
+ "microphone",
+ dialogOpen
+ );
+
+ const permissionSupported = permissionState !== "unsupported";
+ const shouldRequestPermission =
+ permissionSupported && permissionState !== "granted";
+
+ const statusPillClassName = clsx(
+ "px-[0.375rem] h-[1.25rem] min-w-[2.5rem] rounded-full text-[0.75rem] leading-[1.25rem] flex items-center justify-center font-normal transition-colors duration-200 disabled:opacity-100 disabled:pointer-events-none",
+ shouldRequestPermission
+ ? "bg-[var(--red-3)] text-[var(--red-11)] dark:bg-[var(--red-4)] dark:text-[var(--red-12)]"
+ : micEnabled
+ ? "bg-[var(--blue-3)] text-[var(--blue-11)] dark:bg-[var(--blue-4)] dark:text-[var(--blue-12)]"
+ : "bg-[var(--red-3)] text-[var(--red-11)] dark:bg-[var(--red-4)] dark:text-[var(--red-12)]"
+ );
+
+ const handleStatusPillClick = async (
+ event: MouseEvent
+ ) => {
+ if (!shouldRequestPermission) return;
+ event.preventDefault();
+ event.stopPropagation();
+
+ try {
+ const granted = await requestPermission();
+ if (granted) {
+ await Promise.resolve(onRefreshDevices());
+ }
+ } catch (error) {
+ console.error("Microphone permission request failed", error);
+ toast.error(
+ "Unable to access your microphone. Check browser permissions."
+ );
+ }
+ };
+
+ return (
+
+ {
+ onMicChange(value === NO_MICROPHONE_VALUE ? null : value);
+ }}
+ disabled={disabled}
+ >
+ svg]:hidden",
+ disabled || shouldRequestPermission ? "cursor-default" : undefined
+ )}
+ onPointerDown={(event) => {
+ if (shouldRequestPermission) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }}
+ onKeyDown={(event: KeyboardEvent) => {
+ if (shouldRequestPermission) {
+ const keys = ["Enter", " ", "ArrowDown", "ArrowUp"];
+ if (keys.includes(event.key)) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+ }}
+ aria-disabled={disabled || shouldRequestPermission}
+ >
+
+
+
+
+
+
+
+ {NO_MICROPHONE}
+
+
+ {availableMics.map((mic, index) => (
+
+
+
+ {mic.label?.trim() || `Microphone ${index + 1}`}
+
+
+ ))}
+
+
+
+ );
+};
diff --git a/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/RecordingButton.tsx b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/RecordingButton.tsx
new file mode 100644
index 0000000000..7837dbf634
--- /dev/null
+++ b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/RecordingButton.tsx
@@ -0,0 +1,40 @@
+"use client";
+
+import { Button } from "@cap/ui";
+import { PlayIcon } from "lucide-react";
+
+interface RecordingButtonProps {
+ isRecording: boolean;
+ disabled?: boolean;
+ onStart: () => void;
+ onStop: () => void;
+}
+
+export const RecordingButton = ({
+ isRecording,
+ disabled = false,
+ onStart,
+ onStop,
+}: RecordingButtonProps) => {
+ return (
+
+
+
+ );
+};
+
diff --git a/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/RecordingModeSelector.tsx b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/RecordingModeSelector.tsx
new file mode 100644
index 0000000000..0ea0f31561
--- /dev/null
+++ b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/RecordingModeSelector.tsx
@@ -0,0 +1,88 @@
+"use client";
+
+import {
+ SelectRoot,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@cap/ui";
+import {
+ CameraIcon,
+ Globe,
+ MonitorIcon,
+ RectangleHorizontal,
+ type LucideIcon,
+} from "lucide-react";
+
+export type RecordingMode = "fullscreen" | "window" | "tab" | "camera";
+
+interface RecordingModeSelectorProps {
+ mode: RecordingMode;
+ disabled?: boolean;
+ onModeChange: (mode: RecordingMode) => void;
+}
+
+export const RecordingModeSelector = ({
+ mode,
+ disabled = false,
+ onModeChange,
+}: RecordingModeSelectorProps) => {
+ const recordingModeOptions: Record<
+ RecordingMode,
+ {
+ label: string;
+ icon: LucideIcon;
+ }
+ > = {
+ fullscreen: {
+ label: "Full Screen",
+ icon: MonitorIcon,
+ },
+ window: {
+ label: "Window",
+ icon: RectangleHorizontal,
+ },
+ tab: {
+ label: "Current tab",
+ icon: Globe,
+ },
+ camera: {
+ label: "Camera only",
+ icon: CameraIcon,
+ },
+ };
+
+ return (
+
+ {
+ onModeChange(value as RecordingMode);
+ }}
+ disabled={disabled}
+ >
+
+
+
+
+ {Object.entries(recordingModeOptions).map(([value, option]) => {
+ const OptionIcon = option.icon;
+
+ return (
+
+
+
+ {option.label}
+
+
+ );
+ })}
+
+
+
+ );
+};
diff --git a/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/WebRecorderDialog.tsx b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/WebRecorderDialog.tsx
new file mode 100644
index 0000000000..44520e43a2
--- /dev/null
+++ b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/WebRecorderDialog.tsx
@@ -0,0 +1,287 @@
+"use client";
+
+import {
+ Button,
+ Dialog,
+ DialogContent,
+ DialogTitle,
+ DialogTrigger,
+} from "@cap/ui";
+import { AnimatePresence, motion } from "framer-motion";
+import { MonitorIcon } from "lucide-react";
+import { useEffect, useRef, useState } from "react";
+import { toast } from "sonner";
+import { useDashboardContext } from "../../../Contexts";
+import { CameraSelector } from "./CameraSelector";
+import { CameraPreviewWindow } from "./CameraPreviewWindow";
+import { MicrophoneSelector } from "./MicrophoneSelector";
+import { RecordingButton } from "./RecordingButton";
+import {
+ RecordingModeSelector,
+ type RecordingMode,
+} from "./RecordingModeSelector";
+import { WebRecorderDialogHeader } from "./WebRecorderDialogHeader";
+import { dialogVariants } from "./web-recorder-constants";
+import { useCameraDevices } from "./useCameraDevices";
+import { useMicrophoneDevices } from "./useMicrophoneDevices";
+import { useWebRecorder } from "./useWebRecorder";
+
+export const WebRecorderDialog = () => {
+ const [open, setOpen] = useState(false);
+ const [selectedMicId, setSelectedMicId] = useState(null);
+ const [recordingMode, setRecordingMode] =
+ useState("fullscreen");
+ const [selectedCameraId, setSelectedCameraId] = useState(null);
+ const dialogContentRef = useRef(null);
+
+ const { activeOrganization } = useDashboardContext();
+ const organisationId = activeOrganization?.organization.id;
+ const { devices: availableMics, refresh: refreshMics } =
+ useMicrophoneDevices(open);
+ const { devices: availableCameras, refresh: refreshCameras } =
+ useCameraDevices(open);
+
+ const micEnabled = selectedMicId !== null;
+
+ useEffect(() => {
+ if (
+ recordingMode === "camera" &&
+ !selectedCameraId &&
+ availableCameras.length > 0
+ ) {
+ setSelectedCameraId(availableCameras[0]?.deviceId ?? null);
+ }
+ }, [recordingMode, selectedCameraId, availableCameras]);
+
+ const {
+ isRecording,
+ isBusy,
+ canStartRecording,
+ startRecording,
+ stopRecording,
+ resetState,
+ } = useWebRecorder({
+ organisationId,
+ selectedMicId,
+ micEnabled,
+ recordingMode,
+ selectedCameraId,
+ });
+
+ const handleOpenChange = (next: boolean) => {
+ if (!next && isBusy) {
+ toast.info("Keep this dialog open while your upload finishes.");
+ return;
+ }
+
+ if (!next) {
+ resetState();
+ setSelectedCameraId(null);
+ setRecordingMode("fullscreen");
+ }
+ setOpen(next);
+ };
+
+ const handleStopClick = () => {
+ stopRecording().catch((err: unknown) => {
+ console.error("Stop recording error", err);
+ });
+ };
+
+ const handleClose = () => {
+ if (!isBusy) {
+ handleOpenChange(false);
+ }
+ };
+
+ const handleCameraChange = (cameraId: string | null) => {
+ setSelectedCameraId(cameraId);
+ };
+
+ return (
+ <>
+
+ {selectedCameraId && (
+ setSelectedCameraId(null)}
+ />
+ )}
+ >
+ );
+};
diff --git a/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/WebRecorderDialogHeader.tsx b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/WebRecorderDialogHeader.tsx
new file mode 100644
index 0000000000..73c70dc878
--- /dev/null
+++ b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/WebRecorderDialogHeader.tsx
@@ -0,0 +1,98 @@
+"use client";
+
+import clsx from "clsx";
+import { useDashboardContext } from "../../../Contexts";
+
+interface WebRecorderDialogHeaderProps {
+ isBusy: boolean;
+ onClose: () => void;
+}
+
+export const WebRecorderDialogHeader = ({
+ isBusy,
+ onClose,
+}: WebRecorderDialogHeaderProps) => {
+ const { user, setUpgradeModalOpen } = useDashboardContext();
+ const planLabel = user.isPro ? "Pro" : "Free";
+ const planClassName = clsx(
+ "ml-2 inline-flex items-center rounded-md px-1.5 py-0.5 text-[0.7rem] font-medium transition-colors",
+ user.isPro
+ ? "bg-blue-9 text-gray-1"
+ : "cursor-pointer bg-gray-3 text-gray-12 hover:bg-gray-4"
+ );
+
+ return (
+ <>
+
+
+
+
+
{
+ if (!user.isPro) setUpgradeModalOpen(true);
+ }}
+ className={planClassName}
+ >
+ {planLabel}
+
+
+
+ >
+ );
+};
diff --git a/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/useCameraDevices.ts b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/useCameraDevices.ts
new file mode 100644
index 0000000000..5e97819e20
--- /dev/null
+++ b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/useCameraDevices.ts
@@ -0,0 +1,56 @@
+"use client";
+
+import { useCallback, useEffect, useRef, useState } from "react";
+
+export const useCameraDevices = (open: boolean) => {
+ const [availableCameras, setAvailableCameras] = useState([]);
+ const isMountedRef = useRef(false);
+
+ useEffect(() => {
+ isMountedRef.current = true;
+ return () => {
+ isMountedRef.current = false;
+ };
+ }, []);
+
+ const enumerateDevices = useCallback(async () => {
+ if (typeof navigator === "undefined" || !navigator.mediaDevices) return;
+
+ try {
+ const devices = await navigator.mediaDevices.enumerateDevices();
+ const videoInputs = devices.filter(
+ (device) => device.kind === "videoinput"
+ );
+ if (isMountedRef.current) {
+ setAvailableCameras(videoInputs);
+ }
+ } catch (err) {
+ console.error("Failed to enumerate devices", err);
+ }
+ }, []);
+
+ useEffect(() => {
+ if (!open) return;
+
+ enumerateDevices();
+
+ const handleDeviceChange = () => {
+ enumerateDevices();
+ };
+
+ navigator.mediaDevices?.addEventListener("devicechange", handleDeviceChange);
+
+ return () => {
+ navigator.mediaDevices?.removeEventListener(
+ "devicechange",
+ handleDeviceChange
+ );
+ };
+ }, [open, enumerateDevices]);
+
+ return {
+ devices: availableCameras,
+ refresh: enumerateDevices,
+ };
+};
+
diff --git a/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/useMediaPermission.ts b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/useMediaPermission.ts
new file mode 100644
index 0000000000..c7755fbf70
--- /dev/null
+++ b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/useMediaPermission.ts
@@ -0,0 +1,106 @@
+"use client";
+
+import { useCallback, useEffect, useRef, useState } from "react";
+
+type MediaPermissionKind = "camera" | "microphone";
+
+type MediaPermissionState =
+ | PermissionState
+ | "unsupported"
+ | "unknown";
+
+const permissionNameMap: Record = {
+ camera: "camera",
+ microphone: "microphone",
+};
+
+const mediaConstraintsMap: Record = {
+ camera: { video: { width: { ideal: 1280 }, height: { ideal: 720 } }, audio: false },
+ microphone: { audio: true, video: false },
+};
+
+export const useMediaPermission = (
+ kind: MediaPermissionKind,
+ enabled: boolean
+) => {
+ const [state, setState] = useState("unknown");
+ const permissionStatusRef = useRef(null);
+
+ const updateState = useCallback((next: MediaPermissionState) => {
+ setState((prev) => {
+ if (prev === next) return prev;
+ return next;
+ });
+ }, []);
+
+ const refreshPermission = useCallback(async () => {
+ if (!enabled) return;
+ if (typeof navigator === "undefined" || !navigator.permissions?.query) {
+ updateState("unsupported");
+ return;
+ }
+
+ try {
+ const descriptor = {
+ name: permissionNameMap[kind],
+ } as PermissionDescriptor;
+
+ const permissionStatus = await navigator.permissions.query(descriptor);
+ if (permissionStatusRef.current) {
+ permissionStatusRef.current.onchange = null;
+ }
+ permissionStatusRef.current = permissionStatus;
+
+ updateState(permissionStatus.state);
+
+ permissionStatus.onchange = () => {
+ updateState(permissionStatus.state);
+ };
+ } catch (error) {
+ updateState("unsupported");
+ }
+ }, [enabled, kind, updateState]);
+
+ useEffect(() => {
+ if (!enabled) return;
+ refreshPermission();
+
+ return () => {
+ if (permissionStatusRef.current) {
+ permissionStatusRef.current.onchange = null;
+ }
+ permissionStatusRef.current = null;
+ };
+ }, [enabled, refreshPermission]);
+
+ const requestPermission = useCallback(async () => {
+ if (typeof navigator === "undefined" || !navigator.mediaDevices?.getUserMedia) {
+ updateState("unsupported");
+ return false;
+ }
+
+ try {
+ const stream = await navigator.mediaDevices.getUserMedia(
+ mediaConstraintsMap[kind]
+ );
+ stream.getTracks().forEach((track) => track.stop());
+ updateState("granted");
+ await refreshPermission();
+ return true;
+ } catch (error) {
+ if (error instanceof DOMException) {
+ if (error.name === "NotAllowedError" || error.name === "SecurityError") {
+ updateState("denied");
+ }
+ }
+ throw error;
+ }
+ }, [kind, refreshPermission, updateState]);
+
+ return {
+ state,
+ requestPermission,
+ };
+};
+
+
diff --git a/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/useMicrophoneDevices.ts b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/useMicrophoneDevices.ts
new file mode 100644
index 0000000000..e4d996bb36
--- /dev/null
+++ b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/useMicrophoneDevices.ts
@@ -0,0 +1,56 @@
+"use client";
+
+import { useCallback, useEffect, useRef, useState } from "react";
+
+export const useMicrophoneDevices = (open: boolean) => {
+ const [availableMics, setAvailableMics] = useState([]);
+ const isMountedRef = useRef(false);
+
+ useEffect(() => {
+ isMountedRef.current = true;
+ return () => {
+ isMountedRef.current = false;
+ };
+ }, []);
+
+ const enumerateDevices = useCallback(async () => {
+ if (typeof navigator === "undefined" || !navigator.mediaDevices) return;
+
+ try {
+ const devices = await navigator.mediaDevices.enumerateDevices();
+ const audioInputs = devices.filter(
+ (device) => device.kind === "audioinput"
+ );
+ if (isMountedRef.current) {
+ setAvailableMics(audioInputs);
+ }
+ } catch (err) {
+ console.error("Failed to enumerate devices", err);
+ }
+ }, []);
+
+ useEffect(() => {
+ if (!open) return;
+
+ enumerateDevices();
+
+ const handleDeviceChange = () => {
+ enumerateDevices();
+ };
+
+ navigator.mediaDevices?.addEventListener("devicechange", handleDeviceChange);
+
+ return () => {
+ navigator.mediaDevices?.removeEventListener(
+ "devicechange",
+ handleDeviceChange
+ );
+ };
+ }, [open, enumerateDevices]);
+
+ return {
+ devices: availableMics,
+ refresh: enumerateDevices,
+ };
+};
+
diff --git a/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/useWebRecorder.ts b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/useWebRecorder.ts
new file mode 100644
index 0000000000..39935f9681
--- /dev/null
+++ b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/useWebRecorder.ts
@@ -0,0 +1,766 @@
+"use client";
+
+import { useQueryClient } from "@tanstack/react-query";
+import { Organisation } from "@cap/web-domain";
+import { Option } from "effect";
+import { useCallback, useEffect, useRef, useState } from "react";
+import { toast } from "sonner";
+import { useRouter } from "next/navigation";
+import { createVideoAndGetUploadUrl } from "@/actions/video/upload";
+import { ThumbnailRequest } from "@/lib/Requests/ThumbnailRequest";
+import { EffectRuntime, useRpcClient } from "@/lib/EffectRuntime";
+import { useUploadingContext } from "../../UploadingContext";
+import { sendProgressUpdate } from "../sendProgressUpdate";
+import type {
+ PresignedPost,
+ RecorderErrorEvent,
+ RecorderPhase,
+ VideoId,
+} from "./web-recorder-types";
+import type { RecordingMode } from "./RecordingModeSelector";
+
+interface UseWebRecorderOptions {
+ organisationId: string | undefined;
+ selectedMicId: string | null;
+ micEnabled: boolean;
+ recordingMode: RecordingMode;
+ selectedCameraId: string | null;
+ onPhaseChange?: (phase: RecorderPhase) => void;
+}
+
+const DISPLAY_MEDIA_VIDEO_CONSTRAINTS: MediaTrackConstraints = {
+ frameRate: { ideal: 30 },
+ width: { ideal: 1920 },
+ height: { ideal: 1080 },
+};
+
+type ExtendedDisplayMediaStreamOptions = DisplayMediaStreamOptions & {
+ monitorTypeSurfaces?: "include" | "exclude";
+ surfaceSwitching?: "include" | "exclude";
+ selfBrowserSurface?: "include" | "exclude";
+ preferCurrentTab?: boolean;
+};
+
+const DISPLAY_MODE_PREFERENCES: Record<
+ Exclude,
+ Partial
+> = {
+ fullscreen: {
+ monitorTypeSurfaces: "include",
+ selfBrowserSurface: "exclude",
+ surfaceSwitching: "exclude",
+ },
+ window: {
+ monitorTypeSurfaces: "exclude",
+ selfBrowserSurface: "exclude",
+ surfaceSwitching: "exclude",
+ },
+ tab: {
+ monitorTypeSurfaces: "exclude",
+ selfBrowserSurface: "include",
+ surfaceSwitching: "exclude",
+ preferCurrentTab: true,
+ },
+};
+
+const shouldRetryDisplayMediaWithoutPreferences = (error: unknown) => {
+ if (error instanceof DOMException) {
+ return (
+ error.name === "OverconstrainedError" ||
+ error.name === "NotSupportedError"
+ );
+ }
+
+ return error instanceof TypeError;
+};
+
+export const useWebRecorder = ({
+ organisationId,
+ selectedMicId,
+ micEnabled,
+ recordingMode,
+ selectedCameraId,
+ onPhaseChange,
+}: UseWebRecorderOptions) => {
+ const [phase, setPhase] = useState("idle");
+ const [durationMs, setDurationMs] = useState(0);
+ const [videoId, setVideoId] = useState(null);
+ const [hasAudioTrack, setHasAudioTrack] = useState(false);
+ const [isSettingUp, setIsSettingUp] = useState(false);
+
+ const mediaRecorderRef = useRef(null);
+ const recordedChunksRef = useRef([]);
+ const displayStreamRef = useRef(null);
+ const cameraStreamRef = useRef(null);
+ const micStreamRef = useRef(null);
+ const mixedStreamRef = useRef(null);
+ const videoRef = useRef(null);
+ const timerRef = useRef(null);
+ const startTimeRef = useRef(null);
+ const dimensionsRef = useRef<{ width?: number; height?: number }>({});
+ const stopPromiseResolverRef = useRef<((blob: Blob) => void) | null>(null);
+ const stopPromiseRejectRef = useRef<((reason?: unknown) => void) | null>(
+ null
+ );
+ const stopRecordingRef = useRef<(() => Promise) | null>(null);
+
+ const rpc = useRpcClient();
+ const router = useRouter();
+ const { setUploadStatus } = useUploadingContext();
+ const queryClient = useQueryClient();
+
+ const updatePhase = useCallback(
+ (newPhase: RecorderPhase) => {
+ setPhase(newPhase);
+ onPhaseChange?.(newPhase);
+ },
+ [onPhaseChange]
+ );
+
+ const cleanupStreams = useCallback(() => {
+ const stopTracks = (stream: MediaStream | null) => {
+ stream?.getTracks().forEach((track) => {
+ track.stop();
+ });
+ };
+ stopTracks(displayStreamRef.current);
+ stopTracks(cameraStreamRef.current);
+ stopTracks(micStreamRef.current);
+ stopTracks(mixedStreamRef.current);
+ displayStreamRef.current = null;
+ cameraStreamRef.current = null;
+ micStreamRef.current = null;
+ mixedStreamRef.current = null;
+
+ if (videoRef.current) {
+ videoRef.current.srcObject = null;
+ }
+ }, []);
+
+ const clearTimer = useCallback(() => {
+ if (timerRef.current !== null) {
+ window.clearInterval(timerRef.current);
+ timerRef.current = null;
+ }
+ }, []);
+
+ const resetState = useCallback(() => {
+ cleanupStreams();
+ clearTimer();
+ mediaRecorderRef.current = null;
+ recordedChunksRef.current = [];
+ setDurationMs(0);
+ updatePhase("idle");
+ setVideoId(null);
+ setHasAudioTrack(false);
+ setUploadStatus(undefined);
+ }, [cleanupStreams, clearTimer, setUploadStatus, updatePhase]);
+
+ useEffect(() => {
+ return () => {
+ resetState();
+ };
+ }, [resetState]);
+
+ const stopRecordingInternal = useCallback(async () => {
+ const recorder = mediaRecorderRef.current;
+ if (!recorder || recorder.state === "inactive") return null;
+
+ const stopPromise = new Promise((resolve, reject) => {
+ stopPromiseResolverRef.current = resolve;
+ stopPromiseRejectRef.current = reject;
+ });
+
+ recorder.stop();
+ cleanupStreams();
+ clearTimer();
+
+ return stopPromise;
+ }, [cleanupStreams, clearTimer]);
+
+ const onRecorderDataAvailable = useCallback((event: BlobEvent) => {
+ if (event.data && event.data.size > 0) {
+ recordedChunksRef.current.push(event.data);
+ }
+ }, []);
+
+ const onRecorderStop = useCallback(() => {
+ if (recordedChunksRef.current.length === 0) {
+ stopPromiseRejectRef.current?.(new Error("No recorded data"));
+ stopPromiseResolverRef.current = null;
+ stopPromiseRejectRef.current = null;
+ return;
+ }
+
+ const blob = new Blob(recordedChunksRef.current, {
+ type: recordedChunksRef.current[0]?.type ?? "video/webm;codecs=vp8,opus",
+ });
+ recordedChunksRef.current = [];
+ stopPromiseResolverRef.current?.(blob);
+ stopPromiseResolverRef.current = null;
+ stopPromiseRejectRef.current = null;
+ }, []);
+
+ const onRecorderError = useCallback((event: RecorderErrorEvent) => {
+ const error = event.error ?? new DOMException("Recording error");
+ stopPromiseRejectRef.current?.(error);
+ stopPromiseResolverRef.current = null;
+ stopPromiseRejectRef.current = null;
+ }, []);
+
+ const captureThumbnail = useCallback(
+ (source: Blob) =>
+ new Promise((resolve) => {
+ const video = document.createElement("video");
+ const objectUrl = URL.createObjectURL(source);
+ video.src = objectUrl;
+ video.muted = true;
+ video.playsInline = true;
+
+ let timeoutId: number;
+
+ const cleanup = () => {
+ video.pause();
+ video.removeAttribute("src");
+ video.load();
+ URL.revokeObjectURL(objectUrl);
+ };
+
+ const finalize = (result: Blob | null) => {
+ window.clearTimeout(timeoutId);
+ cleanup();
+ resolve(result);
+ };
+
+ timeoutId = window.setTimeout(() => finalize(null), 10000);
+
+ video.addEventListener(
+ "error",
+ () => {
+ finalize(null);
+ },
+ { once: true }
+ );
+
+ video.addEventListener(
+ "loadedmetadata",
+ () => {
+ try {
+ const duration = Number.isFinite(video.duration)
+ ? video.duration
+ : 0;
+ const targetTime = duration > 0 ? Math.min(1, duration / 4) : 0;
+ video.currentTime = targetTime;
+ } catch {
+ finalize(null);
+ }
+ },
+ { once: true }
+ );
+
+ video.addEventListener(
+ "seeked",
+ () => {
+ try {
+ const canvas = document.createElement("canvas");
+ const width =
+ video.videoWidth ||
+ dimensionsRef.current.width ||
+ 640;
+ const height =
+ video.videoHeight ||
+ dimensionsRef.current.height ||
+ 360;
+ canvas.width = width;
+ canvas.height = height;
+ const ctx = canvas.getContext("2d");
+ if (!ctx) {
+ finalize(null);
+ return;
+ }
+ ctx.drawImage(video, 0, 0, width, height);
+ canvas.toBlob(
+ (blob) => {
+ finalize(blob ?? null);
+ },
+ "image/jpeg",
+ 0.8
+ );
+ } catch {
+ finalize(null);
+ }
+ },
+ { once: true }
+ );
+ }),
+ []
+ );
+
+ const convertToMp4 = useCallback(
+ async (blob: Blob, hasAudio: boolean, currentVideoId: string) => {
+ updatePhase("converting");
+ setUploadStatus({
+ status: "converting",
+ capId: currentVideoId,
+ progress: 0,
+ });
+
+ const file = new File([blob], "recording.webm", { type: blob.type });
+ const { convertMedia } = await import("@remotion/webcodecs");
+
+ const result = await convertMedia({
+ src: file,
+ container: "mp4",
+ videoCodec: "h264",
+ ...(hasAudio ? { audioCodec: "aac" as const } : {}),
+ onProgress: ({ overallProgress }) => {
+ if (overallProgress !== null) {
+ const percent = Math.min(100, Math.max(0, overallProgress * 100));
+ setUploadStatus({
+ status: "converting",
+ capId: currentVideoId,
+ progress: percent,
+ });
+ }
+ },
+ });
+
+ const savedFile = await result.save();
+ if (savedFile.size === 0) {
+ throw new Error("Conversion produced empty file");
+ }
+ if (savedFile.type !== "video/mp4") {
+ return new File([savedFile], "result.mp4", { type: "video/mp4" });
+ }
+ return savedFile;
+ },
+ [updatePhase, setUploadStatus]
+ );
+
+ const uploadRecording = useCallback(
+ async (
+ blob: Blob,
+ upload: PresignedPost,
+ currentVideoId: string,
+ thumbnailPreviewUrl: string | undefined
+ ) =>
+ new Promise((resolve, reject) => {
+ if (blob.size === 0) {
+ reject(new Error("Cannot upload empty file"));
+ return;
+ }
+
+ const fileBlob =
+ blob instanceof File && blob.type === "video/mp4"
+ ? blob
+ : new File([blob], "result.mp4", { type: "video/mp4" });
+
+ console.log("Uploading file:", {
+ size: fileBlob.size,
+ type: fileBlob.type,
+ name: fileBlob.name,
+ uploadUrl: upload.url,
+ uploadFields: upload.fields,
+ });
+
+ const formData = new FormData();
+ Object.entries(upload.fields).forEach(([key, value]) => {
+ formData.append(key, value);
+ });
+ formData.append("file", fileBlob, "result.mp4");
+
+ const xhr = new XMLHttpRequest();
+ xhr.open("POST", upload.url);
+
+ xhr.upload.onprogress = (event) => {
+ if (event.lengthComputable) {
+ const percent = (event.loaded / event.total) * 100;
+ setUploadStatus({
+ status: "uploadingVideo",
+ capId: currentVideoId,
+ progress: percent,
+ thumbnailUrl: thumbnailPreviewUrl,
+ });
+ sendProgressUpdate(currentVideoId, event.loaded, event.total);
+ }
+ };
+
+ xhr.onload = async () => {
+ if (xhr.status >= 200 && xhr.status < 300) {
+ await sendProgressUpdate(currentVideoId, blob.size, blob.size);
+ resolve();
+ } else {
+ const errorText = xhr.responseText || xhr.statusText || "Unknown error";
+ console.error("Upload failed:", {
+ status: xhr.status,
+ statusText: xhr.statusText,
+ responseText: errorText,
+ });
+ reject(
+ new Error(
+ `Upload failed with status ${xhr.status}: ${errorText}`
+ )
+ );
+ }
+ };
+
+ xhr.onerror = () => {
+ reject(new Error("Upload failed due to network error"));
+ };
+
+ xhr.send(formData);
+ }),
+ [setUploadStatus]
+ );
+
+ const startRecording = async () => {
+ if (!organisationId) {
+ toast.error("Select an organization before recording.");
+ return;
+ }
+
+ if (recordingMode === "camera" && !selectedCameraId) {
+ toast.error("Select a camera before recording.");
+ return;
+ }
+
+ setIsSettingUp(true);
+
+ try {
+ let videoStream: MediaStream | null = null;
+ let firstTrack: MediaStreamTrack | null = null;
+
+ if (recordingMode === "camera") {
+ if (!selectedCameraId) {
+ throw new Error("Camera ID is required for camera-only mode");
+ }
+ videoStream = await navigator.mediaDevices.getUserMedia({
+ video: {
+ deviceId: { exact: selectedCameraId },
+ frameRate: { ideal: 30 },
+ width: { ideal: 1920 },
+ height: { ideal: 1080 },
+ },
+ });
+ cameraStreamRef.current = videoStream;
+ firstTrack = videoStream.getVideoTracks()[0] ?? null;
+ } else {
+ const baseDisplayRequest: DisplayMediaStreamOptions = {
+ video: { ...DISPLAY_MEDIA_VIDEO_CONSTRAINTS },
+ audio: false,
+ };
+
+ const preferredOptions = DISPLAY_MODE_PREFERENCES[recordingMode];
+
+ if (preferredOptions) {
+ const preferredDisplayRequest: DisplayMediaStreamOptions = {
+ ...baseDisplayRequest,
+ ...preferredOptions,
+ };
+
+ try {
+ videoStream = await navigator.mediaDevices.getDisplayMedia(
+ preferredDisplayRequest
+ );
+ } catch (displayError) {
+ if (shouldRetryDisplayMediaWithoutPreferences(displayError)) {
+ console.warn(
+ "Display media preferences not supported, retrying without them",
+ displayError
+ );
+ videoStream = await navigator.mediaDevices.getDisplayMedia(
+ baseDisplayRequest
+ );
+ } else {
+ throw displayError;
+ }
+ }
+ }
+
+ if (!videoStream) {
+ videoStream = await navigator.mediaDevices.getDisplayMedia(
+ baseDisplayRequest
+ );
+ }
+ displayStreamRef.current = videoStream;
+ firstTrack = videoStream.getVideoTracks()[0] ?? null;
+ }
+
+ const settings = firstTrack?.getSettings();
+ dimensionsRef.current = {
+ width: settings?.width || undefined,
+ height: settings?.height || undefined,
+ };
+
+ let micStream: MediaStream | null = null;
+ if (micEnabled && selectedMicId) {
+ try {
+ micStream = await navigator.mediaDevices.getUserMedia({
+ audio: {
+ deviceId: { exact: selectedMicId },
+ echoCancellation: true,
+ autoGainControl: true,
+ noiseSuppression: true,
+ },
+ });
+ } catch (micError) {
+ console.warn("Microphone permission denied", micError);
+ toast.warning("Microphone unavailable. Recording without audio.");
+ micStream = null;
+ }
+ }
+
+ if (micStream) {
+ micStreamRef.current = micStream;
+ }
+
+ const mixedStream = new MediaStream([
+ ...videoStream.getVideoTracks(),
+ ...(micStream ? micStream.getAudioTracks() : []),
+ ]);
+
+ mixedStreamRef.current = mixedStream;
+ setHasAudioTrack(mixedStream.getAudioTracks().length > 0);
+
+ recordedChunksRef.current = [];
+
+ const mimeTypeCandidates = [
+ "video/webm;codecs=vp9,opus",
+ "video/webm;codecs=vp8,opus",
+ "video/webm",
+ ];
+ const mimeType = mimeTypeCandidates.find((candidate) =>
+ MediaRecorder.isTypeSupported(candidate)
+ );
+
+ const recorder = new MediaRecorder(
+ mixedStream,
+ mimeType ? { mimeType } : undefined
+ );
+ recorder.ondataavailable = onRecorderDataAvailable;
+ recorder.onstop = onRecorderStop;
+ recorder.onerror = onRecorderError;
+
+ const handleVideoEnded = () => {
+ stopRecordingRef.current?.().catch(() => {
+ /* ignore */
+ });
+ };
+
+ firstTrack?.addEventListener("ended", handleVideoEnded, { once: true });
+
+ mediaRecorderRef.current = recorder;
+ recorder.start(200);
+
+ startTimeRef.current = performance.now();
+ setDurationMs(0);
+ updatePhase("recording");
+
+ timerRef.current = window.setInterval(() => {
+ if (startTimeRef.current !== null)
+ setDurationMs(performance.now() - startTimeRef.current);
+ }, 250);
+ } catch (err) {
+ console.error("Failed to start recording", err);
+ toast.error("Could not start recording.");
+ resetState();
+ } finally {
+ setIsSettingUp(false);
+ }
+ };
+
+ const stopRecording = useCallback(async () => {
+ if (phase !== "recording") return;
+
+ let createdVideoId: VideoId | null = null;
+ const orgId = organisationId;
+ if (!orgId) {
+ updatePhase("error");
+ return;
+ }
+
+ const brandedOrgId = Organisation.OrganisationId.make(orgId);
+
+ let thumbnailBlob: Blob | null = null;
+ let thumbnailPreviewUrl: string | undefined;
+
+ try {
+ updatePhase("creating");
+
+ const blob = await stopRecordingInternal();
+ if (!blob) {
+ throw new Error("No recording available");
+ }
+
+ const durationSeconds = Math.max(1, Math.round(durationMs / 1000));
+ const width = dimensionsRef.current.width;
+ const height = dimensionsRef.current.height;
+ const resolution = width && height ? `${width}x${height}` : undefined;
+
+ setUploadStatus({ status: "creating" });
+
+ const result = await EffectRuntime.runPromise(
+ rpc.VideoInstantCreate({
+ orgId: brandedOrgId,
+ folderId: Option.none(),
+ resolution,
+ durationSeconds,
+ width,
+ height,
+ videoCodec: "h264",
+ audioCodec: hasAudioTrack ? "aac" : undefined,
+ supportsUploadProgress: true,
+ })
+ );
+
+ createdVideoId = result.id;
+ setVideoId(result.id);
+
+ const mp4Blob = await convertToMp4(blob, hasAudioTrack, result.id);
+
+ thumbnailBlob = await captureThumbnail(mp4Blob);
+ thumbnailPreviewUrl = thumbnailBlob
+ ? URL.createObjectURL(thumbnailBlob)
+ : undefined;
+
+ updatePhase("uploading");
+ setUploadStatus({
+ status: "uploadingVideo",
+ capId: result.id,
+ progress: 0,
+ thumbnailUrl: thumbnailPreviewUrl,
+ });
+
+ await uploadRecording(mp4Blob, result.upload, result.id, thumbnailPreviewUrl);
+
+ if (thumbnailBlob) {
+ try {
+ const screenshotData = await createVideoAndGetUploadUrl({
+ videoId: result.id,
+ isScreenshot: true,
+ orgId: brandedOrgId,
+ });
+
+ const screenshotFormData = new FormData();
+ Object.entries(screenshotData.presignedPostData.fields).forEach(
+ ([key, value]) => {
+ screenshotFormData.append(key, value as string);
+ }
+ );
+ screenshotFormData.append(
+ "file",
+ thumbnailBlob,
+ "screen-capture.jpg"
+ );
+
+ setUploadStatus({
+ status: "uploadingThumbnail",
+ capId: result.id,
+ progress: 90,
+ });
+
+ await new Promise((resolve, reject) => {
+ const xhr = new XMLHttpRequest();
+ xhr.open("POST", screenshotData.presignedPostData.url);
+
+ xhr.upload.onprogress = (event) => {
+ if (event.lengthComputable) {
+ const percent = 90 + (event.loaded / event.total) * 10;
+ setUploadStatus({
+ status: "uploadingThumbnail",
+ capId: result.id,
+ progress: percent,
+ });
+ }
+ };
+
+ xhr.onload = () => {
+ if (xhr.status >= 200 && xhr.status < 300) {
+ resolve();
+ } else {
+ reject(
+ new Error(
+ `Screenshot upload failed with status ${xhr.status}`
+ )
+ );
+ }
+ };
+
+ xhr.onerror = () => {
+ reject(new Error("Screenshot upload failed"));
+ };
+
+ xhr.send(screenshotFormData);
+ });
+
+ queryClient.refetchQueries({
+ queryKey: ThumbnailRequest.queryKey(result.id),
+ });
+ } catch (thumbnailError) {
+ console.error("Failed to upload thumbnail", thumbnailError);
+ toast.warning(
+ "Recording uploaded, but thumbnail failed to upload."
+ );
+ }
+ }
+
+ setUploadStatus(undefined);
+ updatePhase("completed");
+ toast.success("Recording uploaded");
+ router.refresh();
+ } catch (err) {
+ console.error("Failed to process recording", err);
+ setUploadStatus(undefined);
+ updatePhase("error");
+
+ const idToDelete = createdVideoId ?? videoId;
+ if (idToDelete) {
+ EffectRuntime.runPromise(rpc.VideoDelete(idToDelete)).catch(() => {
+ /* ignore */
+ });
+ }
+ } finally {
+ if (thumbnailPreviewUrl) {
+ URL.revokeObjectURL(thumbnailPreviewUrl);
+ }
+ }
+ }, [
+ phase,
+ organisationId,
+ durationMs,
+ hasAudioTrack,
+ videoId,
+ updatePhase,
+ setUploadStatus,
+ rpc,
+ router,
+ convertToMp4,
+ uploadRecording,
+ stopRecordingInternal,
+ captureThumbnail,
+ queryClient,
+ ]);
+
+ useEffect(() => {
+ stopRecordingRef.current = stopRecording;
+ }, [stopRecording]);
+
+ return {
+ phase,
+ durationMs,
+ videoId,
+ hasAudioTrack,
+ isSettingUp,
+ isRecording: phase === "recording",
+ isBusy:
+ phase === "recording" ||
+ phase === "creating" ||
+ phase === "converting" ||
+ phase === "uploading",
+ canStartRecording: Boolean(organisationId) && !isSettingUp,
+ startRecording,
+ stopRecording,
+ resetState,
+ };
+};
+
diff --git a/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/web-recorder-constants.ts b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/web-recorder-constants.ts
new file mode 100644
index 0000000000..52a83e7d9a
--- /dev/null
+++ b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/web-recorder-constants.ts
@@ -0,0 +1,32 @@
+export const NO_MICROPHONE = "No Microphone";
+export const NO_MICROPHONE_VALUE = "__no_microphone__";
+export const NO_CAMERA = "No Camera";
+export const NO_CAMERA_VALUE = "__no_camera__";
+
+export const dialogVariants = {
+ hidden: {
+ opacity: 0,
+ scale: 0.9,
+ y: 20,
+ },
+ visible: {
+ opacity: 1,
+ scale: 1,
+ y: 0,
+ transition: {
+ type: "spring",
+ duration: 0.4,
+ damping: 25,
+ stiffness: 500,
+ },
+ },
+ exit: {
+ opacity: 0,
+ scale: 0.95,
+ y: 10,
+ transition: {
+ duration: 0.2,
+ },
+ },
+};
+
diff --git a/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/web-recorder-types.ts b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/web-recorder-types.ts
new file mode 100644
index 0000000000..9675401db2
--- /dev/null
+++ b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/web-recorder-types.ts
@@ -0,0 +1,15 @@
+export type RecorderPhase =
+ | "idle"
+ | "recording"
+ | "creating"
+ | "converting"
+ | "uploading"
+ | "completed"
+ | "error";
+
+export type RecorderErrorEvent = Event & { error?: DOMException };
+
+type VideoNamespace = typeof import("@cap/web-domain").Video;
+export type PresignedPost = VideoNamespace["PresignedPost"]["Type"];
+export type VideoId = VideoNamespace["VideoId"]["Type"];
+
diff --git a/apps/web/app/(org)/dashboard/caps/components/index.ts b/apps/web/app/(org)/dashboard/caps/components/index.ts
index ced28c433b..44d2b5579f 100644
--- a/apps/web/app/(org)/dashboard/caps/components/index.ts
+++ b/apps/web/app/(org)/dashboard/caps/components/index.ts
@@ -5,3 +5,4 @@ export * from "./NewFolderDialog";
export * from "./SelectedCapsBar";
export * from "./UploadCapButton";
export * from "./UploadPlaceholderCard";
+export * from "./WebRecorderDialog/WebRecorderDialog";
diff --git a/apps/web/app/(org)/dashboard/caps/components/sendProgressUpdate.ts b/apps/web/app/(org)/dashboard/caps/components/sendProgressUpdate.ts
new file mode 100644
index 0000000000..edf31eb377
--- /dev/null
+++ b/apps/web/app/(org)/dashboard/caps/components/sendProgressUpdate.ts
@@ -0,0 +1,23 @@
+import { EffectRuntime } from "@/lib/EffectRuntime";
+import { withRpc } from "@/lib/Rpcs";
+
+export const sendProgressUpdate = async (
+ videoId: string,
+ uploaded: number,
+ total: number,
+) => {
+ try {
+ await EffectRuntime.runPromise(
+ withRpc((rpc) =>
+ rpc.VideoUploadProgressUpdate({
+ videoId,
+ uploaded,
+ total,
+ updatedAt: new Date(),
+ }),
+ ),
+ );
+ } catch (error) {
+ console.error("Failed to send progress update:", error);
+ }
+};
diff --git a/packages/web-backend/src/Videos/VideosRpcs.ts b/packages/web-backend/src/Videos/VideosRpcs.ts
index 8f843fa20b..a7880e135a 100644
--- a/packages/web-backend/src/Videos/VideosRpcs.ts
+++ b/packages/web-backend/src/Videos/VideosRpcs.ts
@@ -11,47 +11,90 @@ export const VideosRpcsLive = Video.VideoRpcs.toLayer(
return {
VideoDelete: (videoId) =>
videos.delete(videoId).pipe(
- Effect.catchTags({
- DatabaseError: () => new InternalError({ type: "database" }),
- S3Error: () => new InternalError({ type: "s3" }),
- }),
+ Effect.catchTag(
+ "DatabaseError",
+ () => new InternalError({ type: "database" }),
+ ),
+ Effect.catchTag(
+ "S3Error",
+ () => new InternalError({ type: "s3" }),
+ ),
),
VideoDuplicate: (videoId) =>
videos.duplicate(videoId).pipe(
- Effect.catchTags({
- DatabaseError: () => new InternalError({ type: "database" }),
- S3Error: () => new InternalError({ type: "s3" }),
- }),
+ Effect.catchTag(
+ "DatabaseError",
+ () => new InternalError({ type: "database" }),
+ ),
+ Effect.catchTag(
+ "S3Error",
+ () => new InternalError({ type: "s3" }),
+ ),
),
GetUploadProgress: (videoId) =>
videos.getUploadProgress(videoId).pipe(
provideOptionalAuth,
- Effect.catchTags({
- DatabaseError: () => new InternalError({ type: "database" }),
- UnknownException: () => new InternalError({ type: "unknown" }),
- }),
+ Effect.catchTag(
+ "DatabaseError",
+ () => new InternalError({ type: "database" }),
+ ),
+ Effect.catchTag(
+ "UnknownException",
+ () => new InternalError({ type: "unknown" }),
+ ),
+ ),
+
+ VideoInstantCreate: (input) =>
+ videos.createInstantRecording(input).pipe(
+ Effect.catchTag(
+ "DatabaseError",
+ () => new InternalError({ type: "database" }),
+ ),
+ Effect.catchTag(
+ "S3Error",
+ () => new InternalError({ type: "s3" }),
+ ),
+ ),
+
+ VideoUploadProgressUpdate: (input) =>
+ videos.updateUploadProgress(input).pipe(
+ Effect.catchTag(
+ "DatabaseError",
+ () => new InternalError({ type: "database" }),
+ ),
),
VideoGetDownloadInfo: (videoId) =>
videos.getDownloadInfo(videoId).pipe(
provideOptionalAuth,
- Effect.catchTags({
- DatabaseError: () => new InternalError({ type: "database" }),
- UnknownException: () => new InternalError({ type: "unknown" }),
- S3Error: () => new InternalError({ type: "s3" }),
- }),
+ Effect.catchTag(
+ "DatabaseError",
+ () => new InternalError({ type: "database" }),
+ ),
+ Effect.catchTag(
+ "UnknownException",
+ () => new InternalError({ type: "unknown" }),
+ ),
+ Effect.catchTag(
+ "S3Error",
+ () => new InternalError({ type: "s3" }),
+ ),
),
VideosGetThumbnails: (videoIds) =>
Effect.all(
videoIds.map((id) =>
videos.getThumbnailURL(id).pipe(
- Effect.catchTags({
- DatabaseError: () => new InternalError({ type: "database" }),
- S3Error: () => new InternalError({ type: "s3" }),
- }),
+ Effect.catchTag(
+ "DatabaseError",
+ () => new InternalError({ type: "database" }),
+ ),
+ Effect.catchTag(
+ "S3Error",
+ () => new InternalError({ type: "s3" }),
+ ),
Effect.matchEffect({
onSuccess: (v) => Effect.succeed(Exit.succeed(v)),
onFailure: (e) =>
@@ -65,20 +108,28 @@ export const VideosRpcsLive = Video.VideoRpcs.toLayer(
{ concurrency: 10 },
).pipe(
provideOptionalAuth,
- Effect.catchTags({
- DatabaseError: () => new InternalError({ type: "database" }),
- UnknownException: () => new InternalError({ type: "unknown" }),
- }),
+ Effect.catchTag(
+ "DatabaseError",
+ () => new InternalError({ type: "database" }),
+ ),
+ Effect.catchTag(
+ "UnknownException",
+ () => new InternalError({ type: "unknown" }),
+ ),
),
VideosGetAnalytics: (videoIds) =>
Effect.all(
videoIds.map((id) =>
videos.getAnalytics(id).pipe(
- Effect.catchTags({
- DatabaseError: () => new InternalError({ type: "database" }),
- UnknownException: () => new InternalError({ type: "unknown" }),
- }),
+ Effect.catchTag(
+ "DatabaseError",
+ () => new InternalError({ type: "database" }),
+ ),
+ Effect.catchTag(
+ "UnknownException",
+ () => new InternalError({ type: "unknown" }),
+ ),
Effect.matchEffect({
onSuccess: (v) => Effect.succeed(Exit.succeed(v)),
onFailure: (e) =>
@@ -92,10 +143,14 @@ export const VideosRpcsLive = Video.VideoRpcs.toLayer(
{ concurrency: 10 },
).pipe(
provideOptionalAuth,
- Effect.catchTags({
- DatabaseError: () => new InternalError({ type: "database" }),
- UnknownException: () => new InternalError({ type: "unknown" }),
- }),
+ Effect.catchTag(
+ "DatabaseError",
+ () => new InternalError({ type: "database" }),
+ ),
+ Effect.catchTag(
+ "UnknownException",
+ () => new InternalError({ type: "unknown" }),
+ ),
),
};
}),
diff --git a/packages/web-backend/src/Videos/index.ts b/packages/web-backend/src/Videos/index.ts
index b85a464e7e..f58c02ab74 100644
--- a/packages/web-backend/src/Videos/index.ts
+++ b/packages/web-backend/src/Videos/index.ts
@@ -1,14 +1,23 @@
import * as Db from "@cap/database/schema";
+import { buildEnv, NODE_ENV, serverEnv } from "@cap/env";
import { dub } from "@cap/utils";
-import { CurrentUser, Policy, Video } from "@cap/web-domain";
+import { CurrentUser, Folder, Policy, Video } from "@cap/web-domain";
import * as Dz from "drizzle-orm";
import { Array, Effect, Option, pipe } from "effect";
+import type { Schema } from "effect/Schema";
import { Database } from "../Database.ts";
import { S3Buckets } from "../S3Buckets/index.ts";
import { VideosPolicy } from "./VideosPolicy.ts";
import { VideosRepo } from "./VideosRepo.ts";
+type UploadProgressUpdateInput = Schema.Type<
+ typeof Video.UploadProgressUpdateInput
+>;
+type InstantRecordingCreateInput = Schema.Type<
+ typeof Video.InstantRecordingCreateInput
+>;
+
export class Videos extends Effect.Service()("Videos", {
effect: Effect.gen(function* () {
const db = yield* Database;
@@ -131,6 +140,171 @@ export class Videos extends Effect.Service()("Videos", {
);
}),
+ updateUploadProgress: Effect.fn("Videos.updateUploadProgress")(function* (
+ input: UploadProgressUpdateInput,
+ ) {
+ const user = yield* CurrentUser;
+
+ const uploaded = Math.min(input.uploaded, input.total);
+ const total = input.total;
+ const updatedAt = input.updatedAt;
+ const videoId = input.videoId;
+
+ const [record] = yield* db.use((db) =>
+ db
+ .select({
+ video: Db.videos,
+ upload: Db.videoUploads,
+ })
+ .from(Db.videos)
+ .leftJoin(
+ Db.videoUploads,
+ Dz.eq(Db.videos.id, Db.videoUploads.videoId),
+ )
+ .where(
+ Dz.and(
+ Dz.eq(Db.videos.id, videoId),
+ Dz.eq(Db.videos.ownerId, user.id),
+ ),
+ ),
+ );
+
+ if (!record) return yield* new Video.NotFoundError();
+
+ yield* db.use((db) =>
+ db.transaction(async (tx) => {
+ if (record.upload) {
+ if (uploaded === total && record.upload.mode === "singlepart") {
+ await tx
+ .delete(Db.videoUploads)
+ .where(Dz.eq(Db.videoUploads.videoId, videoId));
+ return;
+ }
+
+ await tx
+ .update(Db.videoUploads)
+ .set({
+ uploaded,
+ total,
+ updatedAt,
+ })
+ .where(
+ Dz.and(
+ Dz.eq(Db.videoUploads.videoId, videoId),
+ Dz.lte(Db.videoUploads.updatedAt, updatedAt),
+ ),
+ );
+ return;
+ }
+
+ await tx.insert(Db.videoUploads).values({
+ videoId,
+ uploaded,
+ total,
+ updatedAt,
+ });
+ }),
+ );
+
+ return true as const;
+ }),
+
+ createInstantRecording: Effect.fn("Videos.createInstantRecording")(
+ function* (input: InstantRecordingCreateInput) {
+ const user = yield* CurrentUser;
+
+ if (user.activeOrganizationId !== input.orgId)
+ return yield* new Policy.PolicyDeniedError();
+
+ const [customBucket] = yield* db.use((db) =>
+ db
+ .select()
+ .from(Db.s3Buckets)
+ .where(Dz.eq(Db.s3Buckets.ownerId, user.id)),
+ );
+
+ const bucketId = Option.fromNullable(customBucket?.id);
+ const folderId = input.folderId ?? Option.none();
+ const width = Option.fromNullable(input.width);
+ const height = Option.fromNullable(input.height);
+ const duration = Option.fromNullable(input.durationSeconds);
+
+ const now = new Date();
+ const formattedDate = `${now.getDate()} ${now.toLocaleString("default", {
+ month: "long",
+ })} ${now.getFullYear()}`;
+
+ const videoId = yield* repo.create({
+ ownerId: user.id,
+ orgId: input.orgId,
+ name: `Cap Recording - ${formattedDate}`,
+ public: serverEnv().CAP_VIDEOS_DEFAULT_PUBLIC,
+ source: { type: "desktopMP4" as const },
+ bucketId,
+ folderId,
+ width,
+ height,
+ duration,
+ metadata: Option.none(),
+ transcriptionStatus: Option.none(),
+ });
+
+ if (input.supportsUploadProgress ?? true)
+ yield* db.use((db) =>
+ db.insert(Db.videoUploads).values({
+ videoId,
+ mode: "singlepart",
+ }),
+ );
+
+ const fileKey = `${user.id}/${videoId}/result.mp4`;
+ const [bucket] = yield* s3Buckets.getBucketAccess(bucketId);
+ const presignedPostData = yield* bucket.getPresignedPostUrl(
+ fileKey,
+ {
+ Fields: {
+ "Content-Type": "video/mp4",
+ "x-amz-meta-userid": user.id,
+ "x-amz-meta-duration": input.durationSeconds
+ ? input.durationSeconds.toString()
+ : "",
+ "x-amz-meta-resolution": input.resolution ?? "",
+ "x-amz-meta-videocodec": input.videoCodec ?? "",
+ "x-amz-meta-audiocodec": input.audioCodec ?? "",
+ },
+ Expires: 1800,
+ },
+ );
+
+ const shareUrl = `${serverEnv().WEB_URL}/s/${videoId}`;
+
+ if (buildEnv.NEXT_PUBLIC_IS_CAP && NODE_ENV === "production")
+ yield* Effect.tryPromise(() =>
+ dub()
+ .links.create({
+ url: shareUrl,
+ domain: "cap.link",
+ key: videoId,
+ }),
+ ).pipe(
+ Effect.catchAll((error) =>
+ Effect.logWarning(
+ `Dub link create failed: ${String(error)}`,
+ ),
+ ),
+ );
+
+ return {
+ id: videoId,
+ shareUrl,
+ upload: {
+ url: presignedPostData.url,
+ fields: presignedPostData.fields,
+ },
+ };
+ },
+ ),
+
create: Effect.fn("Videos.create")(repo.create),
getDownloadInfo: Effect.fn("Videos.getDownloadInfo")(function* (
diff --git a/packages/web-domain/src/Video.ts b/packages/web-domain/src/Video.ts
index 98d8c633bf..8247836341 100644
--- a/packages/web-domain/src/Video.ts
+++ b/packages/web-domain/src/Video.ts
@@ -67,6 +67,36 @@ export class UploadProgress extends Schema.Class(
updatedAt: Schema.Date,
}) {}
+export const UploadProgressUpdateInput = Schema.Struct({
+ videoId: VideoId,
+ uploaded: Schema.Int.pipe(Schema.greaterThanOrEqualTo(0)),
+ total: Schema.Int.pipe(Schema.greaterThanOrEqualTo(0)),
+ updatedAt: Schema.Date,
+});
+
+export const PresignedPost = Schema.Struct({
+ url: Schema.String,
+ fields: Schema.Record({ key: Schema.String, value: Schema.String }),
+});
+
+export const InstantRecordingCreateInput = Schema.Struct({
+ orgId: OrganisationId,
+ folderId: Schema.OptionFromUndefinedOr(FolderId),
+ durationSeconds: Schema.optional(Schema.Number),
+ resolution: Schema.optional(Schema.String),
+ width: Schema.optional(Schema.Number),
+ height: Schema.optional(Schema.Number),
+ videoCodec: Schema.optional(Schema.String),
+ audioCodec: Schema.optional(Schema.String),
+ supportsUploadProgress: Schema.optional(Schema.Boolean),
+});
+
+export const InstantRecordingCreateSuccess = Schema.Struct({
+ id: VideoId,
+ shareUrl: Schema.String,
+ upload: PresignedPost,
+});
+
export class ImportSource extends Schema.Class("ImportSource")({
source: Schema.Literal("loom"),
id: Schema.String,
@@ -157,6 +187,20 @@ export class VideoRpcs extends RpcGroup.make(
VerifyVideoPasswordError,
),
}),
+ Rpc.make("VideoInstantCreate", {
+ payload: InstantRecordingCreateInput,
+ success: InstantRecordingCreateSuccess,
+ error: Schema.Union(InternalError, PolicyDeniedError),
+ }).middleware(RpcAuthMiddleware),
+ Rpc.make("VideoUploadProgressUpdate", {
+ payload: UploadProgressUpdateInput,
+ success: Schema.Boolean,
+ error: Schema.Union(
+ NotFoundError,
+ InternalError,
+ PolicyDeniedError,
+ ),
+ }).middleware(RpcAuthMiddleware),
Rpc.make("VideoGetDownloadInfo", {
payload: VideoId,
success: Schema.Option(
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index a08cf69e61..7a134c774a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -115,7 +115,7 @@ importers:
version: 0.14.10(solid-js@1.9.6)
'@solidjs/start':
specifier: ^1.1.3
- version: 1.1.3(@testing-library/jest-dom@6.5.0)(@types/node@22.15.17)(jiti@2.6.1)(solid-js@1.9.6)(terser@5.44.0)(vinxi@0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(rolldown@1.0.0-beta.43)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1))(vite@6.3.5(@types/node@22.15.17)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1)
+ version: 1.1.3(@testing-library/jest-dom@6.5.0)(@types/node@22.15.17)(jiti@2.6.1)(solid-js@1.9.6)(terser@5.44.0)(vinxi@0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1))(vite@6.3.5(@types/node@22.15.17)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1)
'@tanstack/solid-query':
specifier: ^5.51.21
version: 5.75.4(solid-js@1.9.6)
@@ -202,7 +202,7 @@ importers:
version: 9.0.1
vinxi:
specifier: ^0.5.6
- version: 0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(rolldown@1.0.0-beta.43)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1)
+ version: 0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1)
webcodecs:
specifier: ^0.1.0
version: 0.1.0
@@ -342,88 +342,6 @@ importers:
specifier: ^2.10.2
version: 2.11.6(@testing-library/jest-dom@6.5.0)(solid-js@1.9.6)(vite@6.3.5(@types/node@22.15.17)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))
- apps/tasks:
- dependencies:
- '@types/cors':
- specifier: ^2.8.17
- version: 2.8.17
- '@types/express':
- specifier: ^4.17.21
- version: 4.17.21
- '@types/fluent-ffmpeg':
- specifier: ^2.1.24
- version: 2.1.27
- '@types/jest':
- specifier: ^29.5.12
- version: 29.5.14
- '@types/morgan':
- specifier: ^1.9.9
- version: 1.9.9
- '@types/node':
- specifier: ^20.12.6
- version: 20.17.43
- '@types/supertest':
- specifier: ^6.0.2
- version: 6.0.3
- cors:
- specifier: ^2.8.5
- version: 2.8.5
- dotenv:
- specifier: ^16.4.5
- version: 16.5.0
- express:
- specifier: ^4.19.2
- version: 4.21.2
- fluent-ffmpeg:
- specifier: ^2.1.3
- version: 2.1.3
- helmet:
- specifier: ^7.1.0
- version: 7.2.0
- morgan:
- specifier: ^1.10.0
- version: 1.10.0
- ts-node:
- specifier: ^10.9.2
- version: 10.9.2(@types/node@20.17.43)(typescript@5.8.3)
- typescript:
- specifier: ^5.8.3
- version: 5.8.3
- zod:
- specifier: ^3
- version: 3.25.76
- devDependencies:
- '@typescript-eslint/eslint-plugin':
- specifier: ^7.6.0
- version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3)
- '@typescript-eslint/parser':
- specifier: ^7.6.0
- version: 7.18.0(eslint@8.57.1)(typescript@5.8.3)
- eslint:
- specifier: ^8.57.0
- version: 8.57.1
- eslint-config-airbnb-typescript:
- specifier: ^18.0.0
- version: 18.0.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3))(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.8.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1)
- eslint-import-resolver-typescript:
- specifier: ^3.6.1
- version: 3.10.1(eslint-plugin-import@2.31.0)(eslint@8.57.1)
- eslint-plugin-import:
- specifier: ^2.29.1
- version: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1)
- jest:
- specifier: ^29.7.0
- version: 29.7.0(@types/node@20.17.43)(ts-node@10.9.2(@types/node@20.17.43)(typescript@5.8.3))
- nodemon:
- specifier: ^3.1.0
- version: 3.1.10
- supertest:
- specifier: ^6.3.4
- version: 6.3.4
- ts-jest:
- specifier: ^29.1.2
- version: 29.3.2(@babel/core@7.27.1)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.1))(jest@29.7.0(@types/node@20.17.43)(ts-node@10.9.2(@types/node@20.17.43)(typescript@5.8.3)))(typescript@5.8.3)
-
apps/web:
dependencies:
'@aws-sdk/client-cloudfront':
@@ -704,7 +622,7 @@ importers:
version: 15.5.4(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
next-auth:
specifier: ^4.24.5
- version: 4.24.11(next@15.5.4(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(nodemailer@6.10.1)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
+ version: 4.24.11(next@15.5.4(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(nodemailer@6.10.1)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
next-contentlayer2:
specifier: ^0.5.3
version: 0.5.8(acorn@8.15.0)(contentlayer2@0.5.8(acorn@8.15.0)(esbuild@0.25.5))(esbuild@0.25.5)(next@15.5.4(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
@@ -1017,7 +935,7 @@ importers:
version: 15.5.4(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
next-auth:
specifier: ^4.24.5
- version: 4.24.11(next@15.5.4(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(nodemailer@6.10.1)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
+ version: 4.24.11(next@15.5.4(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(nodemailer@6.10.1)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
react-email:
specifier: ^4.0.16
version: 4.0.16(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
@@ -1822,91 +1740,12 @@ packages:
engines: {node: '>=6.0.0'}
hasBin: true
- '@babel/plugin-syntax-async-generators@7.8.4':
- resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-syntax-bigint@7.8.3':
- resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-syntax-class-properties@7.12.13':
- resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-syntax-class-static-block@7.14.5':
- resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-syntax-import-attributes@7.27.1':
- resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-syntax-import-meta@7.10.4':
- resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-syntax-json-strings@7.8.3':
- resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
'@babel/plugin-syntax-jsx@7.27.1':
resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
- '@babel/plugin-syntax-logical-assignment-operators@7.10.4':
- resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3':
- resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-syntax-numeric-separator@7.10.4':
- resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-syntax-object-rest-spread@7.8.3':
- resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-syntax-optional-catch-binding@7.8.3':
- resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-syntax-optional-chaining@7.8.3':
- resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-syntax-private-property-in-object@7.14.5':
- resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-syntax-top-level-await@7.14.5':
- resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
'@babel/plugin-syntax-typescript@7.27.1':
resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==}
engines: {node: '>=6.9.0'}
@@ -1973,9 +1812,6 @@ packages:
resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==}
engines: {node: '>=6.9.0'}
- '@bcoe/v8-coverage@0.2.3':
- resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
-
'@biomejs/biome@2.2.0':
resolution: {integrity: sha512-3On3RSYLsX+n9KnoSgfoYlckYBoU6VRM22cw1gB4Y0OuUVSYd/O/2saOJMrA4HFfA1Ff0eacOvMN1yAAvHtzIw==}
engines: {node: '>=14.21.3'}
@@ -2359,9 +2195,6 @@ packages:
'@effect/rpc': ^0.71.0
effect: ^3.18.1
- '@emnapi/core@1.4.3':
- resolution: {integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==}
-
'@emnapi/core@1.5.0':
resolution: {integrity: sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==}
@@ -2371,9 +2204,6 @@ packages:
'@emnapi/runtime@1.5.0':
resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==}
- '@emnapi/wasi-threads@1.0.2':
- resolution: {integrity: sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==}
-
'@emnapi/wasi-threads@1.1.0':
resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==}
@@ -3698,80 +3528,6 @@ packages:
'@isaacs/string-locale-compare@1.1.0':
resolution: {integrity: sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==}
- '@istanbuljs/load-nyc-config@1.1.0':
- resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==}
- engines: {node: '>=8'}
-
- '@istanbuljs/schema@0.1.3':
- resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==}
- engines: {node: '>=8'}
-
- '@jest/console@29.7.0':
- resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- '@jest/core@29.7.0':
- resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- peerDependencies:
- node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
- peerDependenciesMeta:
- node-notifier:
- optional: true
-
- '@jest/environment@29.7.0':
- resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- '@jest/expect-utils@29.7.0':
- resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- '@jest/expect@29.7.0':
- resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- '@jest/fake-timers@29.7.0':
- resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- '@jest/globals@29.7.0':
- resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- '@jest/reporters@29.7.0':
- resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- peerDependencies:
- node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
- peerDependenciesMeta:
- node-notifier:
- optional: true
-
- '@jest/schemas@29.6.3':
- resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- '@jest/source-map@29.6.3':
- resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- '@jest/test-result@29.7.0':
- resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- '@jest/test-sequencer@29.7.0':
- resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- '@jest/transform@29.7.0':
- resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- '@jest/types@29.6.3':
- resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
'@jridgewell/gen-mapping@0.3.13':
resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
@@ -4517,6 +4273,9 @@ packages:
'@oxc-project/types@0.94.0':
resolution: {integrity: sha512-+UgQT/4o59cZfH6Cp7G0hwmqEQ0wE+AdIwhikdwnhWI9Dp8CgSY081+Q3O67/wq3VJu8mgUEB93J9EHHn70fOw==}
+ '@oxc-project/types@0.95.0':
+ resolution: {integrity: sha512-vACy7vhpMPhjEJhULNxrdR0D943TkA/MigMpJCHmBHvMXxRStRi/dPtTlfQ3uDwWSzRpT8z+7ImjZVf8JWBocQ==}
+
'@panva/hkdf@1.2.1':
resolution: {integrity: sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==}
@@ -5445,8 +5204,8 @@ packages:
cpu: [arm64]
os: [android]
- '@rolldown/binding-android-arm64@1.0.0-beta.43':
- resolution: {integrity: sha512-TP8bcPOb1s6UmY5syhXrDn9k0XkYcw+XaoylTN4cJxf0JOVS2j682I3aTcpfT51hOFGr2bRwNKN9RZ19XxeQbA==}
+ '@rolldown/binding-android-arm64@1.0.0-beta.45':
+ resolution: {integrity: sha512-bfgKYhFiXJALeA/riil908+2vlyWGdwa7Ju5S+JgWZYdR4jtiPOGdM6WLfso1dojCh+4ZWeiTwPeV9IKQEX+4g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [android]
@@ -5457,8 +5216,8 @@ packages:
cpu: [arm64]
os: [darwin]
- '@rolldown/binding-darwin-arm64@1.0.0-beta.43':
- resolution: {integrity: sha512-kuVWnZsE4vEjMF/10SbSUyzucIW2zmdsqFghYMqy+fsjXnRHg0luTU6qWF8IqJf4Cbpm9NEZRnjIEPpAbdiSNQ==}
+ '@rolldown/binding-darwin-arm64@1.0.0-beta.45':
+ resolution: {integrity: sha512-xjCv4CRVsSnnIxTuyH1RDJl5OEQ1c9JYOwfDAHddjJDxCw46ZX9q80+xq7Eok7KC4bRSZudMJllkvOKv0T9SeA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [darwin]
@@ -5469,8 +5228,8 @@ packages:
cpu: [x64]
os: [darwin]
- '@rolldown/binding-darwin-x64@1.0.0-beta.43':
- resolution: {integrity: sha512-u9Ps4sh6lcmJ3vgLtyEg/x4jlhI64U0mM93Ew+tlfFdLDe7yKyA+Fe80cpr2n1mNCeZXrvTSbZluKpXQ0GxLjw==}
+ '@rolldown/binding-darwin-x64@1.0.0-beta.45':
+ resolution: {integrity: sha512-ddcO9TD3D/CLUa/l8GO8LHzBOaZqWg5ClMy3jICoxwCuoz47h9dtqPsIeTiB6yR501LQTeDsjA4lIFd7u3Ljfw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [darwin]
@@ -5481,8 +5240,8 @@ packages:
cpu: [x64]
os: [freebsd]
- '@rolldown/binding-freebsd-x64@1.0.0-beta.43':
- resolution: {integrity: sha512-h9lUtVtXgfbk/tnicMpbFfZ3DJvk5Zn2IvmlC1/e0+nUfwoc/TFqpfrRRqcNBXk/e+xiWMSKv6b0MF8N+Rtvlg==}
+ '@rolldown/binding-freebsd-x64@1.0.0-beta.45':
+ resolution: {integrity: sha512-MBTWdrzW9w+UMYDUvnEuh0pQvLENkl2Sis15fHTfHVW7ClbGuez+RWopZudIDEGkpZXdeI4CkRXk+vdIIebrmg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [freebsd]
@@ -5493,8 +5252,8 @@ packages:
cpu: [arm]
os: [linux]
- '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.43':
- resolution: {integrity: sha512-IX2C6bA6wM2rX/RvD75ko+ix9yxPKjKGGq7pOhB8wGI4Z4fqX5B1nDHga/qMDmAdCAR1m9ymzxkmqhm/AFYf7A==}
+ '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.45':
+ resolution: {integrity: sha512-4YgoCFiki1HR6oSg+GxxfzfnVCesQxLF1LEnw9uXS/MpBmuog0EOO2rYfy69rWP4tFZL9IWp6KEfGZLrZ7aUog==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
@@ -5505,8 +5264,8 @@ packages:
cpu: [arm64]
os: [linux]
- '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.43':
- resolution: {integrity: sha512-mcjd57vEj+CEQbZAzUiaxNzNgwwgOpFtZBWcINm8DNscvkXl5b/s622Z1dqGNWSdrZmdjdC6LWMvu8iHM6v9sQ==}
+ '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.45':
+ resolution: {integrity: sha512-LE1gjAwQRrbCOorJJ7LFr10s5vqYf5a00V5Ea9wXcT2+56n5YosJkcp8eQ12FxRBv2YX8dsdQJb+ZTtYJwb6XQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
@@ -5517,8 +5276,8 @@ packages:
cpu: [arm64]
os: [linux]
- '@rolldown/binding-linux-arm64-musl@1.0.0-beta.43':
- resolution: {integrity: sha512-Pa8QMwlkrztTo/1mVjZmPIQ44tCSci10TBqxzVBvXVA5CFh5EpiEi99fPSll2dHG2uT4dCOMeC6fIhyDdb0zXA==}
+ '@rolldown/binding-linux-arm64-musl@1.0.0-beta.45':
+ resolution: {integrity: sha512-tdy8ThO/fPp40B81v0YK3QC+KODOmzJzSUOO37DinQxzlTJ026gqUSOM8tzlVixRbQJltgVDCTYF8HNPRErQTA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
@@ -5529,8 +5288,8 @@ packages:
cpu: [x64]
os: [linux]
- '@rolldown/binding-linux-x64-gnu@1.0.0-beta.43':
- resolution: {integrity: sha512-BgynXKMjeaX4AfWLARhOKDetBOOghnSiVRjAHVvhiAaDXgdQN8e65mSmXRiVoVtD3cHXx/cfU8Gw0p0K+qYKVQ==}
+ '@rolldown/binding-linux-x64-gnu@1.0.0-beta.45':
+ resolution: {integrity: sha512-lS082ROBWdmOyVY/0YB3JmsiClaWoxvC+dA8/rbhyB9VLkvVEaihLEOr4CYmrMse151C4+S6hCw6oa1iewox7g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
@@ -5541,8 +5300,8 @@ packages:
cpu: [x64]
os: [linux]
- '@rolldown/binding-linux-x64-musl@1.0.0-beta.43':
- resolution: {integrity: sha512-VIsoPlOB/tDSAw9CySckBYysoIBqLeps1/umNSYUD8pMtalJyzMTneAVI1HrUdf4ceFmQ5vARoLIXSsPwVFxNg==}
+ '@rolldown/binding-linux-x64-musl@1.0.0-beta.45':
+ resolution: {integrity: sha512-Hi73aYY0cBkr1/SvNQqH8Cd+rSV6S9RB5izCv0ySBcRnd/Wfn5plguUoGYwBnhHgFbh6cPw9m2dUVBR6BG1gxA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
@@ -5553,8 +5312,8 @@ packages:
cpu: [arm64]
os: [openharmony]
- '@rolldown/binding-openharmony-arm64@1.0.0-beta.43':
- resolution: {integrity: sha512-YDXTxVJG67PqTQMKyjVJSddoPbSWJ4yRz/E3xzTLHqNrTDGY0UuhG8EMr8zsYnfH/0cPFJ3wjQd/hJWHuR6nkA==}
+ '@rolldown/binding-openharmony-arm64@1.0.0-beta.45':
+ resolution: {integrity: sha512-fljEqbO7RHHogNDxYtTzr+GNjlfOx21RUyGmF+NrkebZ8emYYiIqzPxsaMZuRx0rgZmVmliOzEp86/CQFDKhJQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [openharmony]
@@ -5564,8 +5323,8 @@ packages:
engines: {node: '>=14.0.0'}
cpu: [wasm32]
- '@rolldown/binding-wasm32-wasi@1.0.0-beta.43':
- resolution: {integrity: sha512-3M+2DmorXvDuAIGYQ9Z93Oy1G9ETkejLwdXXb1uRTgKN9pMcu7N+KG2zDrJwqyxeeLIFE22AZGtSJm3PJbNu9Q==}
+ '@rolldown/binding-wasm32-wasi@1.0.0-beta.45':
+ resolution: {integrity: sha512-ZJDB7lkuZE9XUnWQSYrBObZxczut+8FZ5pdanm8nNS1DAo8zsrPuvGwn+U3fwU98WaiFsNrA4XHngesCGr8tEQ==}
engines: {node: '>=14.0.0'}
cpu: [wasm32]
@@ -5575,8 +5334,8 @@ packages:
cpu: [arm64]
os: [win32]
- '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.43':
- resolution: {integrity: sha512-/B1j1pJs33y9ywtslOMxryUPHq8zIGu/OGEc2gyed0slimJ8fX2uR/SaJVhB4+NEgCFIeYDR4CX6jynAkeRuCA==}
+ '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.45':
+ resolution: {integrity: sha512-zyzAjItHPUmxg6Z8SyRhLdXlJn3/D9KL5b9mObUrBHhWS/GwRH4665xCiFqeuktAhhWutqfc+rOV2LjK4VYQGQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [win32]
@@ -5587,8 +5346,8 @@ packages:
cpu: [ia32]
os: [win32]
- '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.43':
- resolution: {integrity: sha512-29oG1swCz7hNP+CQYrsM4EtylsKwuYzM8ljqbqC5TsQwmKat7P8ouDpImsqg/GZxFSXcPP9ezQm0Q0wQwGM3JA==}
+ '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.45':
+ resolution: {integrity: sha512-wODcGzlfxqS6D7BR0srkJk3drPwXYLu7jPHN27ce2c4PUnVVmJnp9mJzUQGT4LpmHmmVdMZ+P6hKvyTGBzc1CA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ia32]
os: [win32]
@@ -5599,8 +5358,8 @@ packages:
cpu: [x64]
os: [win32]
- '@rolldown/binding-win32-x64-msvc@1.0.0-beta.43':
- resolution: {integrity: sha512-eWBV1Ef3gfGNehxVGCyXs7wLayRIgCmyItuCZwYYXW5bsk4EvR4n2GP5m3ohjnx7wdiY3nLmwQfH2Knb5gbNZw==}
+ '@rolldown/binding-win32-x64-msvc@1.0.0-beta.45':
+ resolution: {integrity: sha512-wiU40G1nQo9rtfvF9jLbl79lUgjfaD/LTyUEw2Wg/gdF5OhjzpKMVugZQngO+RNdwYaNj+Fs+kWBWfp4VXPMHA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [win32]
@@ -5608,8 +5367,8 @@ packages:
'@rolldown/pluginutils@1.0.0-beta.42':
resolution: {integrity: sha512-N7pQzk9CyE7q0bBN/q0J8s6Db279r5kUZc6d7/wWRe9/zXqC52HQovVyu6iXPIDY4BEzzgbVLhVFXrOuGJ22ZQ==}
- '@rolldown/pluginutils@1.0.0-beta.43':
- resolution: {integrity: sha512-5Uxg7fQUCmfhax7FJke2+8B6cqgeUJUD9o2uXIKXhD+mG0mL6NObmVoi9wXEU1tY89mZKgAYA6fTbftx3q2ZPQ==}
+ '@rolldown/pluginutils@1.0.0-beta.45':
+ resolution: {integrity: sha512-Le9ulGCrD8ggInzWw/k2J8QcbPz7eGIOWqfJ2L+1R0Opm7n6J37s2hiDWlh6LJN0Lk9L5sUzMvRHKW7UxBZsQA==}
'@rollup/plugin-alias@5.1.1':
resolution: {integrity: sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ==}
@@ -5837,9 +5596,6 @@ packages:
resolution: {integrity: sha512-8iKx79/F73DKbGfRf7+t4dqrc0bRr0thdPrxAtCKWRm/F0tG71i6O1rvlnScncJLLBZHn3h8M3c1BSUAb9yu8g==}
engines: {node: ^16.14.0 || >=18.0.0}
- '@sinclair/typebox@0.27.8':
- resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
-
'@sindresorhus/is@4.6.0':
resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==}
engines: {node: '>=10'}
@@ -5852,12 +5608,6 @@ packages:
resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==}
engines: {node: '>=18'}
- '@sinonjs/commons@3.0.1':
- resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==}
-
- '@sinonjs/fake-timers@10.3.0':
- resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==}
-
'@smithy/abort-controller@4.0.2':
resolution: {integrity: sha512-Sl/78VDtgqKxN2+1qduaVE140XF+Xg+TafkncspwM4jFP/LHr76ZHmIY/y3V1M0mMLNk+Je6IGbzxy23RSToMw==}
engines: {node: '>=18.0.0'}
@@ -6495,10 +6245,10 @@ packages:
react-dom:
optional: true
- '@storybook/builder-vite@10.0.0-beta.13':
- resolution: {integrity: sha512-ZPxqgoofi2yfJRQkkEBINSzPjkhrgfh4HsPs4fsbPt3jfVyfP4Wic7vHep4UlR1os2iL2MTRLcapkkiajoztWQ==}
+ '@storybook/builder-vite@10.1.0-alpha.3':
+ resolution: {integrity: sha512-bMgykL7QJCJREt0VyMBmTmEyxOkwssbOoKC6nMoJ8Ltnc8Sxr7g1nWSJyTnRvfrynCeUjJXQCKZOEw8LAzfSGA==}
peerDependencies:
- storybook: ^10.0.0-beta.13
+ storybook: ^10.1.0-alpha.3
vite: ^5.0.0 || ^6.0.0 || ^7.0.0
'@storybook/core@8.6.12':
@@ -6509,12 +6259,12 @@ packages:
prettier:
optional: true
- '@storybook/csf-plugin@10.0.0-beta.13':
- resolution: {integrity: sha512-mjdDsl5MAn6bLZHHInut+TQjYUJDdErpXnYlXPLvZRoaCxqxLN2O2sf5LmxAP9SRjEdKnsLFvBwMCJxVcav/lQ==}
+ '@storybook/csf-plugin@10.1.0-alpha.3':
+ resolution: {integrity: sha512-0RBdc8R/iWdWTnHYvIfqWhdJWdRckLRPs2puu0xNOax3eX69zhPPXsx5XS6j1LCJYom3sNegX578HgkCu7snzg==}
peerDependencies:
esbuild: '*'
rollup: '*'
- storybook: ^10.0.0-beta.13
+ storybook: ^10.1.0-alpha.3
vite: '*'
webpack: '*'
peerDependenciesMeta:
@@ -7021,15 +6771,9 @@ packages:
'@types/cookie@0.6.0':
resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
- '@types/cookiejar@2.1.5':
- resolution: {integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==}
-
'@types/cookies@0.9.0':
resolution: {integrity: sha512-40Zk8qR147RABiQ7NQnBzWzDcjKzNrntB5BAmeGCb2p/MIyOE+4BVvc17wumsUqUw00bJYqoXFHYygQnEFh4/Q==}
- '@types/cors@2.8.17':
- resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==}
-
'@types/cors@2.8.19':
resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==}
@@ -7063,15 +6807,9 @@ packages:
'@types/file-saver@2.0.7':
resolution: {integrity: sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==}
- '@types/fluent-ffmpeg@2.1.27':
- resolution: {integrity: sha512-QiDWjihpUhriISNoBi2hJBRUUmoj/BMTYcfz+F+ZM9hHWBYABFAE6hjP/TbCZC0GWwlpa3FzvHH9RzFeRusZ7A==}
-
'@types/google-protobuf@3.15.12':
resolution: {integrity: sha512-40um9QqwHjRS92qnOaDpL7RmDK15NuZYo9HihiJRbYkMQZlWnuH8AdvbMy8/o6lgLmKbDUKa+OALCltHdbOTpQ==}
- '@types/graceful-fs@4.1.9':
- resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==}
-
'@types/hast@3.0.4':
resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
@@ -7084,18 +6822,6 @@ packages:
'@types/http-errors@2.0.4':
resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==}
- '@types/istanbul-lib-coverage@2.0.6':
- resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==}
-
- '@types/istanbul-lib-report@3.0.3':
- resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==}
-
- '@types/istanbul-reports@3.0.4':
- resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==}
-
- '@types/jest@29.5.14':
- resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==}
-
'@types/js-cookie@3.0.6':
resolution: {integrity: sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==}
@@ -7129,18 +6855,12 @@ packages:
'@types/mdx@2.0.13':
resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==}
- '@types/methods@1.1.4':
- resolution: {integrity: sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==}
-
'@types/micromatch@4.0.9':
resolution: {integrity: sha512-7V+8ncr22h4UoYRLnLXSpTxjQrNUXtWHGeMPRJt1nULXI57G9bIcpyrHlmrQ7QK24EyyuXvYcSSWAM8GA9nqCg==}
'@types/mime@1.3.5':
resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==}
- '@types/morgan@1.9.9':
- resolution: {integrity: sha512-iRYSDKVaC6FkGSpEVVIvrRGw0DfJMiQzIn3qr2G5B3C//AWkulhXgaBd7tS9/J79GWSYMTHGs7PfI5b3Y8m+RQ==}
-
'@types/ms@2.1.0':
resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
@@ -7219,15 +6939,6 @@ packages:
'@types/shimmer@1.2.0':
resolution: {integrity: sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==}
- '@types/stack-utils@2.0.3':
- resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==}
-
- '@types/superagent@8.1.9':
- resolution: {integrity: sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==}
-
- '@types/supertest@6.0.3':
- resolution: {integrity: sha512-8WzXq62EXFhJ7QsH3Ocb/iKQ/Ty9ZVWnVzoTKc9tyyFRRF3a74Tk2+TLFgaFFw364Ere+npzHKEJ6ga2LzIL7w==}
-
'@types/tmp@0.2.6':
resolution: {integrity: sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==}
@@ -7249,12 +6960,6 @@ packages:
'@types/uuid@9.0.8':
resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==}
- '@types/yargs-parser@21.0.3':
- resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==}
-
- '@types/yargs@17.0.33':
- resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==}
-
'@types/yauzl@2.10.3':
resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
@@ -7773,10 +7478,6 @@ packages:
resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
engines: {node: '>=6'}
- ansi-escapes@4.3.2:
- resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==}
- engines: {node: '>=8'}
-
ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
@@ -7874,9 +7575,6 @@ packages:
resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==}
engines: {node: '>= 0.4'}
- array-flatten@1.1.1:
- resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==}
-
array-includes@3.1.8:
resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==}
engines: {node: '>= 0.4'}
@@ -7915,9 +7613,6 @@ packages:
as-table@1.0.55:
resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==}
- asap@2.0.6:
- resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==}
-
asn1js@3.0.6:
resolution: {integrity: sha512-UOCGPYbl0tv8+006qks/dTgV9ajs97X2p0FAbyS2iyCRrmLSRolDaHdp+v/CLgnzHc3fVB+CwYiUmei7ndFcgA==}
engines: {node: '>=12.0.0'}
@@ -7959,9 +7654,6 @@ packages:
async-sema@3.1.1:
resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==}
- async@0.2.10:
- resolution: {integrity: sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==}
-
async@3.2.6:
resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==}
@@ -8007,12 +7699,6 @@ packages:
babel-dead-code-elimination@1.0.10:
resolution: {integrity: sha512-DV5bdJZTzZ0zn0DC24v3jD7Mnidh6xhKa4GfKCbq3sfW8kaWhDdZjP3i81geA8T33tdYqWKw4D3fVv0CwEgKVA==}
- babel-jest@29.7.0:
- resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- peerDependencies:
- '@babel/core': ^7.8.0
-
babel-loader@10.0.0:
resolution: {integrity: sha512-z8jt+EdS61AMw22nSfoNJAZ0vrtmhPRVi6ghL3rCeRZI8cdNYFiV5xeV3HbE7rlZZNmGH8BVccwWt8/ED0QOHA==}
engines: {node: ^18.20.0 || ^20.10.0 || >=22.0.0}
@@ -8020,30 +7706,11 @@ packages:
'@babel/core': ^7.12.0
webpack: '>=5.61.0'
- babel-plugin-istanbul@6.1.1:
- resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==}
- engines: {node: '>=8'}
-
- babel-plugin-jest-hoist@29.6.3:
- resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
babel-plugin-jsx-dom-expressions@0.39.8:
resolution: {integrity: sha512-/MVOIIjonylDXnrWmG23ZX82m9mtKATsVHB7zYlPfDR9Vdd/NBE48if+wv27bSkBtyO7EPMUlcUc4J63QwuACQ==}
peerDependencies:
'@babel/core': ^7.20.12
- babel-preset-current-node-syntax@1.1.0:
- resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==}
- peerDependencies:
- '@babel/core': ^7.0.0
-
- babel-preset-jest@29.6.3:
- resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- peerDependencies:
- '@babel/core': ^7.0.0
-
babel-preset-solid@1.9.6:
resolution: {integrity: sha512-HXTK9f93QxoH8dYn1M2mJdOlWgMsR88Lg/ul6QCZGkNTktjTE5HAf93YxQumHoCudLEtZrU1cFCMFOVho6GqFg==}
peerDependencies:
@@ -8069,10 +7736,6 @@ packages:
resolution: {integrity: sha512-OMu3BGQ4E7P1ErFsIPpbJh0qvDudM/UuJeHgkAvfWe+0HFJCXh+t/l8L6fVLR55RI/UbKrVLnAXZSVwd9ysWYw==}
hasBin: true
- basic-auth@2.0.1:
- resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==}
- engines: {node: '>= 0.8'}
-
before-after-hook@2.2.3:
resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==}
@@ -8109,10 +7772,6 @@ packages:
blake3-wasm@2.1.5:
resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==}
- body-parser@1.20.3:
- resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==}
- engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
-
body-parser@2.2.0:
resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==}
engines: {node: '>=18'}
@@ -8150,13 +7809,6 @@ packages:
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
- bs-logger@0.2.6:
- resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==}
- engines: {node: '>= 6'}
-
- bser@2.1.1:
- resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==}
-
buffer-crc32@0.2.13:
resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
@@ -8240,14 +7892,6 @@ packages:
resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
engines: {node: '>= 6'}
- camelcase@5.3.1:
- resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
- engines: {node: '>=6'}
-
- camelcase@6.3.0:
- resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
- engines: {node: '>=10'}
-
camelcase@8.0.0:
resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==}
engines: {node: '>=16'}
@@ -8300,10 +7944,6 @@ packages:
resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==}
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
- char-regex@1.0.2:
- resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==}
- engines: {node: '>=10'}
-
character-entities-html4@2.1.0:
resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
@@ -8352,10 +7992,6 @@ packages:
resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==}
engines: {node: '>=6.0'}
- ci-info@3.9.0:
- resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==}
- engines: {node: '>=8'}
-
citty@0.1.6:
resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==}
@@ -8425,16 +8061,9 @@ packages:
react: ^18.0.0
react-dom: ^18.0.0
- co@4.6.0:
- resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==}
- engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'}
-
collapse-white-space@2.1.0:
resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==}
- collect-v8-coverage@1.0.2:
- resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==}
-
color-convert@1.9.3:
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
@@ -8503,9 +8132,6 @@ packages:
compatx@0.2.0:
resolution: {integrity: sha512-6gLRNt4ygsi5NyMVhceOCFv14CIdDFN7fQjX1U4+47qVE/+kjPoXMK65KWK+dWxmFzMTuKazoQ9sch6pM0p5oA==}
- component-emitter@1.3.1:
- resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==}
-
compress-commons@4.1.2:
resolution: {integrity: sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==}
engines: {node: '>= 10'}
@@ -8528,9 +8154,6 @@ packages:
confbox@0.2.2:
resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==}
- confusing-browser-globals@1.0.11:
- resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==}
-
consola@3.4.2:
resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==}
engines: {node: ^14.18.0 || >=16.10.0}
@@ -8538,10 +8161,6 @@ packages:
console-control-strings@1.1.0:
resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
- content-disposition@0.5.4:
- resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
- engines: {node: '>= 0.6'}
-
content-disposition@1.0.0:
resolution: {integrity: sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==}
engines: {node: '>= 0.6'}
@@ -8564,9 +8183,6 @@ packages:
cookie-es@2.0.0:
resolution: {integrity: sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg==}
- cookie-signature@1.0.6:
- resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==}
-
cookie-signature@1.2.2:
resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==}
engines: {node: '>=6.6.0'}
@@ -8575,10 +8191,6 @@ packages:
resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==}
engines: {node: '>= 0.6'}
- cookie@0.7.1:
- resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==}
- engines: {node: '>= 0.6'}
-
cookie@0.7.2:
resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
engines: {node: '>= 0.6'}
@@ -8587,9 +8199,6 @@ packages:
resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==}
engines: {node: '>=18'}
- cookiejar@2.1.4:
- resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==}
-
cookies-next@4.3.0:
resolution: {integrity: sha512-XxeCwLR30cWwRd94sa9X5lRCDLVujtx73tv+N0doQCFIDl83fuuYdxbu/WQUt9aSV7EJx7bkMvJldjvzuFqr4w==}
@@ -8620,11 +8229,6 @@ packages:
resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==}
engines: {node: '>= 14'}
- create-jest@29.7.0:
- resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- hasBin: true
-
create-require@1.1.1:
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
@@ -8888,10 +8492,6 @@ packages:
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
engines: {node: '>=8'}
- detect-newline@3.1.0:
- resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==}
- engines: {node: '>=8'}
-
detect-node-es@1.1.0:
resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
@@ -8934,16 +8534,9 @@ packages:
devlop@1.1.0:
resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
- dezalgo@1.0.4:
- resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==}
-
didyoumean@1.2.2:
resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
- diff-sequences@29.6.3:
- resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
diff@4.0.2:
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
engines: {node: '>=0.3.1'}
@@ -9148,21 +8741,12 @@ packages:
effect@3.18.4:
resolution: {integrity: sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==}
- ejs@3.1.10:
- resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==}
- engines: {node: '>=0.10.0'}
- hasBin: true
-
electron-to-chromium@1.5.150:
resolution: {integrity: sha512-rOOkP2ZUMx1yL4fCxXQKDHQ8ZXwisb2OycOQVKHgvB3ZI4CvehOd4y2tfnnLDieJ3Zs1RL1Dlp3cMkyIn7nnXA==}
electron-to-chromium@1.5.234:
resolution: {integrity: sha512-RXfEp2x+VRYn8jbKfQlRImzoJU01kyDvVPBmG39eU2iuRVhuS6vQNocB8J0/8GrIMLnPzgz4eW6WiRnJkTuNWg==}
- emittery@0.13.1:
- resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==}
- engines: {node: '>=12'}
-
emoji-regex-xs@1.0.0:
resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==}
@@ -9231,9 +8815,6 @@ packages:
err-code@2.0.3:
resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==}
- error-ex@1.3.2:
- resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
-
error-stack-parser-es@1.0.5:
resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==}
@@ -9330,10 +8911,6 @@ packages:
resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
engines: {node: '>=0.8.0'}
- escape-string-regexp@2.0.0:
- resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==}
- engines: {node: '>=8'}
-
escape-string-regexp@4.0.0:
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
engines: {node: '>=10'}
@@ -9347,20 +8924,6 @@ packages:
engines: {node: '>=6.0'}
hasBin: true
- eslint-config-airbnb-base@15.0.0:
- resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==}
- engines: {node: ^10.12.0 || >=12.0.0}
- peerDependencies:
- eslint: ^7.32.0 || ^8.2.0
- eslint-plugin-import: ^2.25.2
-
- eslint-config-airbnb-typescript@18.0.0:
- resolution: {integrity: sha512-oc+Lxzgzsu8FQyFVa4QFaVKiitTYiiW3frB9KYW5OWdPrqFc7FzxgB20hP4cHMlr+MBzGcLl3jnCOVOydL9mIg==}
- peerDependencies:
- '@typescript-eslint/eslint-plugin': ^7.0.0
- '@typescript-eslint/parser': ^7.0.0
- eslint: ^8.56.0
-
eslint-config-next@13.3.0:
resolution: {integrity: sha512-6YEwmFBX0VjBd3ODGW9df0Is0FLaRFdMN8eAahQG9CN6LjQ28J8AFr19ngxqMSg7Qv6Uca/3VeeBosJh1bzu0w==}
peerDependencies:
@@ -9656,18 +9219,10 @@ packages:
resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==}
engines: {node: '>=6'}
- exit@0.1.2:
- resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==}
- engines: {node: '>= 0.8.0'}
-
expect-type@1.2.1:
resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==}
engines: {node: '>=12.0.0'}
- expect@29.7.0:
- resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
exponential-backoff@3.1.2:
resolution: {integrity: sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==}
@@ -9677,10 +9232,6 @@ packages:
peerDependencies:
express: '>= 4.11'
- express@4.21.2:
- resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==}
- engines: {node: '>= 0.10.0'}
-
express@5.1.0:
resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==}
engines: {node: '>= 18'}
@@ -9733,9 +9284,6 @@ packages:
fast-levenshtein@2.0.6:
resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
- fast-safe-stringify@2.1.1:
- resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==}
-
fast-uri@3.0.6:
resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==}
@@ -9753,9 +9301,6 @@ packages:
fault@2.0.1:
resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==}
- fb-watchman@2.0.2:
- resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==}
-
fd-slicer@1.1.0:
resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==}
@@ -9800,9 +9345,6 @@ packages:
file-uri-to-path@1.0.0:
resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
- filelist@1.0.4:
- resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==}
-
filesize@10.1.6:
resolution: {integrity: sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w==}
engines: {node: '>= 10.4.0'}
@@ -9815,10 +9357,6 @@ packages:
resolution: {integrity: sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng==}
engines: {node: '>=14.16'}
- finalhandler@1.3.1:
- resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==}
- engines: {node: '>= 0.8'}
-
finalhandler@2.1.0:
resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==}
engines: {node: '>= 0.8'}
@@ -9830,10 +9368,6 @@ packages:
resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==}
engines: {node: '>=18'}
- find-up@4.1.0:
- resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
- engines: {node: '>=8'}
-
find-up@5.0.0:
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
engines: {node: '>=10'}
@@ -9860,11 +9394,6 @@ packages:
flatted@3.3.3:
resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==}
- fluent-ffmpeg@2.1.3:
- resolution: {integrity: sha512-Be3narBNt2s6bsaqP6Jzq91heDgOEaDCJAXcE3qcma/EJBSy5FB4cvO31XBInuAuKBx8Kptf8dkhjK0IOru39Q==}
- engines: {node: '>=18'}
- deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
-
fn.name@1.1.0:
resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==}
@@ -9904,9 +9433,6 @@ packages:
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
engines: {node: '>=12.20.0'}
- formidable@2.1.5:
- resolution: {integrity: sha512-Oz5Hwvwak/DCaXVVUtPn4oLMLLy1CdclLKO1LFgU7XzDpVMUU5UjlSLpGMocyQNNk8F6IJW9M/YdooSn2MRI+Q==}
-
forwarded@0.2.0:
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
engines: {node: '>= 0.6'}
@@ -10019,10 +9545,6 @@ packages:
resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==}
engines: {node: '>=6'}
- get-package-type@0.1.0:
- resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==}
- engines: {node: '>=8.0.0'}
-
get-port-please@3.1.2:
resolution: {integrity: sha512-Gxc29eLs1fbn6LQ4jSU4vXjlwyZhF5HsGuMAa7gqBP4Rw4yxxltyDUuF5MBclFzDTXO+ACchGQoeela4DSfzdQ==}
@@ -10223,10 +9745,6 @@ packages:
hast-util-whitespace@3.0.0:
resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
- helmet@7.2.0:
- resolution: {integrity: sha512-ZRiwvN089JfMXokizgqEPXsl2Guk094yExfoDXR0cBYWxtBbaSww/w+vT4WEJsBW2iTUi1GgZ6swmoug3Oy4Xw==}
- engines: {node: '>=16.0.0'}
-
hls.js@0.14.17:
resolution: {integrity: sha512-25A7+m6qqp6UVkuzUQ//VVh2EEOPYlOBg32ypr34bcPO7liBMOkKFvbjbCBfiPAOTA/7BSx1Dujft3Th57WyFg==}
@@ -10258,9 +9776,6 @@ packages:
html-entities@2.3.3:
resolution: {integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==}
- html-escaper@2.0.2:
- resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
-
html-to-image@1.11.13:
resolution: {integrity: sha512-cuOPoI7WApyhBElTTb9oqsawRvZ0rHhaHwghRLlTuffoD1B2aDemlCruLeZrUIIdvG7gs9xeELEPm6PhuASqrg==}
@@ -10327,10 +9842,6 @@ packages:
resolution: {integrity: sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==}
engines: {node: '>=10.18'}
- iconv-lite@0.4.24:
- resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
- engines: {node: '>=0.10.0'}
-
iconv-lite@0.6.3:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
engines: {node: '>=0.10.0'}
@@ -10345,9 +9856,6 @@ packages:
ieee754@1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
- ignore-by-default@1.0.1:
- resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==}
-
ignore-walk@6.0.5:
resolution: {integrity: sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
@@ -10378,11 +9886,6 @@ packages:
import-in-the-middle@1.13.1:
resolution: {integrity: sha512-k2V9wNm9B+ysuelDTHjI9d5KPc4l8zAZTGqj+pcynvWkypZd857ryzN8jNC7Pg2YZXNMJcHRPpaDyCBbNyVRpA==}
- import-local@3.2.0:
- resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==}
- engines: {node: '>=8'}
- hasBin: true
-
imurmurhash@0.1.4:
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
engines: {node: '>=0.8.19'}
@@ -10471,9 +9974,6 @@ packages:
resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==}
engines: {node: '>= 0.4'}
- is-arrayish@0.2.1:
- resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
-
is-arrayish@0.3.2:
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
@@ -10545,10 +10045,6 @@ packages:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
- is-generator-fn@2.1.0:
- resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==}
- engines: {node: '>=6'}
-
is-generator-function@1.1.0:
resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==}
engines: {node: '>= 0.4'}
@@ -10707,30 +10203,6 @@ packages:
resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==}
engines: {node: '>=16'}
- istanbul-lib-coverage@3.2.2:
- resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==}
- engines: {node: '>=8'}
-
- istanbul-lib-instrument@5.2.1:
- resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==}
- engines: {node: '>=8'}
-
- istanbul-lib-instrument@6.0.3:
- resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==}
- engines: {node: '>=10'}
-
- istanbul-lib-report@3.0.1:
- resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==}
- engines: {node: '>=10'}
-
- istanbul-lib-source-maps@4.0.1:
- resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==}
- engines: {node: '>=10'}
-
- istanbul-reports@3.1.7:
- resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==}
- engines: {node: '>=8'}
-
iterator.prototype@1.1.5:
resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==}
engines: {node: '>= 0.4'}
@@ -10742,168 +10214,34 @@ packages:
resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==}
engines: {node: 20 || >=22}
- jake@10.9.2:
- resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==}
- engines: {node: '>=10'}
- hasBin: true
+ jest-worker@27.5.1:
+ resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==}
+ engines: {node: '>= 10.13.0'}
- jest-changed-files@29.7.0:
- resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ jiti@1.21.7:
+ resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==}
+ hasBin: true
- jest-circus@29.7.0:
- resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ jiti@2.4.2:
+ resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
+ hasBin: true
- jest-cli@29.7.0:
- resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ jiti@2.6.1:
+ resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
hasBin: true
- peerDependencies:
- node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
- peerDependenciesMeta:
- node-notifier:
- optional: true
- jest-config@29.7.0:
- resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- peerDependencies:
- '@types/node': '*'
- ts-node: '>=9.0.0'
- peerDependenciesMeta:
- '@types/node':
- optional: true
- ts-node:
- optional: true
+ jmespath@0.16.0:
+ resolution: {integrity: sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==}
+ engines: {node: '>= 0.6.0'}
- jest-diff@29.7.0:
- resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ jose@4.15.9:
+ resolution: {integrity: sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==}
- jest-docblock@29.7.0:
- resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ jose@5.10.0:
+ resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==}
- jest-each@29.7.0:
- resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- jest-environment-node@29.7.0:
- resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- jest-get-type@29.6.3:
- resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- jest-haste-map@29.7.0:
- resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- jest-leak-detector@29.7.0:
- resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- jest-matcher-utils@29.7.0:
- resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- jest-message-util@29.7.0:
- resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- jest-mock@29.7.0:
- resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- jest-pnp-resolver@1.2.3:
- resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==}
- engines: {node: '>=6'}
- peerDependencies:
- jest-resolve: '*'
- peerDependenciesMeta:
- jest-resolve:
- optional: true
-
- jest-regex-util@29.6.3:
- resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- jest-resolve-dependencies@29.7.0:
- resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- jest-resolve@29.7.0:
- resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- jest-runner@29.7.0:
- resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- jest-runtime@29.7.0:
- resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- jest-snapshot@29.7.0:
- resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- jest-util@29.7.0:
- resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- jest-validate@29.7.0:
- resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- jest-watcher@29.7.0:
- resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- jest-worker@27.5.1:
- resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==}
- engines: {node: '>= 10.13.0'}
-
- jest-worker@29.7.0:
- resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- jest@29.7.0:
- resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- hasBin: true
- peerDependencies:
- node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
- peerDependenciesMeta:
- node-notifier:
- optional: true
-
- jiti@1.21.7:
- resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==}
- hasBin: true
-
- jiti@2.4.2:
- resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
- hasBin: true
-
- jiti@2.6.1:
- resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
- hasBin: true
-
- jmespath@0.16.0:
- resolution: {integrity: sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==}
- engines: {node: '>= 0.6.0'}
-
- jose@4.15.9:
- resolution: {integrity: sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==}
-
- jose@5.10.0:
- resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==}
-
- jose@5.2.3:
- resolution: {integrity: sha512-KUXdbctm1uHVL8BYhnyHkgp3zDX5KW8ZhAKVFEfUbU2P8Alpzjb+48hHvjOdQIyPshoblhzsuqOwEEAbtHVirA==}
+ jose@5.2.3:
+ resolution: {integrity: sha512-KUXdbctm1uHVL8BYhnyHkgp3zDX5KW8ZhAKVFEfUbU2P8Alpzjb+48hHvjOdQIyPshoblhzsuqOwEEAbtHVirA==}
jose@5.6.3:
resolution: {integrity: sha512-1Jh//hEEwMhNYPDDLwXHa2ePWgWiFNNUadVmguAAw2IJ6sj9mNxV5tGXJNqlMkJAybF6Lgw1mISDxTePP/187g==}
@@ -11063,10 +10401,6 @@ packages:
leb@1.0.0:
resolution: {integrity: sha512-Y3c3QZfvKWHX60BVOQPhLCvVGmDYWyJEiINE3drOog6KCyN2AOwvuQQzlS3uJg1J85kzpILXIUwRXULWavir+w==}
- leven@3.1.0:
- resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
- engines: {node: '>=6'}
-
levn@0.4.1:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
@@ -11101,10 +10435,6 @@ packages:
resolution: {integrity: sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==}
engines: {node: '>=14'}
- locate-path@5.0.0:
- resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
- engines: {node: '>=8'}
-
locate-path@6.0.0:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'}
@@ -11140,9 +10470,6 @@ packages:
lodash.isplainobject@4.0.6:
resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
- lodash.memoize@4.1.2:
- resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==}
-
lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
@@ -11249,10 +10576,6 @@ packages:
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
engines: {node: '>=8'}
- make-dir@4.0.0:
- resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
- engines: {node: '>=10'}
-
make-error@1.3.6:
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
@@ -11260,9 +10583,6 @@ packages:
resolution: {integrity: sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==}
engines: {node: ^16.14.0 || >=18.0.0}
- makeerror@1.0.12:
- resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==}
-
map-or-similar@1.5.0:
resolution: {integrity: sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==}
@@ -11329,10 +10649,6 @@ packages:
media-tracks@0.3.3:
resolution: {integrity: sha512-9P2FuUHnZZ3iji+2RQk7Zkh5AmZTnOG5fODACnjhCVveX1McY3jmCRHofIEI+yTBqplz7LXy48c7fQ3Uigp88w==}
- media-typer@0.3.0:
- resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
- engines: {node: '>= 0.6'}
-
media-typer@1.1.0:
resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==}
engines: {node: '>= 0.8'}
@@ -11348,9 +10664,6 @@ packages:
resolution: {integrity: sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==}
engines: {node: '>=12.13'}
- merge-descriptors@1.0.3:
- resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==}
-
merge-descriptors@2.0.0:
resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==}
engines: {node: '>=18'}
@@ -11366,10 +10679,6 @@ packages:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
- methods@1.1.2:
- resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==}
- engines: {node: '>= 0.6'}
-
micro-api-client@3.3.0:
resolution: {integrity: sha512-y0y6CUB9RLVsy3kfgayU28746QrNMpSm9O/AYGNsBgOkJr/X/Jk0VLGoO8Ude7Bpa8adywzF+MzXNZRFRsNPhg==}
@@ -11485,11 +10794,6 @@ packages:
engines: {node: '>=4'}
hasBin: true
- mime@2.6.0:
- resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==}
- engines: {node: '>=4.0.0'}
- hasBin: true
-
mime@3.0.0:
resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==}
engines: {node: '>=10.0.0'}
@@ -11616,10 +10920,6 @@ packages:
moment@2.30.1:
resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==}
- morgan@1.10.0:
- resolution: {integrity: sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==}
- engines: {node: '>= 0.8.0'}
-
motion-dom@11.18.1:
resolution: {integrity: sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw==}
@@ -11834,9 +11134,6 @@ packages:
engines: {node: ^16.14.0 || >=18.0.0}
hasBin: true
- node-int64@0.4.0:
- resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==}
-
node-mock-http@1.0.0:
resolution: {integrity: sha512-0uGYQ1WQL1M5kKvGRXWQ3uZCHtLTO8hln3oBjIusM75WoesZ909uQJs/Hb946i2SS+Gsrhkaa6iAO17jRIv6DQ==}
@@ -11854,11 +11151,6 @@ packages:
resolution: {integrity: sha512-Z+iLaBGVaSjbIzQ4pX6XV41HrooLsQ10ZWPUehGmuantvzWoDVBnmsdUcOIDM1t+yPor5pDhVlDESgOMEGxhHA==}
engines: {node: '>=6.0.0'}
- nodemon@3.1.10:
- resolution: {integrity: sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==}
- engines: {node: '>=10'}
- hasBin: true
-
nopt@5.0.0:
resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==}
engines: {node: '>=6'}
@@ -12013,18 +11305,10 @@ packages:
resolution: {integrity: sha512-D7EmwxJV6DsEB6vOFLrBM2OzsVgQzgPWyHlV2OOAVj772n+WTXpudC9e9u5BVKQnYwaD30Ivhi9b+4UeBcGu9g==}
engines: {node: ^10.13.0 || >=12.0.0}
- on-finished@2.3.0:
- resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==}
- engines: {node: '>= 0.8'}
-
on-finished@2.4.1:
resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
engines: {node: '>= 0.8'}
- on-headers@1.0.2:
- resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==}
- engines: {node: '>= 0.8'}
-
once@1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
@@ -12084,10 +11368,6 @@ packages:
resolution: {integrity: sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
- p-limit@2.3.0:
- resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
- engines: {node: '>=6'}
-
p-limit@3.1.0:
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
engines: {node: '>=10'}
@@ -12096,10 +11376,6 @@ packages:
resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
- p-locate@4.1.0:
- resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
- engines: {node: '>=8'}
-
p-locate@5.0.0:
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
engines: {node: '>=10'}
@@ -12124,10 +11400,6 @@ packages:
resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==}
engines: {node: '>=14.16'}
- p-try@2.2.0:
- resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
- engines: {node: '>=6'}
-
p-wait-for@5.0.2:
resolution: {integrity: sha512-lwx6u1CotQYPVju77R+D0vFomni/AqRfqLmqQ8hekklqZ6gAY9rONh7lBQ0uxWMkC2AuX9b2DVAl8To0NyP1JA==}
engines: {node: '>=12'}
@@ -12168,10 +11440,6 @@ packages:
resolution: {integrity: sha512-RmVuCHWsfu0QPNW+mraxh/xjQVw/lhUCUru8Zni3Ctq3AoMhpDTq0OVdKS6iesd6Kqb7viCV3isAL43dciOSog==}
engines: {node: '>=14'}
- parse-json@5.2.0:
- resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
- engines: {node: '>=8'}
-
parse-json@8.3.0:
resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==}
engines: {node: '>=18'}
@@ -12220,9 +11488,6 @@ packages:
resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==}
engines: {node: 20 || >=22}
- path-to-regexp@0.1.12:
- resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==}
-
path-to-regexp@6.3.0:
resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==}
@@ -12287,10 +11552,6 @@ packages:
resolution: {integrity: sha512-ZBmhE1C9LcPoH9XZSdwiPtbPHZROwAnMy+kIFQVrnMCxY4Cudlz3gBOpzilgc0jOgRaiT3sIWfpMomW2ar2orQ==}
engines: {node: '>=16.20.0'}
- pkg-dir@4.2.0:
- resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==}
- engines: {node: '>=8'}
-
pkg-dir@7.0.0:
resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==}
engines: {node: '>=14.16'}
@@ -12444,10 +11705,6 @@ packages:
resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
- pretty-format@29.7.0:
- resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
pretty-format@3.8.0:
resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==}
@@ -12519,9 +11776,6 @@ packages:
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
- pstree.remy@1.1.8:
- resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==}
-
pump@3.0.2:
resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==}
@@ -12542,10 +11796,6 @@ packages:
resolution: {integrity: sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==}
engines: {node: '>=6.0.0'}
- qs@6.13.0:
- resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==}
- engines: {node: '>=0.6'}
-
qs@6.14.0:
resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==}
engines: {node: '>=0.6'}
@@ -12581,10 +11831,6 @@ packages:
resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
engines: {node: '>= 0.6'}
- raw-body@2.5.2:
- resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==}
- engines: {node: '>= 0.8'}
-
raw-body@3.0.1:
resolution: {integrity: sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==}
engines: {node: '>= 0.10'}
@@ -12659,9 +11905,6 @@ packages:
react-is@17.0.2:
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
- react-is@18.3.1:
- resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
-
react-loading-skeleton@3.5.0:
resolution: {integrity: sha512-gxxSyLbrEAdXTKgfbpBEFZCO/P153DnqSCQau2+o6lNy1jgMRr2MmRmOzMmyrwSaSYLRB8g7b0waYPmUjz7IhQ==}
peerDependencies:
@@ -12893,10 +12136,6 @@ packages:
resolve-alpn@1.2.1:
resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==}
- resolve-cwd@3.0.0:
- resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==}
- engines: {node: '>=8'}
-
resolve-from@4.0.0:
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
engines: {node: '>=4'}
@@ -12908,10 +12147,6 @@ packages:
resolve-pkg-maps@1.0.0:
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
- resolve.exports@2.0.3:
- resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==}
- engines: {node: '>=10'}
-
resolve@1.22.10:
resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==}
engines: {node: '>= 0.4'}
@@ -12965,8 +12200,8 @@ packages:
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
- rolldown@1.0.0-beta.43:
- resolution: {integrity: sha512-6RcqyRx0tY1MlRLnjXPp/849Rl/CPFhzpGGwNPEPjKwqBMqPq/Rbbkxasa8s0x+IkUk46ty4jazb5skZ/Vgdhw==}
+ rolldown@1.0.0-beta.45:
+ resolution: {integrity: sha512-iMmuD72XXLf26Tqrv1cryNYLX6NNPLhZ3AmNkSf8+xda0H+yijjGJ+wVT9UdBUHOpKzq9RjKtQKRCWoEKQQBZQ==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
@@ -13192,10 +12427,6 @@ packages:
simple-swizzle@0.2.2:
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
- simple-update-notifier@2.0.0:
- resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==}
- engines: {node: '>=10'}
-
sisteransi@1.0.5:
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
@@ -13298,9 +12529,6 @@ packages:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
- source-map-support@0.5.13:
- resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==}
-
source-map-support@0.5.21:
resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
@@ -13400,10 +12628,6 @@ packages:
stack-trace@0.0.10:
resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==}
- stack-utils@2.0.6:
- resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==}
- engines: {node: '>=10'}
-
stackback@0.0.2:
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
@@ -13472,10 +12696,6 @@ packages:
streamx@2.22.0:
resolution: {integrity: sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==}
- string-length@4.0.2:
- resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==}
- engines: {node: '>=10'}
-
string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
@@ -13536,10 +12756,6 @@ packages:
resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
engines: {node: '>=4'}
- strip-bom@4.0.0:
- resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==}
- engines: {node: '>=8'}
-
strip-final-newline@2.0.0:
resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
engines: {node: '>=6'}
@@ -13602,16 +12818,6 @@ packages:
engines: {node: '>=16 || 14 >=14.17'}
hasBin: true
- superagent@8.1.2:
- resolution: {integrity: sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==}
- engines: {node: '>=6.4.0 <13 || >=14'}
- deprecated: Please upgrade to superagent v10.2.2+, see release notes at https://github.com/forwardemail/superagent/releases/tag/v10.2.2 - maintenance is supported by Forward Email @ https://forwardemail.net
-
- supertest@6.3.4:
- resolution: {integrity: sha512-erY3HFDG0dPnhw4U+udPfrzXa4xhSG+n4rxfRuZWCUvjFWwKl+OxWf/7zk50s84/fAAs7vf5QAb9uRa0cCykxw==}
- engines: {node: '>=6.4.0'}
- deprecated: Please upgrade to supertest v7.1.3+, see release notes at https://github.com/forwardemail/supertest/releases/tag/v7.1.3 - maintenance is supported by Forward Email @ https://forwardemail.net
-
supports-color@10.0.0:
resolution: {integrity: sha512-HRVVSbCCMbj7/kdWF9Q+bbckjBHLtHMEoJWlkmYzzdwhYMkjkOwubLM6t7NbWKjgKamGDrWL1++KrjUO1t9oAQ==}
engines: {node: '>=18'}
@@ -13719,10 +12925,6 @@ packages:
engines: {node: '>=10'}
hasBin: true
- test-exclude@6.0.0:
- resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==}
- engines: {node: '>=8'}
-
text-decoder@1.2.3:
resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==}
@@ -13802,9 +13004,6 @@ packages:
resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==}
engines: {node: '>=14.14'}
- tmpl@1.0.5:
- resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==}
-
to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
@@ -13820,10 +13019,6 @@ packages:
toml@3.0.0:
resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==}
- touch@3.1.1:
- resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==}
- hasBin: true
-
tough-cookie@5.1.2:
resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==}
engines: {node: '>=16'}
@@ -13875,30 +13070,6 @@ packages:
ts-interface-checker@0.1.13:
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
- ts-jest@29.3.2:
- resolution: {integrity: sha512-bJJkrWc6PjFVz5g2DGCNUo8z7oFEYaz1xP1NpeDU7KNLMWPpEyV8Chbpkn8xjzgRDpQhnGMyvyldoL7h8JXyug==}
- engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0}
- hasBin: true
- peerDependencies:
- '@babel/core': '>=7.0.0-beta.0 <8'
- '@jest/transform': ^29.0.0
- '@jest/types': ^29.0.0
- babel-jest: ^29.0.0
- esbuild: '*'
- jest: ^29.0.0
- typescript: '>=4.3 <6'
- peerDependenciesMeta:
- '@babel/core':
- optional: true
- '@jest/transform':
- optional: true
- '@jest/types':
- optional: true
- babel-jest:
- optional: true
- esbuild:
- optional: true
-
ts-node@10.9.2:
resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==}
hasBin: true
@@ -14043,26 +13214,14 @@ packages:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'}
- type-detect@4.0.8:
- resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==}
- engines: {node: '>=4'}
-
type-fest@0.20.2:
resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
engines: {node: '>=10'}
- type-fest@0.21.3:
- resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
- engines: {node: '>=10'}
-
type-fest@4.41.0:
resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==}
engines: {node: '>=16'}
- type-is@1.6.18:
- resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==}
- engines: {node: '>= 0.6'}
-
type-is@2.0.1:
resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==}
engines: {node: '>= 0.6'}
@@ -14107,9 +13266,6 @@ packages:
unctx@2.4.1:
resolution: {integrity: sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg==}
- undefsafe@2.0.5:
- resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==}
-
undici-types@5.26.5:
resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
@@ -14427,10 +13583,6 @@ packages:
util@0.12.5:
resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==}
- utils-merge@1.0.1:
- resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
- engines: {node: '>= 0.4.0'}
-
uuid@11.1.0:
resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==}
hasBin: true
@@ -14453,10 +13605,6 @@ packages:
v8-compile-cache@2.4.0:
resolution: {integrity: sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==}
- v8-to-istanbul@9.3.0:
- resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==}
- engines: {node: '>=10.12.0'}
-
valibot@1.0.0-rc.1:
resolution: {integrity: sha512-bTHNpeeQ403xS7qGHF/tw3EC/zkZOU5VdkfIsmRDu1Sp+BJNTNCm6m5HlwOgyW/03lofP+uQiq3R+Poo9wiCEg==}
peerDependencies:
@@ -14674,9 +13822,6 @@ packages:
walk-up-path@3.0.1:
resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==}
- walker@1.0.8:
- resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==}
-
watchpack@2.4.4:
resolution: {integrity: sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==}
engines: {node: '>=10.13.0'}
@@ -14759,10 +13904,6 @@ packages:
resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==}
engines: {node: '>= 0.4'}
- which@1.3.1:
- resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==}
- hasBin: true
-
which@2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'}
@@ -14842,10 +13983,6 @@ packages:
wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
- write-file-atomic@4.0.2:
- resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==}
- engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
-
write-file-atomic@5.0.1:
resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
@@ -16164,86 +15301,11 @@ snapshots:
dependencies:
'@babel/types': 7.28.4
- '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.27.1)':
- dependencies:
- '@babel/core': 7.27.1
- '@babel/helper-plugin-utils': 7.27.1
-
- '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.27.1)':
- dependencies:
- '@babel/core': 7.27.1
- '@babel/helper-plugin-utils': 7.27.1
-
- '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.27.1)':
- dependencies:
- '@babel/core': 7.27.1
- '@babel/helper-plugin-utils': 7.27.1
-
- '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.27.1)':
- dependencies:
- '@babel/core': 7.27.1
- '@babel/helper-plugin-utils': 7.27.1
-
- '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.27.1)':
- dependencies:
- '@babel/core': 7.27.1
- '@babel/helper-plugin-utils': 7.27.1
-
- '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.27.1)':
- dependencies:
- '@babel/core': 7.27.1
- '@babel/helper-plugin-utils': 7.27.1
-
- '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.27.1)':
- dependencies:
- '@babel/core': 7.27.1
- '@babel/helper-plugin-utils': 7.27.1
-
'@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.27.1)':
dependencies:
'@babel/core': 7.27.1
'@babel/helper-plugin-utils': 7.27.1
- '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.27.1)':
- dependencies:
- '@babel/core': 7.27.1
- '@babel/helper-plugin-utils': 7.27.1
-
- '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.27.1)':
- dependencies:
- '@babel/core': 7.27.1
- '@babel/helper-plugin-utils': 7.27.1
-
- '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.27.1)':
- dependencies:
- '@babel/core': 7.27.1
- '@babel/helper-plugin-utils': 7.27.1
-
- '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.27.1)':
- dependencies:
- '@babel/core': 7.27.1
- '@babel/helper-plugin-utils': 7.27.1
-
- '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.27.1)':
- dependencies:
- '@babel/core': 7.27.1
- '@babel/helper-plugin-utils': 7.27.1
-
- '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.27.1)':
- dependencies:
- '@babel/core': 7.27.1
- '@babel/helper-plugin-utils': 7.27.1
-
- '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.27.1)':
- dependencies:
- '@babel/core': 7.27.1
- '@babel/helper-plugin-utils': 7.27.1
-
- '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.27.1)':
- dependencies:
- '@babel/core': 7.27.1
- '@babel/helper-plugin-utils': 7.27.1
-
'@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.27.1)':
dependencies:
'@babel/core': 7.27.1
@@ -16337,8 +15399,6 @@ snapshots:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.27.1
- '@bcoe/v8-coverage@0.2.3': {}
-
'@biomejs/biome@2.2.0':
optionalDependencies:
'@biomejs/cli-darwin-arm64': 2.2.0
@@ -16769,12 +15829,6 @@ snapshots:
'@effect/rpc': 0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4)
effect: 3.18.4
- '@emnapi/core@1.4.3':
- dependencies:
- '@emnapi/wasi-threads': 1.0.2
- tslib: 2.8.1
- optional: true
-
'@emnapi/core@1.5.0':
dependencies:
'@emnapi/wasi-threads': 1.1.0
@@ -16791,11 +15845,6 @@ snapshots:
tslib: 2.8.1
optional: true
- '@emnapi/wasi-threads@1.0.2':
- dependencies:
- tslib: 2.8.1
- optional: true
-
'@emnapi/wasi-threads@1.1.0':
dependencies:
tslib: 2.8.1
@@ -17668,207 +16717,35 @@ snapshots:
'@isaacs/string-locale-compare@1.1.0': {}
- '@istanbuljs/load-nyc-config@1.1.0':
+ '@jridgewell/gen-mapping@0.3.13':
dependencies:
- camelcase: 5.3.1
- find-up: 4.1.0
- get-package-type: 0.1.0
- js-yaml: 3.14.1
- resolve-from: 5.0.0
-
- '@istanbuljs/schema@0.1.3': {}
+ '@jridgewell/sourcemap-codec': 1.5.5
+ '@jridgewell/trace-mapping': 0.3.31
- '@jest/console@29.7.0':
+ '@jridgewell/gen-mapping@0.3.8':
dependencies:
- '@jest/types': 29.6.3
- '@types/node': 20.17.43
- chalk: 4.1.2
- jest-message-util: 29.7.0
- jest-util: 29.7.0
- slash: 3.0.0
+ '@jridgewell/set-array': 1.2.1
+ '@jridgewell/sourcemap-codec': 1.5.0
+ '@jridgewell/trace-mapping': 0.3.31
- '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.17.43)(typescript@5.8.3))':
+ '@jridgewell/remapping@2.3.5':
dependencies:
- '@jest/console': 29.7.0
- '@jest/reporters': 29.7.0
- '@jest/test-result': 29.7.0
- '@jest/transform': 29.7.0
- '@jest/types': 29.6.3
- '@types/node': 20.17.43
- ansi-escapes: 4.3.2
- chalk: 4.1.2
- ci-info: 3.9.0
- exit: 0.1.2
- graceful-fs: 4.2.11
- jest-changed-files: 29.7.0
- jest-config: 29.7.0(@types/node@20.17.43)(ts-node@10.9.2(@types/node@20.17.43)(typescript@5.8.3))
- jest-haste-map: 29.7.0
- jest-message-util: 29.7.0
- jest-regex-util: 29.6.3
- jest-resolve: 29.7.0
- jest-resolve-dependencies: 29.7.0
- jest-runner: 29.7.0
- jest-runtime: 29.7.0
- jest-snapshot: 29.7.0
- jest-util: 29.7.0
- jest-validate: 29.7.0
- jest-watcher: 29.7.0
- micromatch: 4.0.8
- pretty-format: 29.7.0
- slash: 3.0.0
- strip-ansi: 6.0.1
- transitivePeerDependencies:
- - babel-plugin-macros
- - supports-color
- - ts-node
+ '@jridgewell/gen-mapping': 0.3.13
+ '@jridgewell/trace-mapping': 0.3.31
- '@jest/environment@29.7.0':
- dependencies:
- '@jest/fake-timers': 29.7.0
- '@jest/types': 29.6.3
- '@types/node': 20.17.43
- jest-mock: 29.7.0
+ '@jridgewell/resolve-uri@3.1.2': {}
- '@jest/expect-utils@29.7.0':
- dependencies:
- jest-get-type: 29.6.3
+ '@jridgewell/set-array@1.2.1': {}
- '@jest/expect@29.7.0':
+ '@jridgewell/source-map@0.3.11':
dependencies:
- expect: 29.7.0
- jest-snapshot: 29.7.0
- transitivePeerDependencies:
- - supports-color
+ '@jridgewell/gen-mapping': 0.3.13
+ '@jridgewell/trace-mapping': 0.3.31
- '@jest/fake-timers@29.7.0':
+ '@jridgewell/source-map@0.3.6':
dependencies:
- '@jest/types': 29.6.3
- '@sinonjs/fake-timers': 10.3.0
- '@types/node': 20.17.43
- jest-message-util: 29.7.0
- jest-mock: 29.7.0
- jest-util: 29.7.0
-
- '@jest/globals@29.7.0':
- dependencies:
- '@jest/environment': 29.7.0
- '@jest/expect': 29.7.0
- '@jest/types': 29.6.3
- jest-mock: 29.7.0
- transitivePeerDependencies:
- - supports-color
-
- '@jest/reporters@29.7.0':
- dependencies:
- '@bcoe/v8-coverage': 0.2.3
- '@jest/console': 29.7.0
- '@jest/test-result': 29.7.0
- '@jest/transform': 29.7.0
- '@jest/types': 29.6.3
- '@jridgewell/trace-mapping': 0.3.25
- '@types/node': 20.17.43
- chalk: 4.1.2
- collect-v8-coverage: 1.0.2
- exit: 0.1.2
- glob: 7.2.3
- graceful-fs: 4.2.11
- istanbul-lib-coverage: 3.2.2
- istanbul-lib-instrument: 6.0.3
- istanbul-lib-report: 3.0.1
- istanbul-lib-source-maps: 4.0.1
- istanbul-reports: 3.1.7
- jest-message-util: 29.7.0
- jest-util: 29.7.0
- jest-worker: 29.7.0
- slash: 3.0.0
- string-length: 4.0.2
- strip-ansi: 6.0.1
- v8-to-istanbul: 9.3.0
- transitivePeerDependencies:
- - supports-color
-
- '@jest/schemas@29.6.3':
- dependencies:
- '@sinclair/typebox': 0.27.8
-
- '@jest/source-map@29.6.3':
- dependencies:
- '@jridgewell/trace-mapping': 0.3.30
- callsites: 3.1.0
- graceful-fs: 4.2.11
-
- '@jest/test-result@29.7.0':
- dependencies:
- '@jest/console': 29.7.0
- '@jest/types': 29.6.3
- '@types/istanbul-lib-coverage': 2.0.6
- collect-v8-coverage: 1.0.2
-
- '@jest/test-sequencer@29.7.0':
- dependencies:
- '@jest/test-result': 29.7.0
- graceful-fs: 4.2.11
- jest-haste-map: 29.7.0
- slash: 3.0.0
-
- '@jest/transform@29.7.0':
- dependencies:
- '@babel/core': 7.27.1
- '@jest/types': 29.6.3
- '@jridgewell/trace-mapping': 0.3.25
- babel-plugin-istanbul: 6.1.1
- chalk: 4.1.2
- convert-source-map: 2.0.0
- fast-json-stable-stringify: 2.1.0
- graceful-fs: 4.2.11
- jest-haste-map: 29.7.0
- jest-regex-util: 29.6.3
- jest-util: 29.7.0
- micromatch: 4.0.8
- pirates: 4.0.7
- slash: 3.0.0
- write-file-atomic: 4.0.2
- transitivePeerDependencies:
- - supports-color
-
- '@jest/types@29.6.3':
- dependencies:
- '@jest/schemas': 29.6.3
- '@types/istanbul-lib-coverage': 2.0.6
- '@types/istanbul-reports': 3.0.4
- '@types/node': 20.17.43
- '@types/yargs': 17.0.33
- chalk: 4.1.2
-
- '@jridgewell/gen-mapping@0.3.13':
- dependencies:
- '@jridgewell/sourcemap-codec': 1.5.5
- '@jridgewell/trace-mapping': 0.3.31
-
- '@jridgewell/gen-mapping@0.3.8':
- dependencies:
- '@jridgewell/set-array': 1.2.1
- '@jridgewell/sourcemap-codec': 1.5.0
- '@jridgewell/trace-mapping': 0.3.25
-
- '@jridgewell/remapping@2.3.5':
- dependencies:
- '@jridgewell/gen-mapping': 0.3.13
- '@jridgewell/trace-mapping': 0.3.31
-
- '@jridgewell/resolve-uri@3.1.2': {}
-
- '@jridgewell/set-array@1.2.1': {}
-
- '@jridgewell/source-map@0.3.11':
- dependencies:
- '@jridgewell/gen-mapping': 0.3.13
- '@jridgewell/trace-mapping': 0.3.31
-
- '@jridgewell/source-map@0.3.6':
- dependencies:
- '@jridgewell/gen-mapping': 0.3.13
- '@jridgewell/trace-mapping': 0.3.31
+ '@jridgewell/gen-mapping': 0.3.13
+ '@jridgewell/trace-mapping': 0.3.31
'@jridgewell/sourcemap-codec@1.5.0': {}
@@ -18120,8 +16997,8 @@ snapshots:
'@napi-rs/wasm-runtime@0.2.9':
dependencies:
- '@emnapi/core': 1.4.3
- '@emnapi/runtime': 1.4.3
+ '@emnapi/core': 1.5.0
+ '@emnapi/runtime': 1.5.0
'@tybys/wasm-util': 0.9.0
optional: true
@@ -18868,6 +17745,8 @@ snapshots:
'@oxc-project/types@0.94.0': {}
+ '@oxc-project/types@0.95.0': {}
+
'@panva/hkdf@1.2.1': {}
'@paralleldrive/cuid2@2.2.2':
@@ -19827,61 +18706,61 @@ snapshots:
'@rolldown/binding-android-arm64@1.0.0-beta.42':
optional: true
- '@rolldown/binding-android-arm64@1.0.0-beta.43':
+ '@rolldown/binding-android-arm64@1.0.0-beta.45':
optional: true
'@rolldown/binding-darwin-arm64@1.0.0-beta.42':
optional: true
- '@rolldown/binding-darwin-arm64@1.0.0-beta.43':
+ '@rolldown/binding-darwin-arm64@1.0.0-beta.45':
optional: true
'@rolldown/binding-darwin-x64@1.0.0-beta.42':
optional: true
- '@rolldown/binding-darwin-x64@1.0.0-beta.43':
+ '@rolldown/binding-darwin-x64@1.0.0-beta.45':
optional: true
'@rolldown/binding-freebsd-x64@1.0.0-beta.42':
optional: true
- '@rolldown/binding-freebsd-x64@1.0.0-beta.43':
+ '@rolldown/binding-freebsd-x64@1.0.0-beta.45':
optional: true
'@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.42':
optional: true
- '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.43':
+ '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.45':
optional: true
'@rolldown/binding-linux-arm64-gnu@1.0.0-beta.42':
optional: true
- '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.43':
+ '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.45':
optional: true
'@rolldown/binding-linux-arm64-musl@1.0.0-beta.42':
optional: true
- '@rolldown/binding-linux-arm64-musl@1.0.0-beta.43':
+ '@rolldown/binding-linux-arm64-musl@1.0.0-beta.45':
optional: true
'@rolldown/binding-linux-x64-gnu@1.0.0-beta.42':
optional: true
- '@rolldown/binding-linux-x64-gnu@1.0.0-beta.43':
+ '@rolldown/binding-linux-x64-gnu@1.0.0-beta.45':
optional: true
'@rolldown/binding-linux-x64-musl@1.0.0-beta.42':
optional: true
- '@rolldown/binding-linux-x64-musl@1.0.0-beta.43':
+ '@rolldown/binding-linux-x64-musl@1.0.0-beta.45':
optional: true
'@rolldown/binding-openharmony-arm64@1.0.0-beta.42':
optional: true
- '@rolldown/binding-openharmony-arm64@1.0.0-beta.43':
+ '@rolldown/binding-openharmony-arm64@1.0.0-beta.45':
optional: true
'@rolldown/binding-wasm32-wasi@1.0.0-beta.42':
@@ -19889,7 +18768,7 @@ snapshots:
'@napi-rs/wasm-runtime': 1.0.6
optional: true
- '@rolldown/binding-wasm32-wasi@1.0.0-beta.43':
+ '@rolldown/binding-wasm32-wasi@1.0.0-beta.45':
dependencies:
'@napi-rs/wasm-runtime': 1.0.7
optional: true
@@ -19897,24 +18776,24 @@ snapshots:
'@rolldown/binding-win32-arm64-msvc@1.0.0-beta.42':
optional: true
- '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.43':
+ '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.45':
optional: true
'@rolldown/binding-win32-ia32-msvc@1.0.0-beta.42':
optional: true
- '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.43':
+ '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.45':
optional: true
'@rolldown/binding-win32-x64-msvc@1.0.0-beta.42':
optional: true
- '@rolldown/binding-win32-x64-msvc@1.0.0-beta.43':
+ '@rolldown/binding-win32-x64-msvc@1.0.0-beta.45':
optional: true
'@rolldown/pluginutils@1.0.0-beta.42': {}
- '@rolldown/pluginutils@1.0.0-beta.43': {}
+ '@rolldown/pluginutils@1.0.0-beta.45': {}
'@rollup/plugin-alias@5.1.1(rollup@4.40.2)':
optionalDependencies:
@@ -20115,22 +18994,12 @@ snapshots:
'@sigstore/core': 1.1.0
'@sigstore/protobuf-specs': 0.3.3
- '@sinclair/typebox@0.27.8': {}
-
'@sindresorhus/is@4.6.0': {}
'@sindresorhus/is@7.0.1': {}
'@sindresorhus/merge-streams@2.3.0': {}
- '@sinonjs/commons@3.0.1':
- dependencies:
- type-detect: 4.0.8
-
- '@sinonjs/fake-timers@10.3.0':
- dependencies:
- '@sinonjs/commons': 3.0.1
-
'@smithy/abort-controller@4.0.2':
dependencies:
'@smithy/types': 4.3.1
@@ -20903,11 +19772,11 @@ snapshots:
dependencies:
solid-js: 1.9.6
- '@solidjs/start@1.1.3(@testing-library/jest-dom@6.5.0)(@types/node@22.15.17)(jiti@2.6.1)(solid-js@1.9.6)(terser@5.44.0)(vinxi@0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(rolldown@1.0.0-beta.43)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1))(vite@6.3.5(@types/node@22.15.17)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1)':
+ '@solidjs/start@1.1.3(@testing-library/jest-dom@6.5.0)(@types/node@22.15.17)(jiti@2.6.1)(solid-js@1.9.6)(terser@5.44.0)(vinxi@0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1))(vite@6.3.5(@types/node@22.15.17)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1)':
dependencies:
'@tanstack/server-functions-plugin': 1.119.2(@types/node@22.15.17)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1)
- '@vinxi/plugin-directives': 0.5.1(vinxi@0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(rolldown@1.0.0-beta.43)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1))
- '@vinxi/server-components': 0.5.1(vinxi@0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(rolldown@1.0.0-beta.43)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1))
+ '@vinxi/plugin-directives': 0.5.1(vinxi@0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1))
+ '@vinxi/server-components': 0.5.1(vinxi@0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1))
defu: 6.1.4
error-stack-parser: 2.1.4
html-to-image: 1.11.13
@@ -20918,7 +19787,7 @@ snapshots:
source-map-js: 1.2.1
terracotta: 1.0.6(solid-js@1.9.6)
tinyglobby: 0.2.13
- vinxi: 0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(rolldown@1.0.0-beta.43)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1)
+ vinxi: 0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1)
vite-plugin-solid: 2.11.6(@testing-library/jest-dom@6.5.0)(solid-js@1.9.6)(vite@6.3.5(@types/node@22.15.17)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))
transitivePeerDependencies:
- '@testing-library/jest-dom'
@@ -21046,9 +19915,9 @@ snapshots:
react: 19.1.1
react-dom: 19.1.1(react@19.1.1)
- '@storybook/builder-vite@10.0.0-beta.13(esbuild@0.25.5)(rollup@4.40.2)(storybook@8.6.12(prettier@3.5.3))(vite@6.3.5(@types/node@22.15.17)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(webpack@5.101.3(esbuild@0.25.5))':
+ '@storybook/builder-vite@10.1.0-alpha.3(esbuild@0.25.5)(rollup@4.40.2)(storybook@8.6.12(prettier@3.5.3))(vite@6.3.5(@types/node@22.15.17)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(webpack@5.101.3(esbuild@0.25.5))':
dependencies:
- '@storybook/csf-plugin': 10.0.0-beta.13(esbuild@0.25.5)(rollup@4.40.2)(storybook@8.6.12(prettier@3.5.3))(vite@6.3.5(@types/node@22.15.17)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(webpack@5.101.3(esbuild@0.25.5))
+ '@storybook/csf-plugin': 10.1.0-alpha.3(esbuild@0.25.5)(rollup@4.40.2)(storybook@8.6.12(prettier@3.5.3))(vite@6.3.5(@types/node@22.15.17)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(webpack@5.101.3(esbuild@0.25.5))
storybook: 8.6.12(prettier@3.5.3)
ts-dedent: 2.2.0
vite: 6.3.5(@types/node@22.15.17)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1)
@@ -21078,7 +19947,7 @@ snapshots:
- supports-color
- utf-8-validate
- '@storybook/csf-plugin@10.0.0-beta.13(esbuild@0.25.5)(rollup@4.40.2)(storybook@8.6.12(prettier@3.5.3))(vite@6.3.5(@types/node@22.15.17)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(webpack@5.101.3(esbuild@0.25.5))':
+ '@storybook/csf-plugin@10.1.0-alpha.3(esbuild@0.25.5)(rollup@4.40.2)(storybook@8.6.12(prettier@3.5.3))(vite@6.3.5(@types/node@22.15.17)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(webpack@5.101.3(esbuild@0.25.5))':
dependencies:
storybook: 8.6.12(prettier@3.5.3)
unplugin: 2.3.10
@@ -21547,13 +20416,17 @@ snapshots:
'@tsconfig/bun@1.0.7': {}
- '@tsconfig/node10@1.0.11': {}
+ '@tsconfig/node10@1.0.11':
+ optional: true
- '@tsconfig/node12@1.0.11': {}
+ '@tsconfig/node12@1.0.11':
+ optional: true
- '@tsconfig/node14@1.0.3': {}
+ '@tsconfig/node14@1.0.3':
+ optional: true
- '@tsconfig/node16@1.0.4': {}
+ '@tsconfig/node16@1.0.4':
+ optional: true
'@tufjs/canonical-json@2.0.0': {}
@@ -21627,8 +20500,6 @@ snapshots:
'@types/cookie@0.6.0': {}
- '@types/cookiejar@2.1.5': {}
-
'@types/cookies@0.9.0':
dependencies:
'@types/connect': 3.4.38
@@ -21636,10 +20507,6 @@ snapshots:
'@types/keygrip': 1.0.6
'@types/node': 20.17.43
- '@types/cors@2.8.17':
- dependencies:
- '@types/node': 20.17.43
-
'@types/cors@2.8.19':
dependencies:
'@types/node': 20.17.43
@@ -21684,16 +20551,8 @@ snapshots:
'@types/file-saver@2.0.7': {}
- '@types/fluent-ffmpeg@2.1.27':
- dependencies:
- '@types/node': 20.17.43
-
'@types/google-protobuf@3.15.12': {}
- '@types/graceful-fs@4.1.9':
- dependencies:
- '@types/node': 20.17.43
-
'@types/hast@3.0.4':
dependencies:
'@types/unist': 3.0.3
@@ -21704,21 +20563,6 @@ snapshots:
'@types/http-errors@2.0.4': {}
- '@types/istanbul-lib-coverage@2.0.6': {}
-
- '@types/istanbul-lib-report@3.0.3':
- dependencies:
- '@types/istanbul-lib-coverage': 2.0.6
-
- '@types/istanbul-reports@3.0.4':
- dependencies:
- '@types/istanbul-lib-report': 3.0.3
-
- '@types/jest@29.5.14':
- dependencies:
- expect: 29.7.0
- pretty-format: 29.7.0
-
'@types/js-cookie@3.0.6': {}
'@types/jsdom@21.1.7':
@@ -21760,18 +20604,12 @@ snapshots:
'@types/mdx@2.0.13': {}
- '@types/methods@1.1.4': {}
-
'@types/micromatch@4.0.9':
dependencies:
'@types/braces': 3.0.5
'@types/mime@1.3.5': {}
- '@types/morgan@1.9.9':
- dependencies:
- '@types/node': 20.17.43
-
'@types/ms@2.1.0': {}
'@types/node-fetch@2.6.12':
@@ -21861,20 +20699,6 @@ snapshots:
'@types/shimmer@1.2.0': {}
- '@types/stack-utils@2.0.3': {}
-
- '@types/superagent@8.1.9':
- dependencies:
- '@types/cookiejar': 2.1.5
- '@types/methods': 1.1.4
- '@types/node': 20.17.43
- form-data: 4.0.2
-
- '@types/supertest@6.0.3':
- dependencies:
- '@types/methods': 1.1.4
- '@types/superagent': 8.1.9
-
'@types/tmp@0.2.6': {}
'@types/tough-cookie@4.0.5': {}
@@ -21890,12 +20714,6 @@ snapshots:
'@types/uuid@9.0.8': {}
- '@types/yargs-parser@21.0.3': {}
-
- '@types/yargs@17.0.33':
- dependencies:
- '@types/yargs-parser': 21.0.3
-
'@types/yauzl@2.10.3':
dependencies:
'@types/node': 20.19.19
@@ -21908,7 +20726,7 @@ snapshots:
'@typescript-eslint/scope-manager': 5.62.0
'@typescript-eslint/type-utils': 5.62.0(eslint@8.57.1)(typescript@5.8.3)
'@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.8.3)
- debug: 4.4.0(supports-color@5.5.0)
+ debug: 4.4.0
eslint: 8.57.1
graphemer: 1.4.0
ignore: 5.3.2
@@ -21920,24 +20738,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3)':
- dependencies:
- '@eslint-community/regexpp': 4.12.1
- '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.8.3)
- '@typescript-eslint/scope-manager': 7.18.0
- '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.1)(typescript@5.8.3)
- '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.8.3)
- '@typescript-eslint/visitor-keys': 7.18.0
- eslint: 8.57.1
- graphemer: 1.4.0
- ignore: 5.3.2
- natural-compare: 1.4.0
- ts-api-utils: 1.4.3(typescript@5.8.3)
- optionalDependencies:
- typescript: 5.8.3
- transitivePeerDependencies:
- - supports-color
-
'@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.30.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.30.1(jiti@2.6.1))(typescript@5.8.3)':
dependencies:
'@eslint-community/regexpp': 4.12.1
@@ -21961,20 +20761,7 @@ snapshots:
'@typescript-eslint/scope-manager': 5.62.0
'@typescript-eslint/types': 5.62.0
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.8.3)
- debug: 4.4.0(supports-color@5.5.0)
- eslint: 8.57.1
- optionalDependencies:
- typescript: 5.8.3
- transitivePeerDependencies:
- - supports-color
-
- '@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.8.3)':
- dependencies:
- '@typescript-eslint/scope-manager': 7.18.0
- '@typescript-eslint/types': 7.18.0
- '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.8.3)
- '@typescript-eslint/visitor-keys': 7.18.0
- debug: 4.4.0(supports-color@5.5.0)
+ debug: 4.4.0
eslint: 8.57.1
optionalDependencies:
typescript: 5.8.3
@@ -21987,7 +20774,7 @@ snapshots:
'@typescript-eslint/types': 7.18.0
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.8.3)
'@typescript-eslint/visitor-keys': 7.18.0
- debug: 4.4.0(supports-color@5.5.0)
+ debug: 4.4.0
eslint: 9.30.1(jiti@2.6.1)
optionalDependencies:
typescript: 5.8.3
@@ -22016,18 +20803,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/type-utils@7.18.0(eslint@8.57.1)(typescript@5.8.3)':
- dependencies:
- '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.8.3)
- '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.8.3)
- debug: 4.4.1
- eslint: 8.57.1
- ts-api-utils: 1.4.3(typescript@5.8.3)
- optionalDependencies:
- typescript: 5.8.3
- transitivePeerDependencies:
- - supports-color
-
'@typescript-eslint/type-utils@7.18.0(eslint@9.30.1(jiti@2.6.1))(typescript@5.8.3)':
dependencies:
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.8.3)
@@ -22088,17 +20863,6 @@ snapshots:
- supports-color
- typescript
- '@typescript-eslint/utils@7.18.0(eslint@8.57.1)(typescript@5.8.3)':
- dependencies:
- '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.1)
- '@typescript-eslint/scope-manager': 7.18.0
- '@typescript-eslint/types': 7.18.0
- '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.8.3)
- eslint: 8.57.1
- transitivePeerDependencies:
- - supports-color
- - typescript
-
'@typescript-eslint/utils@7.18.0(eslint@9.30.1(jiti@2.6.1))(typescript@5.8.3)':
dependencies:
'@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.6.1))
@@ -22261,7 +21025,7 @@ snapshots:
untun: 0.1.3
uqr: 0.1.2
- '@vinxi/plugin-directives@0.5.1(vinxi@0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(rolldown@1.0.0-beta.43)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1))':
+ '@vinxi/plugin-directives@0.5.1(vinxi@0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1))':
dependencies:
'@babel/parser': 7.27.2
acorn: 8.14.1
@@ -22272,18 +21036,18 @@ snapshots:
magicast: 0.2.11
recast: 0.23.11
tslib: 2.8.1
- vinxi: 0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(rolldown@1.0.0-beta.43)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1)
+ vinxi: 0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1)
- '@vinxi/server-components@0.5.1(vinxi@0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(rolldown@1.0.0-beta.43)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1))':
+ '@vinxi/server-components@0.5.1(vinxi@0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1))':
dependencies:
- '@vinxi/plugin-directives': 0.5.1(vinxi@0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(rolldown@1.0.0-beta.43)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1))
+ '@vinxi/plugin-directives': 0.5.1(vinxi@0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1))
acorn: 8.14.1
acorn-loose: 8.5.0
acorn-typescript: 1.4.13(acorn@8.14.1)
astring: 1.9.0
magicast: 0.2.11
recast: 0.23.11
- vinxi: 0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(rolldown@1.0.0-beta.43)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1)
+ vinxi: 0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1)
'@virtual-grid/core@2.0.1': {}
@@ -22546,6 +21310,7 @@ snapshots:
acorn-walk@8.3.4:
dependencies:
acorn: 8.15.0
+ optional: true
acorn@7.4.1: {}
@@ -22601,10 +21366,6 @@ snapshots:
ansi-colors@4.1.3: {}
- ansi-escapes@4.3.2:
- dependencies:
- type-fest: 0.21.3
-
ansi-regex@5.0.1: {}
ansi-regex@6.1.0: {}
@@ -22695,7 +21456,8 @@ snapshots:
delegates: 1.0.0
readable-stream: 3.6.2
- arg@4.1.3: {}
+ arg@4.1.3:
+ optional: true
arg@5.0.2: {}
@@ -22724,8 +21486,6 @@ snapshots:
call-bound: 1.0.4
is-array-buffer: 3.0.5
- array-flatten@1.1.1: {}
-
array-includes@3.1.8:
dependencies:
call-bind: 1.0.8
@@ -22794,8 +21554,6 @@ snapshots:
dependencies:
printable-characters: 1.0.42
- asap@2.0.6: {}
-
asn1js@3.0.6:
dependencies:
pvtsutils: 1.3.6
@@ -22829,8 +21587,6 @@ snapshots:
async-sema@3.1.1: {}
- async@0.2.10: {}
-
async@3.2.6: {}
asynckit@0.4.0: {}
@@ -22889,42 +21645,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
- babel-jest@29.7.0(@babel/core@7.27.1):
- dependencies:
- '@babel/core': 7.27.1
- '@jest/transform': 29.7.0
- '@types/babel__core': 7.20.5
- babel-plugin-istanbul: 6.1.1
- babel-preset-jest: 29.6.3(@babel/core@7.27.1)
- chalk: 4.1.2
- graceful-fs: 4.2.11
- slash: 3.0.0
- transitivePeerDependencies:
- - supports-color
-
babel-loader@10.0.0(@babel/core@7.27.1)(webpack@5.101.3(esbuild@0.25.5)):
dependencies:
'@babel/core': 7.27.1
find-up: 5.0.0
webpack: 5.101.3(esbuild@0.25.5)
- babel-plugin-istanbul@6.1.1:
- dependencies:
- '@babel/helper-plugin-utils': 7.27.1
- '@istanbuljs/load-nyc-config': 1.1.0
- '@istanbuljs/schema': 0.1.3
- istanbul-lib-instrument: 5.2.1
- test-exclude: 6.0.0
- transitivePeerDependencies:
- - supports-color
-
- babel-plugin-jest-hoist@29.6.3:
- dependencies:
- '@babel/template': 7.27.2
- '@babel/types': 7.28.4
- '@types/babel__core': 7.20.5
- '@types/babel__traverse': 7.20.7
-
babel-plugin-jsx-dom-expressions@0.39.8(@babel/core@7.27.1):
dependencies:
'@babel/core': 7.27.1
@@ -22935,31 +21661,6 @@ snapshots:
parse5: 7.3.0
validate-html-nesting: 1.2.2
- babel-preset-current-node-syntax@1.1.0(@babel/core@7.27.1):
- dependencies:
- '@babel/core': 7.27.1
- '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.27.1)
- '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.27.1)
- '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.27.1)
- '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.27.1)
- '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.27.1)
- '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.27.1)
- '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.27.1)
- '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.27.1)
- '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.27.1)
- '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.27.1)
- '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.27.1)
- '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.27.1)
- '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.27.1)
- '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.27.1)
- '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.27.1)
-
- babel-preset-jest@29.6.3(@babel/core@7.27.1):
- dependencies:
- '@babel/core': 7.27.1
- babel-plugin-jest-hoist: 29.6.3
- babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.1)
-
babel-preset-solid@1.9.6(@babel/core@7.27.1):
dependencies:
'@babel/core': 7.27.1
@@ -22978,10 +21679,6 @@ snapshots:
baseline-browser-mapping@2.8.16: {}
- basic-auth@2.0.1:
- dependencies:
- safe-buffer: 5.1.2
-
before-after-hook@2.2.3: {}
before-after-hook@3.0.2: {}
@@ -23017,23 +21714,6 @@ snapshots:
blake3-wasm@2.1.5: {}
- body-parser@1.20.3:
- dependencies:
- bytes: 3.1.2
- content-type: 1.0.5
- debug: 2.6.9
- depd: 2.0.0
- destroy: 1.2.0
- http-errors: 2.0.0
- iconv-lite: 0.4.24
- on-finished: 2.4.1
- qs: 6.13.0
- raw-body: 2.5.2
- type-is: 1.6.18
- unpipe: 1.0.0
- transitivePeerDependencies:
- - supports-color
-
body-parser@2.2.0:
dependencies:
bytes: 3.1.2
@@ -23093,14 +21773,6 @@ snapshots:
node-releases: 2.0.23
update-browserslist-db: 1.1.3(browserslist@4.26.3)
- bs-logger@0.2.6:
- dependencies:
- fast-json-stable-stringify: 2.1.0
-
- bser@2.1.1:
- dependencies:
- node-int64: 0.4.0
-
buffer-crc32@0.2.13: {}
buffer-crc32@1.0.0: {}
@@ -23206,10 +21878,6 @@ snapshots:
camelcase-css@2.0.1: {}
- camelcase@5.3.1: {}
-
- camelcase@6.3.0: {}
-
camelcase@8.0.0: {}
caniuse-lite@1.0.30001717: {}
@@ -23260,8 +21928,6 @@ snapshots:
chalk@5.4.1: {}
- char-regex@1.0.2: {}
-
character-entities-html4@2.1.0: {}
character-entities-legacy@3.0.0: {}
@@ -23296,8 +21962,6 @@ snapshots:
chrome-trace-event@1.0.4: {}
- ci-info@3.9.0: {}
-
citty@0.1.6:
dependencies:
consola: 3.4.2
@@ -23358,12 +22022,8 @@ snapshots:
transitivePeerDependencies:
- '@types/react'
- co@4.6.0: {}
-
collapse-white-space@2.1.0: {}
- collect-v8-coverage@1.0.2: {}
-
color-convert@1.9.3:
dependencies:
color-name: 1.1.3
@@ -23429,8 +22089,6 @@ snapshots:
compatx@0.2.0: {}
- component-emitter@1.3.1: {}
-
compress-commons@4.1.2:
dependencies:
buffer-crc32: 0.2.13
@@ -23461,16 +22119,10 @@ snapshots:
confbox@0.2.2: {}
- confusing-browser-globals@1.0.11: {}
-
consola@3.4.2: {}
console-control-strings@1.1.0: {}
- content-disposition@0.5.4:
- dependencies:
- safe-buffer: 5.2.1
-
content-disposition@1.0.0:
dependencies:
safe-buffer: 5.2.1
@@ -23498,20 +22150,14 @@ snapshots:
cookie-es@2.0.0: {}
- cookie-signature@1.0.6: {}
-
cookie-signature@1.2.2: {}
cookie@0.5.0: {}
- cookie@0.7.1: {}
-
cookie@0.7.2: {}
cookie@1.0.2: {}
- cookiejar@2.1.4: {}
-
cookies-next@4.3.0:
dependencies:
'@types/cookie': 0.6.0
@@ -23544,22 +22190,8 @@ snapshots:
crc-32: 1.2.2
readable-stream: 4.7.0
- create-jest@29.7.0(@types/node@20.17.43)(ts-node@10.9.2(@types/node@20.17.43)(typescript@5.8.3)):
- dependencies:
- '@jest/types': 29.6.3
- chalk: 4.1.2
- exit: 0.1.2
- graceful-fs: 4.2.11
- jest-config: 29.7.0(@types/node@20.17.43)(ts-node@10.9.2(@types/node@20.17.43)(typescript@5.8.3))
- jest-util: 29.7.0
- prompts: 2.4.2
- transitivePeerDependencies:
- - '@types/node'
- - babel-plugin-macros
- - supports-color
- - ts-node
-
- create-require@1.1.1: {}
+ create-require@1.1.1:
+ optional: true
cron-parser@4.9.0:
dependencies:
@@ -23657,11 +22289,9 @@ snapshots:
dependencies:
ms: 2.1.3
- debug@4.4.0(supports-color@5.5.0):
+ debug@4.4.0:
dependencies:
ms: 2.1.3
- optionalDependencies:
- supports-color: 5.5.0
debug@4.4.1:
dependencies:
@@ -23761,8 +22391,6 @@ snapshots:
detect-libc@2.1.2:
optional: true
- detect-newline@3.1.0: {}
-
detect-node-es@1.1.0: {}
detective-amd@5.0.2:
@@ -23814,16 +22442,10 @@ snapshots:
dependencies:
dequal: 2.0.3
- dezalgo@1.0.4:
- dependencies:
- asap: 2.0.6
- wrappy: 1.0.2
-
didyoumean@1.2.2: {}
- diff-sequences@29.6.3: {}
-
- diff@4.0.2: {}
+ diff@4.0.2:
+ optional: true
diff@7.0.0: {}
@@ -23931,16 +22553,10 @@ snapshots:
'@standard-schema/spec': 1.0.0
fast-check: 3.23.2
- ejs@3.1.10:
- dependencies:
- jake: 10.9.2
-
electron-to-chromium@1.5.150: {}
electron-to-chromium@1.5.234: {}
- emittery@0.13.1: {}
-
emoji-regex-xs@1.0.0: {}
emoji-regex@10.4.0: {}
@@ -24004,10 +22620,6 @@ snapshots:
err-code@2.0.3: {}
- error-ex@1.3.2:
- dependencies:
- is-arrayish: 0.2.1
-
error-stack-parser-es@1.0.5: {}
error-stack-parser@2.1.4:
@@ -24320,8 +22932,6 @@ snapshots:
escape-string-regexp@1.0.5: {}
- escape-string-regexp@2.0.0: {}
-
escape-string-regexp@4.0.0: {}
escape-string-regexp@5.0.0: {}
@@ -24334,24 +22944,6 @@ snapshots:
optionalDependencies:
source-map: 0.6.1
- eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.31.0)(eslint@8.57.1):
- dependencies:
- confusing-browser-globals: 1.0.11
- eslint: 8.57.1
- eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1)
- object.assign: 4.1.7
- object.entries: 1.1.9
- semver: 6.3.1
-
- eslint-config-airbnb-typescript@18.0.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3))(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.8.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1):
- dependencies:
- '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3)
- '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.8.3)
- eslint: 8.57.1
- eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0)(eslint@8.57.1)
- transitivePeerDependencies:
- - eslint-plugin-import
-
eslint-config-next@13.3.0(eslint@8.57.1)(typescript@5.8.3):
dependencies:
'@next/eslint-plugin-next': 13.3.0
@@ -24411,7 +23003,7 @@ snapshots:
eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0)(eslint@8.57.1):
dependencies:
'@nolyfill/is-core-module': 1.0.39
- debug: 4.4.0(supports-color@5.5.0)
+ debug: 4.4.0
eslint: 8.57.1
get-tsconfig: 4.10.0
is-bun-module: 2.0.0
@@ -24419,14 +23011,14 @@ snapshots:
tinyglobby: 0.2.13
unrs-resolver: 1.7.2
optionalDependencies:
- eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1)
+ eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1)
transitivePeerDependencies:
- supports-color
eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0)(eslint@9.30.1(jiti@2.6.1)):
dependencies:
'@nolyfill/is-core-module': 1.0.39
- debug: 4.4.0(supports-color@5.5.0)
+ debug: 4.4.0
eslint: 9.30.1(jiti@2.6.1)
get-tsconfig: 4.10.0
is-bun-module: 2.0.0
@@ -24449,17 +23041,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-module-utils@2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1):
- dependencies:
- debug: 3.2.7
- optionalDependencies:
- '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.8.3)
- eslint: 8.57.1
- eslint-import-resolver-node: 0.3.9
- eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0)(eslint@8.57.1)
- transitivePeerDependencies:
- - supports-color
-
eslint-module-utils@2.12.0(@typescript-eslint/parser@7.18.0(eslint@9.30.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@2.6.1)):
dependencies:
debug: 3.2.7
@@ -24500,35 +23081,6 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
- eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1):
- dependencies:
- '@rtsao/scc': 1.1.0
- array-includes: 3.1.8
- array.prototype.findlastindex: 1.2.6
- array.prototype.flat: 1.3.3
- array.prototype.flatmap: 1.3.3
- debug: 3.2.7
- doctrine: 2.1.0
- eslint: 8.57.1
- eslint-import-resolver-node: 0.3.9
- eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1)
- hasown: 2.0.2
- is-core-module: 2.16.1
- is-glob: 4.0.3
- minimatch: 3.1.2
- object.fromentries: 2.0.8
- object.groupby: 1.0.3
- object.values: 1.2.1
- semver: 6.3.1
- string.prototype.trimend: 1.0.9
- tsconfig-paths: 3.15.0
- optionalDependencies:
- '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.8.3)
- transitivePeerDependencies:
- - eslint-import-resolver-typescript
- - eslint-import-resolver-webpack
- - supports-color
-
eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@9.30.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@2.6.1)):
dependencies:
'@rtsao/scc': 1.1.0
@@ -24707,7 +23259,7 @@ snapshots:
ajv: 6.12.6
chalk: 4.1.2
cross-spawn: 7.0.6
- debug: 4.4.0(supports-color@5.5.0)
+ debug: 4.4.0
doctrine: 3.0.0
enquirer: 2.4.1
escape-string-regexp: 4.0.0
@@ -24960,60 +23512,14 @@ snapshots:
exit-hook@2.2.1: {}
- exit@0.1.2: {}
-
expect-type@1.2.1: {}
- expect@29.7.0:
- dependencies:
- '@jest/expect-utils': 29.7.0
- jest-get-type: 29.6.3
- jest-matcher-utils: 29.7.0
- jest-message-util: 29.7.0
- jest-util: 29.7.0
-
exponential-backoff@3.1.2: {}
express-rate-limit@7.5.1(express@5.1.0):
dependencies:
express: 5.1.0
- express@4.21.2:
- dependencies:
- accepts: 1.3.8
- array-flatten: 1.1.1
- body-parser: 1.20.3
- content-disposition: 0.5.4
- content-type: 1.0.5
- cookie: 0.7.1
- cookie-signature: 1.0.6
- debug: 2.6.9
- depd: 2.0.0
- encodeurl: 2.0.0
- escape-html: 1.0.3
- etag: 1.8.1
- finalhandler: 1.3.1
- fresh: 0.5.2
- http-errors: 2.0.0
- merge-descriptors: 1.0.3
- methods: 1.1.2
- on-finished: 2.4.1
- parseurl: 1.3.3
- path-to-regexp: 0.1.12
- proxy-addr: 2.0.7
- qs: 6.13.0
- range-parser: 1.2.1
- safe-buffer: 5.2.1
- send: 0.19.0
- serve-static: 1.16.2
- setprototypeof: 1.2.0
- statuses: 2.0.1
- type-is: 1.6.18
- utils-merge: 1.0.1
- vary: 1.1.2
- transitivePeerDependencies:
- - supports-color
-
express@5.1.0:
dependencies:
accepts: 2.0.0
@@ -25098,8 +23604,6 @@ snapshots:
fast-levenshtein@2.0.6: {}
- fast-safe-stringify@2.1.1: {}
-
fast-uri@3.0.6: {}
fast-xml-parser@4.4.1:
@@ -25118,10 +23622,6 @@ snapshots:
dependencies:
format: 0.2.2
- fb-watchman@2.0.2:
- dependencies:
- bser: 2.1.1
-
fd-slicer@1.1.0:
dependencies:
pend: 1.2.0
@@ -25163,10 +23663,6 @@ snapshots:
file-uri-to-path@1.0.0: {}
- filelist@1.0.4:
- dependencies:
- minimatch: 5.1.6
-
filesize@10.1.6: {}
fill-range@7.1.1:
@@ -25175,18 +23671,6 @@ snapshots:
filter-obj@5.1.0: {}
- finalhandler@1.3.1:
- dependencies:
- debug: 2.6.9
- encodeurl: 2.0.0
- escape-html: 1.0.3
- on-finished: 2.4.1
- parseurl: 1.3.3
- statuses: 2.0.1
- unpipe: 1.0.0
- transitivePeerDependencies:
- - supports-color
-
finalhandler@2.1.0:
dependencies:
debug: 4.4.3
@@ -25202,11 +23686,6 @@ snapshots:
find-up-simple@1.0.1: {}
- find-up@4.1.0:
- dependencies:
- locate-path: 5.0.0
- path-exists: 4.0.0
-
find-up@5.0.0:
dependencies:
locate-path: 6.0.0
@@ -25242,11 +23721,6 @@ snapshots:
flatted@3.3.3: {}
- fluent-ffmpeg@2.1.3:
- dependencies:
- async: 0.2.10
- which: 1.3.1
-
fn.name@1.1.0: {}
follow-redirects@1.15.9: {}
@@ -25280,13 +23754,6 @@ snapshots:
dependencies:
fetch-blob: 3.2.0
- formidable@2.1.5:
- dependencies:
- '@paralleldrive/cuid2': 2.2.2
- dezalgo: 1.0.4
- once: 1.4.0
- qs: 6.14.0
-
forwarded@0.2.0: {}
fraction.js@4.3.7: {}
@@ -25389,8 +23856,6 @@ snapshots:
get-nonce@1.0.1: {}
- get-package-type@0.1.0: {}
-
get-port-please@3.1.2: {}
get-proto@1.0.1:
@@ -25691,8 +24156,6 @@ snapshots:
dependencies:
'@types/hast': 3.0.4
- helmet@7.2.0: {}
-
hls.js@0.14.17:
dependencies:
eventemitter3: 4.0.7
@@ -25718,8 +24181,6 @@ snapshots:
html-entities@2.3.3: {}
- html-escaper@2.0.2: {}
-
html-to-image@1.11.13: {}
html-to-text@9.0.5:
@@ -25799,10 +24260,6 @@ snapshots:
hyperdyperid@1.2.0: {}
- iconv-lite@0.4.24:
- dependencies:
- safer-buffer: 2.1.2
-
iconv-lite@0.6.3:
dependencies:
safer-buffer: 2.1.2
@@ -25815,8 +24272,6 @@ snapshots:
ieee754@1.2.1: {}
- ignore-by-default@1.0.1: {}
-
ignore-walk@6.0.5:
dependencies:
minimatch: 9.0.5
@@ -25843,11 +24298,6 @@ snapshots:
cjs-module-lexer: 1.4.3
module-details-from-path: 1.0.4
- import-local@3.2.0:
- dependencies:
- pkg-dir: 4.2.0
- resolve-cwd: 3.0.0
-
imurmurhash@0.1.4: {}
indent-string@4.0.0: {}
@@ -25935,8 +24385,6 @@ snapshots:
call-bound: 1.0.4
get-intrinsic: 1.3.0
- is-arrayish@0.2.1: {}
-
is-arrayish@0.3.2: {}
is-async-function@2.1.1:
@@ -26001,8 +24449,6 @@ snapshots:
is-fullwidth-code-point@3.0.0: {}
- is-generator-fn@2.1.0: {}
-
is-generator-function@1.1.0:
dependencies:
call-bound: 1.0.4
@@ -26128,47 +24574,6 @@ snapshots:
isexe@3.1.1: {}
- istanbul-lib-coverage@3.2.2: {}
-
- istanbul-lib-instrument@5.2.1:
- dependencies:
- '@babel/core': 7.27.1
- '@babel/parser': 7.28.4
- '@istanbuljs/schema': 0.1.3
- istanbul-lib-coverage: 3.2.2
- semver: 6.3.1
- transitivePeerDependencies:
- - supports-color
-
- istanbul-lib-instrument@6.0.3:
- dependencies:
- '@babel/core': 7.27.1
- '@babel/parser': 7.27.5
- '@istanbuljs/schema': 0.1.3
- istanbul-lib-coverage: 3.2.2
- semver: 7.7.2
- transitivePeerDependencies:
- - supports-color
-
- istanbul-lib-report@3.0.1:
- dependencies:
- istanbul-lib-coverage: 3.2.2
- make-dir: 4.0.0
- supports-color: 7.2.0
-
- istanbul-lib-source-maps@4.0.1:
- dependencies:
- debug: 4.4.3
- istanbul-lib-coverage: 3.2.2
- source-map: 0.6.1
- transitivePeerDependencies:
- - supports-color
-
- istanbul-reports@3.1.7:
- dependencies:
- html-escaper: 2.0.2
- istanbul-lib-report: 3.0.1
-
iterator.prototype@1.1.5:
dependencies:
define-data-property: 1.1.4
@@ -26188,328 +24593,12 @@ snapshots:
dependencies:
'@isaacs/cliui': 8.0.2
- jake@10.9.2:
- dependencies:
- async: 3.2.6
- chalk: 4.1.2
- filelist: 1.0.4
- minimatch: 3.1.2
-
- jest-changed-files@29.7.0:
- dependencies:
- execa: 5.1.1
- jest-util: 29.7.0
- p-limit: 3.1.0
-
- jest-circus@29.7.0:
- dependencies:
- '@jest/environment': 29.7.0
- '@jest/expect': 29.7.0
- '@jest/test-result': 29.7.0
- '@jest/types': 29.6.3
- '@types/node': 20.17.43
- chalk: 4.1.2
- co: 4.6.0
- dedent: 1.6.0
- is-generator-fn: 2.1.0
- jest-each: 29.7.0
- jest-matcher-utils: 29.7.0
- jest-message-util: 29.7.0
- jest-runtime: 29.7.0
- jest-snapshot: 29.7.0
- jest-util: 29.7.0
- p-limit: 3.1.0
- pretty-format: 29.7.0
- pure-rand: 6.1.0
- slash: 3.0.0
- stack-utils: 2.0.6
- transitivePeerDependencies:
- - babel-plugin-macros
- - supports-color
-
- jest-cli@29.7.0(@types/node@20.17.43)(ts-node@10.9.2(@types/node@20.17.43)(typescript@5.8.3)):
- dependencies:
- '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.17.43)(typescript@5.8.3))
- '@jest/test-result': 29.7.0
- '@jest/types': 29.6.3
- chalk: 4.1.2
- create-jest: 29.7.0(@types/node@20.17.43)(ts-node@10.9.2(@types/node@20.17.43)(typescript@5.8.3))
- exit: 0.1.2
- import-local: 3.2.0
- jest-config: 29.7.0(@types/node@20.17.43)(ts-node@10.9.2(@types/node@20.17.43)(typescript@5.8.3))
- jest-util: 29.7.0
- jest-validate: 29.7.0
- yargs: 17.7.2
- transitivePeerDependencies:
- - '@types/node'
- - babel-plugin-macros
- - supports-color
- - ts-node
-
- jest-config@29.7.0(@types/node@20.17.43)(ts-node@10.9.2(@types/node@20.17.43)(typescript@5.8.3)):
- dependencies:
- '@babel/core': 7.27.1
- '@jest/test-sequencer': 29.7.0
- '@jest/types': 29.6.3
- babel-jest: 29.7.0(@babel/core@7.27.1)
- chalk: 4.1.2
- ci-info: 3.9.0
- deepmerge: 4.3.1
- glob: 7.2.3
- graceful-fs: 4.2.11
- jest-circus: 29.7.0
- jest-environment-node: 29.7.0
- jest-get-type: 29.6.3
- jest-regex-util: 29.6.3
- jest-resolve: 29.7.0
- jest-runner: 29.7.0
- jest-util: 29.7.0
- jest-validate: 29.7.0
- micromatch: 4.0.8
- parse-json: 5.2.0
- pretty-format: 29.7.0
- slash: 3.0.0
- strip-json-comments: 3.1.1
- optionalDependencies:
- '@types/node': 20.17.43
- ts-node: 10.9.2(@types/node@20.17.43)(typescript@5.8.3)
- transitivePeerDependencies:
- - babel-plugin-macros
- - supports-color
-
- jest-diff@29.7.0:
- dependencies:
- chalk: 4.1.2
- diff-sequences: 29.6.3
- jest-get-type: 29.6.3
- pretty-format: 29.7.0
-
- jest-docblock@29.7.0:
- dependencies:
- detect-newline: 3.1.0
-
- jest-each@29.7.0:
- dependencies:
- '@jest/types': 29.6.3
- chalk: 4.1.2
- jest-get-type: 29.6.3
- jest-util: 29.7.0
- pretty-format: 29.7.0
-
- jest-environment-node@29.7.0:
- dependencies:
- '@jest/environment': 29.7.0
- '@jest/fake-timers': 29.7.0
- '@jest/types': 29.6.3
- '@types/node': 20.17.43
- jest-mock: 29.7.0
- jest-util: 29.7.0
-
- jest-get-type@29.6.3: {}
-
- jest-haste-map@29.7.0:
- dependencies:
- '@jest/types': 29.6.3
- '@types/graceful-fs': 4.1.9
- '@types/node': 20.17.43
- anymatch: 3.1.3
- fb-watchman: 2.0.2
- graceful-fs: 4.2.11
- jest-regex-util: 29.6.3
- jest-util: 29.7.0
- jest-worker: 29.7.0
- micromatch: 4.0.8
- walker: 1.0.8
- optionalDependencies:
- fsevents: 2.3.3
-
- jest-leak-detector@29.7.0:
- dependencies:
- jest-get-type: 29.6.3
- pretty-format: 29.7.0
-
- jest-matcher-utils@29.7.0:
- dependencies:
- chalk: 4.1.2
- jest-diff: 29.7.0
- jest-get-type: 29.6.3
- pretty-format: 29.7.0
-
- jest-message-util@29.7.0:
- dependencies:
- '@babel/code-frame': 7.27.1
- '@jest/types': 29.6.3
- '@types/stack-utils': 2.0.3
- chalk: 4.1.2
- graceful-fs: 4.2.11
- micromatch: 4.0.8
- pretty-format: 29.7.0
- slash: 3.0.0
- stack-utils: 2.0.6
-
- jest-mock@29.7.0:
- dependencies:
- '@jest/types': 29.6.3
- '@types/node': 20.17.43
- jest-util: 29.7.0
-
- jest-pnp-resolver@1.2.3(jest-resolve@29.7.0):
- optionalDependencies:
- jest-resolve: 29.7.0
-
- jest-regex-util@29.6.3: {}
-
- jest-resolve-dependencies@29.7.0:
- dependencies:
- jest-regex-util: 29.6.3
- jest-snapshot: 29.7.0
- transitivePeerDependencies:
- - supports-color
-
- jest-resolve@29.7.0:
- dependencies:
- chalk: 4.1.2
- graceful-fs: 4.2.11
- jest-haste-map: 29.7.0
- jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0)
- jest-util: 29.7.0
- jest-validate: 29.7.0
- resolve: 1.22.10
- resolve.exports: 2.0.3
- slash: 3.0.0
-
- jest-runner@29.7.0:
- dependencies:
- '@jest/console': 29.7.0
- '@jest/environment': 29.7.0
- '@jest/test-result': 29.7.0
- '@jest/transform': 29.7.0
- '@jest/types': 29.6.3
- '@types/node': 20.17.43
- chalk: 4.1.2
- emittery: 0.13.1
- graceful-fs: 4.2.11
- jest-docblock: 29.7.0
- jest-environment-node: 29.7.0
- jest-haste-map: 29.7.0
- jest-leak-detector: 29.7.0
- jest-message-util: 29.7.0
- jest-resolve: 29.7.0
- jest-runtime: 29.7.0
- jest-util: 29.7.0
- jest-watcher: 29.7.0
- jest-worker: 29.7.0
- p-limit: 3.1.0
- source-map-support: 0.5.13
- transitivePeerDependencies:
- - supports-color
-
- jest-runtime@29.7.0:
- dependencies:
- '@jest/environment': 29.7.0
- '@jest/fake-timers': 29.7.0
- '@jest/globals': 29.7.0
- '@jest/source-map': 29.6.3
- '@jest/test-result': 29.7.0
- '@jest/transform': 29.7.0
- '@jest/types': 29.6.3
- '@types/node': 20.17.43
- chalk: 4.1.2
- cjs-module-lexer: 1.4.3
- collect-v8-coverage: 1.0.2
- glob: 7.2.3
- graceful-fs: 4.2.11
- jest-haste-map: 29.7.0
- jest-message-util: 29.7.0
- jest-mock: 29.7.0
- jest-regex-util: 29.6.3
- jest-resolve: 29.7.0
- jest-snapshot: 29.7.0
- jest-util: 29.7.0
- slash: 3.0.0
- strip-bom: 4.0.0
- transitivePeerDependencies:
- - supports-color
-
- jest-snapshot@29.7.0:
- dependencies:
- '@babel/core': 7.27.1
- '@babel/generator': 7.27.1
- '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.1)
- '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.27.1)
- '@babel/types': 7.27.1
- '@jest/expect-utils': 29.7.0
- '@jest/transform': 29.7.0
- '@jest/types': 29.6.3
- babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.1)
- chalk: 4.1.2
- expect: 29.7.0
- graceful-fs: 4.2.11
- jest-diff: 29.7.0
- jest-get-type: 29.6.3
- jest-matcher-utils: 29.7.0
- jest-message-util: 29.7.0
- jest-util: 29.7.0
- natural-compare: 1.4.0
- pretty-format: 29.7.0
- semver: 7.7.2
- transitivePeerDependencies:
- - supports-color
-
- jest-util@29.7.0:
- dependencies:
- '@jest/types': 29.6.3
- '@types/node': 20.17.43
- chalk: 4.1.2
- ci-info: 3.9.0
- graceful-fs: 4.2.11
- picomatch: 2.3.1
-
- jest-validate@29.7.0:
- dependencies:
- '@jest/types': 29.6.3
- camelcase: 6.3.0
- chalk: 4.1.2
- jest-get-type: 29.6.3
- leven: 3.1.0
- pretty-format: 29.7.0
-
- jest-watcher@29.7.0:
- dependencies:
- '@jest/test-result': 29.7.0
- '@jest/types': 29.6.3
- '@types/node': 20.17.43
- ansi-escapes: 4.3.2
- chalk: 4.1.2
- emittery: 0.13.1
- jest-util: 29.7.0
- string-length: 4.0.2
-
jest-worker@27.5.1:
dependencies:
'@types/node': 20.19.21
merge-stream: 2.0.0
supports-color: 8.1.1
- jest-worker@29.7.0:
- dependencies:
- '@types/node': 20.17.43
- jest-util: 29.7.0
- merge-stream: 2.0.0
- supports-color: 8.1.1
-
- jest@29.7.0(@types/node@20.17.43)(ts-node@10.9.2(@types/node@20.17.43)(typescript@5.8.3)):
- dependencies:
- '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.17.43)(typescript@5.8.3))
- '@jest/types': 29.6.3
- import-local: 3.2.0
- jest-cli: 29.7.0(@types/node@20.17.43)(ts-node@10.9.2(@types/node@20.17.43)(typescript@5.8.3))
- transitivePeerDependencies:
- - '@types/node'
- - babel-plugin-macros
- - supports-color
- - ts-node
-
jiti@1.21.7: {}
jiti@2.4.2: {}
@@ -26666,8 +24755,6 @@ snapshots:
leb@1.0.0: {}
- leven@3.1.0: {}
-
levn@0.4.1:
dependencies:
prelude-ls: 1.2.1
@@ -26717,10 +24804,6 @@ snapshots:
pkg-types: 2.1.0
quansync: 0.2.10
- locate-path@5.0.0:
- dependencies:
- p-locate: 4.1.0
-
locate-path@6.0.0:
dependencies:
p-locate: 5.0.0
@@ -26747,8 +24830,6 @@ snapshots:
lodash.isplainobject@4.0.6: {}
- lodash.memoize@4.1.2: {}
-
lodash.merge@4.6.2: {}
lodash.sortby@4.7.0: {}
@@ -26850,11 +24931,8 @@ snapshots:
dependencies:
semver: 6.3.1
- make-dir@4.0.0:
- dependencies:
- semver: 7.7.2
-
- make-error@1.3.6: {}
+ make-error@1.3.6:
+ optional: true
make-fetch-happen@13.0.1:
dependencies:
@@ -26873,10 +24951,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- makeerror@1.0.12:
- dependencies:
- tmpl: 1.0.5
-
map-or-similar@1.5.0: {}
markdown-extensions@2.0.0: {}
@@ -27031,8 +25105,6 @@ snapshots:
media-tracks@0.3.3: {}
- media-typer@0.3.0: {}
-
media-typer@1.1.0: {}
memfs@4.17.1:
@@ -27050,8 +25122,6 @@ snapshots:
dependencies:
is-what: 4.1.16
- merge-descriptors@1.0.3: {}
-
merge-descriptors@2.0.0: {}
merge-options@3.0.4:
@@ -27062,8 +25132,6 @@ snapshots:
merge2@1.4.1: {}
- methods@1.1.2: {}
-
micro-api-client@3.3.0: {}
micromark-core-commonmark@2.0.3:
@@ -27298,8 +25366,6 @@ snapshots:
mime@1.6.0: {}
- mime@2.6.0: {}
-
mime@3.0.0: {}
mime@4.0.7: {}
@@ -27429,16 +25495,6 @@ snapshots:
moment@2.30.1: {}
- morgan@1.10.0:
- dependencies:
- basic-auth: 2.0.1
- debug: 2.6.9
- depd: 2.0.0
- on-finished: 2.3.0
- on-headers: 1.0.2
- transitivePeerDependencies:
- - supports-color
-
motion-dom@11.18.1:
dependencies:
motion-utils: 11.18.1
@@ -27538,7 +25594,7 @@ snapshots:
p-wait-for: 5.0.2
qs: 6.14.0
- next-auth@4.24.11(next@15.5.4(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(nodemailer@6.10.1)(react-dom@19.1.1(react@19.1.1))(react@19.1.1):
+ next-auth@4.24.11(next@15.5.4(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(nodemailer@6.10.1)(react-dom@19.1.1(react@19.1.1))(react@19.1.1):
dependencies:
'@babel/runtime': 7.27.1
'@panva/hkdf': 1.2.1
@@ -27613,7 +25669,7 @@ snapshots:
cors: 2.8.5
next: 15.5.4(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
- nitropack@2.11.11(@planetscale/database@1.19.0)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(mysql2@3.15.2)(rolldown@1.0.0-beta.43)(xml2js@0.6.2):
+ nitropack@2.11.11(@planetscale/database@1.19.0)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(mysql2@3.15.2)(xml2js@0.6.2):
dependencies:
'@cloudflare/kv-asset-handler': 0.4.0
'@netlify/functions': 3.1.5(encoding@0.1.13)(rollup@4.40.2)
@@ -27667,7 +25723,7 @@ snapshots:
pretty-bytes: 6.1.1
radix3: 1.1.2
rollup: 4.40.2
- rollup-plugin-visualizer: 5.14.0(rolldown@1.0.0-beta.43)(rollup@4.40.2)
+ rollup-plugin-visualizer: 5.14.0(rollup@4.40.2)
scule: 1.3.0
semver: 7.7.2
serve-placeholder: 2.0.2
@@ -27762,8 +25818,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- node-int64@0.4.0: {}
-
node-mock-http@1.0.0: {}
node-releases@2.0.19: {}
@@ -27776,19 +25830,6 @@ snapshots:
nodemailer@6.10.1: {}
- nodemon@3.1.10:
- dependencies:
- chokidar: 3.6.0
- debug: 4.4.0(supports-color@5.5.0)
- ignore-by-default: 1.0.1
- minimatch: 3.1.2
- pstree.remy: 1.1.8
- semver: 7.7.1
- simple-update-notifier: 2.0.0
- supports-color: 5.5.0
- touch: 3.1.1
- undefsafe: 2.0.5
-
nopt@5.0.0:
dependencies:
abbrev: 1.1.1
@@ -27967,16 +26008,10 @@ snapshots:
oidc-token-hash@5.1.1: {}
- on-finished@2.3.0:
- dependencies:
- ee-first: 1.1.1
-
on-finished@2.4.1:
dependencies:
ee-first: 1.1.1
- on-headers@1.0.2: {}
-
once@1.4.0:
dependencies:
wrappy: 1.0.2
@@ -28068,10 +26103,6 @@ snapshots:
dependencies:
p-timeout: 5.1.0
- p-limit@2.3.0:
- dependencies:
- p-try: 2.2.0
-
p-limit@3.1.0:
dependencies:
yocto-queue: 0.1.0
@@ -28080,10 +26111,6 @@ snapshots:
dependencies:
yocto-queue: 1.2.1
- p-locate@4.1.0:
- dependencies:
- p-limit: 2.3.0
-
p-locate@5.0.0:
dependencies:
p-limit: 3.1.0
@@ -28102,8 +26129,6 @@ snapshots:
p-timeout@6.1.4: {}
- p-try@2.2.0: {}
-
p-wait-for@5.0.2:
dependencies:
p-timeout: 6.1.4
@@ -28167,13 +26192,6 @@ snapshots:
parse-gitignore@2.0.0: {}
- parse-json@5.2.0:
- dependencies:
- '@babel/code-frame': 7.27.1
- error-ex: 1.3.2
- json-parse-even-better-errors: 2.3.1
- lines-and-columns: 1.2.4
-
parse-json@8.3.0:
dependencies:
'@babel/code-frame': 7.27.1
@@ -28218,8 +26236,6 @@ snapshots:
lru-cache: 11.1.0
minipass: 7.1.2
- path-to-regexp@0.1.12: {}
-
path-to-regexp@6.3.0: {}
path-to-regexp@8.3.0: {}
@@ -28256,10 +26272,6 @@ snapshots:
pkce-challenge@4.1.0: {}
- pkg-dir@4.2.0:
- dependencies:
- find-up: 4.1.0
-
pkg-dir@7.0.0:
dependencies:
find-up: 6.3.0
@@ -28419,12 +26431,6 @@ snapshots:
ansi-styles: 5.2.0
react-is: 17.0.2
- pretty-format@29.7.0:
- dependencies:
- '@jest/schemas': 29.6.3
- ansi-styles: 5.2.0
- react-is: 18.3.1
-
pretty-format@3.8.0: {}
printable-characters@1.0.42: {}
@@ -28489,8 +26495,6 @@ snapshots:
proxy-from-env@1.1.0: {}
- pstree.remy@1.1.8: {}
-
pump@3.0.2:
dependencies:
end-of-stream: 1.4.4
@@ -28508,10 +26512,6 @@ snapshots:
pvutils@1.1.3: {}
- qs@6.13.0:
- dependencies:
- side-channel: 1.1.0
-
qs@6.14.0:
dependencies:
side-channel: 1.1.0
@@ -28536,13 +26536,6 @@ snapshots:
range-parser@1.2.1: {}
- raw-body@2.5.2:
- dependencies:
- bytes: 3.1.2
- http-errors: 2.0.0
- iconv-lite: 0.4.24
- unpipe: 1.0.0
-
raw-body@3.0.1:
dependencies:
bytes: 3.1.2
@@ -28656,8 +26649,6 @@ snapshots:
react-is@17.0.2: {}
- react-is@18.3.1: {}
-
react-loading-skeleton@3.5.0(react@19.1.1):
dependencies:
react: 19.1.1
@@ -28967,18 +26958,12 @@ snapshots:
resolve-alpn@1.2.1: {}
- resolve-cwd@3.0.0:
- dependencies:
- resolve-from: 5.0.0
-
resolve-from@4.0.0: {}
resolve-from@5.0.0: {}
resolve-pkg-maps@1.0.0: {}
- resolve.exports@2.0.3: {}
-
resolve@1.22.10:
dependencies:
is-core-module: 2.16.1
@@ -29008,7 +26993,7 @@ snapshots:
dependencies:
glob: 7.2.3
- rolldown-plugin-dts@0.16.11(rolldown@1.0.0-beta.43)(typescript@5.8.3):
+ rolldown-plugin-dts@0.16.11(rolldown@1.0.0-beta.45)(typescript@5.8.3):
dependencies:
'@babel/generator': 7.28.3
'@babel/parser': 7.28.4
@@ -29019,7 +27004,7 @@ snapshots:
dts-resolver: 2.1.2
get-tsconfig: 4.11.0
magic-string: 0.30.19
- rolldown: 1.0.0-beta.43
+ rolldown: 1.0.0-beta.45
optionalDependencies:
typescript: 5.8.3
transitivePeerDependencies:
@@ -29047,26 +27032,25 @@ snapshots:
'@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.42
'@rolldown/binding-win32-x64-msvc': 1.0.0-beta.42
- rolldown@1.0.0-beta.43:
+ rolldown@1.0.0-beta.45:
dependencies:
- '@oxc-project/types': 0.94.0
- '@rolldown/pluginutils': 1.0.0-beta.43
- ansis: 4.2.0
+ '@oxc-project/types': 0.95.0
+ '@rolldown/pluginutils': 1.0.0-beta.45
optionalDependencies:
- '@rolldown/binding-android-arm64': 1.0.0-beta.43
- '@rolldown/binding-darwin-arm64': 1.0.0-beta.43
- '@rolldown/binding-darwin-x64': 1.0.0-beta.43
- '@rolldown/binding-freebsd-x64': 1.0.0-beta.43
- '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.43
- '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.43
- '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.43
- '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.43
- '@rolldown/binding-linux-x64-musl': 1.0.0-beta.43
- '@rolldown/binding-openharmony-arm64': 1.0.0-beta.43
- '@rolldown/binding-wasm32-wasi': 1.0.0-beta.43
- '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.43
- '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.43
- '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.43
+ '@rolldown/binding-android-arm64': 1.0.0-beta.45
+ '@rolldown/binding-darwin-arm64': 1.0.0-beta.45
+ '@rolldown/binding-darwin-x64': 1.0.0-beta.45
+ '@rolldown/binding-freebsd-x64': 1.0.0-beta.45
+ '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.45
+ '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.45
+ '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.45
+ '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.45
+ '@rolldown/binding-linux-x64-musl': 1.0.0-beta.45
+ '@rolldown/binding-openharmony-arm64': 1.0.0-beta.45
+ '@rolldown/binding-wasm32-wasi': 1.0.0-beta.45
+ '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.45
+ '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.45
+ '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.45
rollup-plugin-inject@3.0.2:
dependencies:
@@ -29078,14 +27062,13 @@ snapshots:
dependencies:
rollup-plugin-inject: 3.0.2
- rollup-plugin-visualizer@5.14.0(rolldown@1.0.0-beta.43)(rollup@4.40.2):
+ rollup-plugin-visualizer@5.14.0(rollup@4.40.2):
dependencies:
open: 8.4.2
picomatch: 4.0.3
source-map: 0.7.4
yargs: 17.7.2
optionalDependencies:
- rolldown: 1.0.0-beta.43
rollup: 4.40.2
rollup-pluginutils@2.8.2:
@@ -29422,10 +27405,6 @@ snapshots:
dependencies:
is-arrayish: 0.3.2
- simple-update-notifier@2.0.0:
- dependencies:
- semver: 7.7.1
-
sisteransi@1.0.5: {}
slash@3.0.0: {}
@@ -29556,11 +27535,6 @@ snapshots:
source-map-js@1.2.1: {}
- source-map-support@0.5.13:
- dependencies:
- buffer-from: 1.1.2
- source-map: 0.6.1
-
source-map-support@0.5.21:
dependencies:
buffer-from: 1.1.2
@@ -29649,10 +27623,6 @@ snapshots:
stack-trace@0.0.10: {}
- stack-utils@2.0.6:
- dependencies:
- escape-string-regexp: 2.0.0
-
stackback@0.0.2: {}
stackframe@1.3.4: {}
@@ -29681,7 +27651,7 @@ snapshots:
storybook-solidjs-vite@1.0.0-beta.7(@storybook/test@8.6.12(storybook@8.6.12(prettier@3.5.3)))(esbuild@0.25.5)(rollup@4.40.2)(solid-js@1.9.6)(storybook@8.6.12(prettier@3.5.3))(vite-plugin-solid@2.11.6(@testing-library/jest-dom@6.5.0)(solid-js@1.9.6)(vite@6.3.5(@types/node@22.15.17)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1)))(vite@6.3.5(@types/node@22.15.17)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(webpack@5.101.3(esbuild@0.25.5)):
dependencies:
- '@storybook/builder-vite': 10.0.0-beta.13(esbuild@0.25.5)(rollup@4.40.2)(storybook@8.6.12(prettier@3.5.3))(vite@6.3.5(@types/node@22.15.17)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(webpack@5.101.3(esbuild@0.25.5))
+ '@storybook/builder-vite': 10.1.0-alpha.3(esbuild@0.25.5)(rollup@4.40.2)(storybook@8.6.12(prettier@3.5.3))(vite@6.3.5(@types/node@22.15.17)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(webpack@5.101.3(esbuild@0.25.5))
'@storybook/types': 9.0.0-alpha.1(storybook@8.6.12(prettier@3.5.3))
magic-string: 0.30.17
solid-js: 1.9.6
@@ -29726,11 +27696,6 @@ snapshots:
optionalDependencies:
bare-events: 2.5.4
- string-length@4.0.2:
- dependencies:
- char-regex: 1.0.2
- strip-ansi: 6.0.1
-
string-width@4.2.3:
dependencies:
emoji-regex: 8.0.0
@@ -29824,8 +27789,6 @@ snapshots:
strip-bom@3.0.0: {}
- strip-bom@4.0.0: {}
-
strip-final-newline@2.0.0: {}
strip-final-newline@3.0.0: {}
@@ -29884,28 +27847,6 @@ snapshots:
pirates: 4.0.7
ts-interface-checker: 0.1.13
- superagent@8.1.2:
- dependencies:
- component-emitter: 1.3.1
- cookiejar: 2.1.4
- debug: 4.4.1
- fast-safe-stringify: 2.1.1
- form-data: 4.0.2
- formidable: 2.1.5
- methods: 1.1.2
- mime: 2.6.0
- qs: 6.14.0
- semver: 7.7.1
- transitivePeerDependencies:
- - supports-color
-
- supertest@6.3.4:
- dependencies:
- methods: 1.1.2
- superagent: 8.1.2
- transitivePeerDependencies:
- - supports-color
-
supports-color@10.0.0: {}
supports-color@5.5.0:
@@ -30078,12 +28019,6 @@ snapshots:
commander: 2.20.3
source-map-support: 0.5.21
- test-exclude@6.0.0:
- dependencies:
- '@istanbuljs/schema': 0.1.3
- glob: 7.2.3
- minimatch: 3.1.2
-
text-decoder@1.2.3:
dependencies:
b4a: 1.6.7
@@ -30148,8 +28083,6 @@ snapshots:
tmp@0.2.5: {}
- tmpl@1.0.5: {}
-
to-regex-range@5.0.1:
dependencies:
is-number: 7.0.0
@@ -30160,8 +28093,6 @@ snapshots:
toml@3.0.0: {}
- touch@3.1.1: {}
-
tough-cookie@5.1.2:
dependencies:
tldts: 6.1.86
@@ -30198,26 +28129,6 @@ snapshots:
ts-interface-checker@0.1.13: {}
- ts-jest@29.3.2(@babel/core@7.27.1)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.1))(jest@29.7.0(@types/node@20.17.43)(ts-node@10.9.2(@types/node@20.17.43)(typescript@5.8.3)))(typescript@5.8.3):
- dependencies:
- bs-logger: 0.2.6
- ejs: 3.1.10
- fast-json-stable-stringify: 2.1.0
- jest: 29.7.0(@types/node@20.17.43)(ts-node@10.9.2(@types/node@20.17.43)(typescript@5.8.3))
- jest-util: 29.7.0
- json5: 2.2.3
- lodash.memoize: 4.1.2
- make-error: 1.3.6
- semver: 7.7.1
- type-fest: 4.41.0
- typescript: 5.8.3
- yargs-parser: 21.1.1
- optionalDependencies:
- '@babel/core': 7.27.1
- '@jest/transform': 29.7.0
- '@jest/types': 29.6.3
- babel-jest: 29.7.0(@babel/core@7.27.1)
-
ts-node@10.9.2(@types/node@20.17.43)(typescript@5.8.3):
dependencies:
'@cspotcode/source-map-support': 0.8.1
@@ -30235,6 +28146,7 @@ snapshots:
typescript: 5.8.3
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
+ optional: true
ts-node@10.9.2(@types/node@22.15.17)(typescript@5.8.3):
dependencies:
@@ -30285,8 +28197,8 @@ snapshots:
diff: 8.0.2
empathic: 2.0.0
hookable: 5.5.3
- rolldown: 1.0.0-beta.43
- rolldown-plugin-dts: 0.16.11(rolldown@1.0.0-beta.43)(typescript@5.8.3)
+ rolldown: 1.0.0-beta.45
+ rolldown-plugin-dts: 0.16.11(rolldown@1.0.0-beta.45)(typescript@5.8.3)
semver: 7.7.2
tinyexec: 1.0.1
tinyglobby: 0.2.15
@@ -30385,19 +28297,10 @@ snapshots:
dependencies:
prelude-ls: 1.2.1
- type-detect@4.0.8: {}
-
type-fest@0.20.2: {}
- type-fest@0.21.3: {}
-
type-fest@4.41.0: {}
- type-is@1.6.18:
- dependencies:
- media-typer: 0.3.0
- mime-types: 2.1.35
-
type-is@2.0.1:
dependencies:
content-type: 1.0.5
@@ -30466,8 +28369,6 @@ snapshots:
magic-string: 0.30.17
unplugin: 2.3.2
- undefsafe@2.0.5: {}
-
undici-types@5.26.5: {}
undici-types@5.28.4: {}
@@ -30662,7 +28563,7 @@ snapshots:
'@antfu/install-pkg': 0.4.1
'@antfu/utils': 0.7.10
'@iconify/utils': 2.3.0
- debug: 4.4.0(supports-color@5.5.0)
+ debug: 4.4.0
kolorist: 1.8.0
local-pkg: 0.5.1
unplugin: 1.16.1
@@ -30828,8 +28729,6 @@ snapshots:
is-typed-array: 1.1.15
which-typed-array: 1.1.19
- utils-merge@1.0.1: {}
-
uuid@11.1.0: {}
uuid@8.0.0: {}
@@ -30838,16 +28737,11 @@ snapshots:
uuid@9.0.1: {}
- v8-compile-cache-lib@3.0.1: {}
+ v8-compile-cache-lib@3.0.1:
+ optional: true
v8-compile-cache@2.4.0: {}
- v8-to-istanbul@9.3.0:
- dependencies:
- '@jridgewell/trace-mapping': 0.3.30
- '@types/istanbul-lib-coverage': 2.0.6
- convert-source-map: 2.0.0
-
valibot@1.0.0-rc.1(typescript@5.8.3):
optionalDependencies:
typescript: 5.8.3
@@ -30878,7 +28772,7 @@ snapshots:
'@types/unist': 3.0.3
vfile-message: 4.0.2
- vinxi@0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(rolldown@1.0.0-beta.43)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1):
+ vinxi@0.5.6(@planetscale/database@1.19.0)(@types/node@22.15.17)(db0@0.3.2(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(mysql2@3.15.2))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(ioredis@5.6.1)(jiti@2.6.1)(mysql2@3.15.2)(terser@5.44.0)(xml2js@0.6.2)(yaml@2.8.1):
dependencies:
'@babel/core': 7.27.1
'@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.1)
@@ -30900,7 +28794,7 @@ snapshots:
hookable: 5.5.3
http-proxy: 1.18.1
micromatch: 4.0.8
- nitropack: 2.11.11(@planetscale/database@1.19.0)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(mysql2@3.15.2)(rolldown@1.0.0-beta.43)(xml2js@0.6.2)
+ nitropack: 2.11.11(@planetscale/database@1.19.0)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20250507.0)(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(mysql2@3.15.2))(encoding@0.1.13)(mysql2@3.15.2)(xml2js@0.6.2)
node-fetch-native: 1.6.6
path-to-regexp: 6.3.0
pathe: 1.1.2
@@ -30991,7 +28885,7 @@ snapshots:
vite-tsconfig-paths@4.3.2(typescript@5.8.3)(vite@6.3.5(@types/node@20.17.43)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1)):
dependencies:
- debug: 4.4.0(supports-color@5.5.0)
+ debug: 4.4.0
globrex: 0.1.2
tsconfck: 3.1.5(typescript@5.8.3)
optionalDependencies:
@@ -31002,7 +28896,7 @@ snapshots:
vite-tsconfig-paths@5.1.4(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.17)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1)):
dependencies:
- debug: 4.4.0(supports-color@5.5.0)
+ debug: 4.4.0
globrex: 0.1.2
tsconfck: 3.1.5(typescript@5.8.3)
optionalDependencies:
@@ -31077,7 +28971,7 @@ snapshots:
'@vitest/spy': 2.1.9
'@vitest/utils': 2.1.9
chai: 5.2.0
- debug: 4.4.0(supports-color@5.5.0)
+ debug: 4.4.0
expect-type: 1.2.1
magic-string: 0.30.17
pathe: 1.1.2
@@ -31109,10 +29003,6 @@ snapshots:
walk-up-path@3.0.1: {}
- walker@1.0.8:
- dependencies:
- makeerror: 1.0.12
-
watchpack@2.4.4:
dependencies:
glob-to-regexp: 0.4.1
@@ -31239,10 +29129,6 @@ snapshots:
gopd: 1.2.0
has-tostringtag: 1.0.2
- which@1.3.1:
- dependencies:
- isexe: 2.0.0
-
which@2.0.2:
dependencies:
isexe: 2.0.0
@@ -31361,11 +29247,6 @@ snapshots:
wrappy@1.0.2: {}
- write-file-atomic@4.0.2:
- dependencies:
- imurmurhash: 0.1.4
- signal-exit: 3.0.7
-
write-file-atomic@5.0.1:
dependencies:
imurmurhash: 0.1.4
@@ -31426,7 +29307,8 @@ snapshots:
buffer-crc32: 0.2.13
fd-slicer: 1.1.0
- yn@3.1.1: {}
+ yn@3.1.1:
+ optional: true
yocto-queue@0.1.0: {}
From 6031aaf6566e97f9aa880815484971867d0f8847 Mon Sep 17 00:00:00 2001
From: Richie McIlroy <33632126+richiemcilroy@users.noreply.github.com>
Date: Thu, 6 Nov 2025 16:36:05 +0000
Subject: [PATCH 02/56] feat: picture in picture camera
---
.../WebRecorderDialog/CameraPreviewWindow.tsx | 85 ++++++++++++++++++-
1 file changed, 84 insertions(+), 1 deletion(-)
diff --git a/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/CameraPreviewWindow.tsx b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/CameraPreviewWindow.tsx
index a695943901..88de2a719e 100644
--- a/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/CameraPreviewWindow.tsx
+++ b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/CameraPreviewWindow.tsx
@@ -28,6 +28,7 @@ export const CameraPreviewWindow = ({
const containerRef = useRef(null);
const [videoDimensions, setVideoDimensions] = useState<{ width: number; height: number } | null>(null);
const [mounted, setMounted] = useState(false);
+ const pipAutoEnteredRef = useRef(false);
useEffect(() => {
setMounted(true);
@@ -157,6 +158,88 @@ export const CameraPreviewWindow = ({
}
}, [isDragging, handleMouseMove, handleMouseUp]);
+ const handleClose = useCallback(async () => {
+ if (videoRef.current && document.pictureInPictureElement === videoRef.current) {
+ try {
+ await document.exitPictureInPicture();
+ } catch (err) {
+ console.error("Failed to exit Picture-in-Picture", err);
+ }
+ }
+ onClose();
+ }, [onClose]);
+
+ useEffect(() => {
+ if (!videoRef.current || !videoDimensions) return;
+
+ const video = videoRef.current;
+
+ const enterPictureInPicture = async () => {
+ if (!video || !document.pictureInPictureEnabled) return;
+
+ const isAlreadyInPip = document.pictureInPictureElement === video;
+ if (isAlreadyInPip) return;
+
+ try {
+ await video.requestPictureInPicture();
+ pipAutoEnteredRef.current = true;
+ } catch (err) {
+ console.error("Failed to enter Picture-in-Picture", err);
+ }
+ };
+
+ const exitPictureInPicture = async () => {
+ if (!video || document.pictureInPictureElement !== video) return;
+
+ try {
+ await document.exitPictureInPicture();
+ pipAutoEnteredRef.current = false;
+ } catch (err) {
+ console.error("Failed to exit Picture-in-Picture", err);
+ }
+ };
+
+ const handleVisibilityChange = () => {
+ if (document.hidden) {
+ enterPictureInPicture();
+ } else if (pipAutoEnteredRef.current) {
+ exitPictureInPicture();
+ }
+ };
+
+ const handleWindowBlur = () => {
+ enterPictureInPicture();
+ };
+
+ const handleWindowFocus = () => {
+ if (pipAutoEnteredRef.current) {
+ exitPictureInPicture();
+ }
+ };
+
+ const handlePipEnter = () => {
+ pipAutoEnteredRef.current = true;
+ };
+
+ const handlePipLeave = () => {
+ pipAutoEnteredRef.current = false;
+ };
+
+ document.addEventListener("visibilitychange", handleVisibilityChange);
+ window.addEventListener("blur", handleWindowBlur);
+ window.addEventListener("focus", handleWindowFocus);
+ video.addEventListener("enterpictureinpicture", handlePipEnter);
+ video.addEventListener("leavepictureinpicture", handlePipLeave);
+
+ return () => {
+ document.removeEventListener("visibilitychange", handleVisibilityChange);
+ window.removeEventListener("blur", handleWindowBlur);
+ window.removeEventListener("focus", handleWindowFocus);
+ video.removeEventListener("enterpictureinpicture", handlePipEnter);
+ video.removeEventListener("leavepictureinpicture", handlePipLeave);
+ };
+ }, [videoDimensions]);
+
if (!mounted || !position) {
return null;
}
@@ -214,7 +297,7 @@ export const CameraPreviewWindow = ({
type="button"
onClick={(e) => {
e.stopPropagation();
- onClose();
+ handleClose();
}}
className="p-2 rounded-lg ui-pressed:bg-gray-3 ui-pressed:text-gray-12 hover:bg-gray-3 hover:text-gray-12"
>
From 1c83f8f7c76d520402f61d93a2ef667d42399c5a Mon Sep 17 00:00:00 2001
From: Richie McIlroy <33632126+richiemcilroy@users.noreply.github.com>
Date: Thu, 6 Nov 2025 17:08:10 +0000
Subject: [PATCH 03/56] feat: clear errors in web recorder files
---
.../dashboard/_components/Navbar/Items.tsx | 819 +++++++++---------
.../WebRecorderDialog/CameraPreviewWindow.tsx | 356 ++++----
.../WebRecorderDialog/CameraSelector.tsx | 71 +-
.../WebRecorderDialog/MicrophoneSelector.tsx | 71 +-
.../WebRecorderDialog/WebRecorderDialog.tsx | 16 +
5 files changed, 715 insertions(+), 618 deletions(-)
diff --git a/apps/web/app/(org)/dashboard/_components/Navbar/Items.tsx b/apps/web/app/(org)/dashboard/_components/Navbar/Items.tsx
index a7ad288067..d75c508dff 100644
--- a/apps/web/app/(org)/dashboard/_components/Navbar/Items.tsx
+++ b/apps/web/app/(org)/dashboard/_components/Navbar/Items.tsx
@@ -1,28 +1,28 @@
"use client";
import { buildEnv } from "@cap/env";
import {
- Avatar,
- Button,
- Command,
- CommandEmpty,
- CommandGroup,
- CommandInput,
- CommandItem,
- Dialog,
- DialogContent,
- DialogFooter,
- DialogHeader,
- DialogTitle,
- DialogTrigger,
- Popover,
- PopoverContent,
- PopoverTrigger,
+ Avatar,
+ Button,
+ Command,
+ CommandEmpty,
+ CommandGroup,
+ CommandInput,
+ CommandItem,
+ Dialog,
+ DialogContent,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+ Popover,
+ PopoverContent,
+ PopoverTrigger,
} from "@cap/ui";
import { classNames } from "@cap/utils";
import {
- faBuilding,
- faCircleInfo,
- faLink,
+ faBuilding,
+ faCircleInfo,
+ faLink,
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import clsx from "clsx";
@@ -43,410 +43,411 @@ import SpacesList from "./SpacesList";
import { updateActiveOrganization } from "./server";
interface Props {
- toggleMobileNav?: () => void;
+ toggleMobileNav?: () => void;
}
const AdminNavItems = ({ toggleMobileNav }: Props) => {
- const pathname = usePathname();
- const [open, setOpen] = useState(false);
- const { user, sidebarCollapsed, userCapsCount } = useDashboardContext();
+ const pathname = usePathname();
+ const [open, setOpen] = useState(false);
+ const { user, sidebarCollapsed, userCapsCount } = useDashboardContext();
- const manageNavigation = [
- {
- name: "My Caps",
- href: `/dashboard/caps`,
- extraText: userCapsCount,
- icon: ,
- subNav: [],
- },
- {
- name: "Organization Settings",
- href: `/dashboard/settings/organization`,
- ownerOnly: true,
- icon: ,
- subNav: [],
- },
- ];
+ const manageNavigation = [
+ {
+ name: "My Caps",
+ href: `/dashboard/caps`,
+ extraText: userCapsCount,
+ icon: ,
+ subNav: [],
+ },
+ {
+ name: "Organization Settings",
+ href: `/dashboard/settings/organization`,
+ ownerOnly: true,
+ icon: ,
+ subNav: [],
+ },
+ ];
- const [dialogOpen, setDialogOpen] = useState(false);
- const { organizationData: orgData, activeOrganization: activeOrg } =
- useDashboardContext();
- const formRef = useRef(null);
- const [createLoading, setCreateLoading] = useState(false);
- const [organizationName, setOrganizationName] = useState("");
- const isOwner = activeOrg?.organization.ownerId === user.id;
- const [openAIDialog, setOpenAIDialog] = useState(false);
- const router = useRouter();
+ const [dialogOpen, setDialogOpen] = useState(false);
+ const { organizationData: orgData, activeOrganization: activeOrg } =
+ useDashboardContext();
+ const formRef = useRef(null);
+ const [createLoading, setCreateLoading] = useState(false);
+ const [organizationName, setOrganizationName] = useState("");
+ const isOwner = activeOrg?.organization.ownerId === user.id;
+ const [openAIDialog, setOpenAIDialog] = useState(false);
+ const router = useRouter();
- const isPathActive = (path: string) => pathname.includes(path);
- const isDomainSetupVerified =
- activeOrg?.organization.customDomain &&
- activeOrg?.organization.domainVerified;
+ const isPathActive = (path: string) => pathname.includes(path);
+ const isDomainSetupVerified =
+ activeOrg?.organization.customDomain &&
+ activeOrg?.organization.domainVerified;
- return (
-
+ );
};
const NavItem = ({
- name,
- href,
- icon,
- sidebarCollapsed,
- toggleMobileNav,
- isPathActive,
- extraText,
+ name,
+ href,
+ icon,
+ sidebarCollapsed,
+ toggleMobileNav,
+ isPathActive,
+ extraText,
}: {
- name: string;
- href: string;
- icon: React.ReactElement<{
- ref: RefObject;
- className: string;
- size: number;
- }>;
- sidebarCollapsed: boolean;
- toggleMobileNav?: () => void;
- isPathActive: (path: string) => boolean;
- extraText: number | null | undefined;
+ name: string;
+ href: string;
+ icon: React.ReactElement<{
+ ref: RefObject;
+ className: string;
+ size: number;
+ }>;
+ sidebarCollapsed: boolean;
+ toggleMobileNav?: () => void;
+ isPathActive: (path: string) => boolean;
+ extraText: number | null | undefined;
}) => {
- const iconRef = useRef(null);
- return (
-
- toggleMobileNav?.()}
- onMouseEnter={() => {
- iconRef.current?.startAnimation();
- }}
- onMouseLeave={() => {
- iconRef.current?.stopAnimation();
- }}
- prefetch={false}
- passHref
- className={classNames(
- "relative border border-transparent transition z-3",
- sidebarCollapsed
- ? "flex justify-center items-center px-0 w-full size-9"
- : "px-3 py-2 w-full",
- isPathActive(href)
- ? "bg-transparent pointer-events-none"
- : "hover:bg-gray-2",
- "flex overflow-hidden justify-start items-center tracking-tight rounded-xl outline-none",
- )}
- >
- {cloneElement(icon, {
- ref: iconRef,
- className: clsx(
- sidebarCollapsed ? "text-gray-12 mx-auto" : "text-gray-10",
- ),
- size: sidebarCollapsed ? 18 : 16,
- })}
-
- {name}
-
- {extraText !== null && !sidebarCollapsed && (
-
- {extraText}
-
- )}
-
-
- );
+ const iconRef = useRef(null);
+ return (
+
+ toggleMobileNav?.()}
+ onMouseEnter={() => {
+ iconRef.current?.startAnimation();
+ }}
+ onMouseLeave={() => {
+ iconRef.current?.stopAnimation();
+ }}
+ prefetch={false}
+ passHref
+ className={classNames(
+ "relative border border-transparent transition z-3",
+ sidebarCollapsed
+ ? "flex justify-center items-center px-0 w-full size-9"
+ : "px-3 py-2 w-full",
+ isPathActive(href)
+ ? "bg-transparent pointer-events-none"
+ : "hover:bg-gray-2",
+ "flex overflow-hidden justify-start items-center tracking-tight rounded-xl outline-none"
+ )}
+ >
+ {cloneElement(icon, {
+ ref: iconRef,
+ className: clsx(
+ sidebarCollapsed ? "text-gray-12 mx-auto" : "text-gray-10"
+ ),
+ size: sidebarCollapsed ? 18 : 16,
+ })}
+
+ {name}
+
+ {extraText !== null && !sidebarCollapsed && (
+
+ {extraText}
+
+ )}
+
+
+ );
};
export default AdminNavItems;
diff --git a/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/CameraPreviewWindow.tsx b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/CameraPreviewWindow.tsx
index 88de2a719e..d815238837 100644
--- a/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/CameraPreviewWindow.tsx
+++ b/apps/web/app/(org)/dashboard/caps/components/WebRecorderDialog/CameraPreviewWindow.tsx
@@ -1,12 +1,71 @@
"use client";
-import { X, Maximize2, Circle, Square, RectangleHorizontal, FlipHorizontal } from "lucide-react";
+import {
+ X,
+ Maximize2,
+ Circle,
+ Square,
+ RectangleHorizontal,
+ FlipHorizontal,
+ PictureInPicture,
+} from "lucide-react";
import { useCallback, useEffect, useRef, useState } from "react";
import { createPortal } from "react-dom";
import clsx from "clsx";
type CameraPreviewSize = "sm" | "lg";
type CameraPreviewShape = "round" | "square" | "full";
+type VideoDimensions = {
+ width: number;
+ height: number;
+};
+
+const WINDOW_PADDING = 20;
+const BAR_HEIGHT = 52;
+
+const getPreviewMetrics = (
+ previewSize: CameraPreviewSize,
+ previewShape: CameraPreviewShape,
+ dimensions: VideoDimensions | null
+) => {
+ const base = previewSize === "sm" ? 230 : 400;
+
+ if (!dimensions || dimensions.height === 0) {
+ return {
+ base,
+ width: base,
+ height: base,
+ aspectRatio: 1,
+ };
+ }
+
+ const aspectRatio = dimensions.width / dimensions.height;
+
+ if (previewShape !== "full") {
+ return {
+ base,
+ width: base,
+ height: base,
+ aspectRatio,
+ };
+ }
+
+ if (aspectRatio >= 1) {
+ return {
+ base,
+ width: base * aspectRatio,
+ height: base,
+ aspectRatio,
+ };
+ }
+
+ return {
+ base,
+ width: base,
+ height: base / aspectRatio,
+ aspectRatio,
+ };
+};
interface CameraPreviewWindowProps {
cameraId: string;
@@ -20,15 +79,18 @@ export const CameraPreviewWindow = ({
const [size, setSize] = useState("sm");
const [shape, setShape] = useState("round");
const [mirrored, setMirrored] = useState(false);
- const [position, setPosition] = useState<{ x: number; y: number } | null>(null);
+ const [position, setPosition] = useState<{ x: number; y: number } | null>(
+ null
+ );
const [isDragging, setIsDragging] = useState(false);
const [dragStart, setDragStart] = useState({ x: 0, y: 0 });
const videoRef = useRef(null);
const streamRef = useRef(null);
const containerRef = useRef(null);
- const [videoDimensions, setVideoDimensions] = useState<{ width: number; height: number } | null>(null);
+ const [videoDimensions, setVideoDimensions] =
+ useState(null);
const [mounted, setMounted] = useState(false);
- const pipAutoEnteredRef = useRef(false);
+ const [isInPictureInPicture, setIsInPictureInPicture] = useState(false);
useEffect(() => {
setMounted(true);
@@ -47,23 +109,10 @@ export const CameraPreviewWindow = ({
});
streamRef.current = stream;
-
+
if (videoRef.current) {
videoRef.current.srcObject = stream;
}
-
- const calculateInitialPosition = () => {
- const padding = 20;
- const base = size === "sm" ? 230 : 400;
- const barHeight = 52;
- const windowWidth = base;
- const windowHeight = base + barHeight;
- const x = padding;
- const y = window.innerHeight - windowHeight - padding;
- setPosition({ x, y });
- };
-
- setTimeout(calculateInitialPosition, 100);
} catch (err) {
console.error("Failed to start camera", err);
}
@@ -73,75 +122,73 @@ export const CameraPreviewWindow = ({
return () => {
if (streamRef.current) {
- streamRef.current.getTracks().forEach((track) => track.stop());
+ streamRef.current.getTracks().forEach((track) => {
+ track.stop();
+ });
+ streamRef.current = null;
}
};
}, [cameraId]);
useEffect(() => {
- if (videoRef.current && streamRef.current && !videoRef.current.srcObject) {
- videoRef.current.srcObject = streamRef.current;
- }
- }, [position]);
-
- useEffect(() => {
- if (position) {
- const padding = 20;
- const base = size === "sm" ? 230 : 400;
- const barHeight = 52;
- const windowWidth = base;
- const windowHeight = base + barHeight;
-
- setPosition((prev) => {
- if (!prev) return { x: padding, y: window.innerHeight - windowHeight - padding };
- const maxX = window.innerWidth - windowWidth;
- const maxY = window.innerHeight - windowHeight;
- return {
- x: Math.max(0, Math.min(prev.x, maxX)),
- y: Math.max(0, Math.min(prev.y, maxY)),
- };
- });
- }
- }, [size]);
+ const metrics = getPreviewMetrics(size, shape, videoDimensions);
- const handleMouseDown = useCallback((e: React.MouseEvent) => {
- if ((e.target as HTMLElement).closest('[data-controls]')) {
+ if (typeof window === "undefined") {
return;
}
- e.stopPropagation();
- e.preventDefault();
- setIsDragging(true);
- setDragStart({
- x: e.clientX - (position?.x || 0),
- y: e.clientY - (position?.y || 0),
- });
- }, [position]);
-
- const handleMouseMove = useCallback((e: MouseEvent) => {
- if (!isDragging) return;
-
- const newX = e.clientX - dragStart.x;
- const newY = e.clientY - dragStart.y;
-
- const base = size === "sm" ? 230 : 400;
- const barHeight = 52;
- const aspectRatio = videoDimensions
- ? videoDimensions.width / videoDimensions.height
- : 1;
- const windowWidth =
- shape === "full" ? (aspectRatio >= 1 ? base * aspectRatio : base) : base;
- const windowHeight =
- shape === "full" ? (aspectRatio >= 1 ? base : base / aspectRatio) : base;
- const totalWidth = windowWidth;
- const totalHeight = windowHeight + barHeight;
- const maxX = window.innerWidth - totalWidth;
- const maxY = window.innerHeight - totalHeight;
-
- setPosition({
- x: Math.max(0, Math.min(newX, maxX)),
- y: Math.max(0, Math.min(newY, maxY)),
+
+ const totalHeight = metrics.height + BAR_HEIGHT;
+ const maxX = Math.max(0, window.innerWidth - metrics.width);
+ const maxY = Math.max(0, window.innerHeight - totalHeight);
+
+ setPosition((prev) => {
+ const defaultX = WINDOW_PADDING;
+ const defaultY = window.innerHeight - totalHeight - WINDOW_PADDING;
+ const nextX = prev?.x ?? defaultX;
+ const nextY = prev?.y ?? defaultY;
+
+ return {
+ x: Math.max(0, Math.min(nextX, maxX)),
+ y: Math.max(0, Math.min(nextY, maxY)),
+ };
});
- }, [isDragging, dragStart, size, shape, videoDimensions]);
+ }, [size, shape, videoDimensions]);
+
+ const handleMouseDown = useCallback(
+ (e: React.MouseEvent) => {
+ if ((e.target as HTMLElement).closest("[data-controls]")) {
+ return;
+ }
+ e.stopPropagation();
+ e.preventDefault();
+ setIsDragging(true);
+ setDragStart({
+ x: e.clientX - (position?.x || 0),
+ y: e.clientY - (position?.y || 0),
+ });
+ },
+ [position]
+ );
+
+ const handleMouseMove = useCallback(
+ (e: MouseEvent) => {
+ if (!isDragging) return;
+
+ const newX = e.clientX - dragStart.x;
+ const newY = e.clientY - dragStart.y;
+
+ const metrics = getPreviewMetrics(size, shape, videoDimensions);
+ const totalHeight = metrics.height + BAR_HEIGHT;
+ const maxX = Math.max(0, window.innerWidth - metrics.width);
+ const maxY = Math.max(0, window.innerHeight - totalHeight);
+
+ setPosition({
+ x: Math.max(0, Math.min(newX, maxX)),
+ y: Math.max(0, Math.min(newY, maxY)),
+ });
+ },
+ [isDragging, dragStart, size, shape, videoDimensions]
+ );
const handleMouseUp = useCallback(() => {
setIsDragging(false);
@@ -159,7 +206,10 @@ export const CameraPreviewWindow = ({
}, [isDragging, handleMouseMove, handleMouseUp]);
const handleClose = useCallback(async () => {
- if (videoRef.current && document.pictureInPictureElement === videoRef.current) {
+ if (
+ videoRef.current &&
+ document.pictureInPictureElement === videoRef.current
+ ) {
try {
await document.exitPictureInPicture();
} catch (err) {
@@ -169,72 +219,42 @@ export const CameraPreviewWindow = ({
onClose();
}, [onClose]);
- useEffect(() => {
- if (!videoRef.current || !videoDimensions) return;
-
+ const handleTogglePictureInPicture = useCallback(async () => {
const video = videoRef.current;
+ if (!video || !document.pictureInPictureEnabled) return;
- const enterPictureInPicture = async () => {
- if (!video || !document.pictureInPictureEnabled) return;
-
- const isAlreadyInPip = document.pictureInPictureElement === video;
- if (isAlreadyInPip) return;
-
- try {
- await video.requestPictureInPicture();
- pipAutoEnteredRef.current = true;
- } catch (err) {
- console.error("Failed to enter Picture-in-Picture", err);
- }
- };
-
- const exitPictureInPicture = async () => {
- if (!video || document.pictureInPictureElement !== video) return;
-
- try {
+ try {
+ if (document.pictureInPictureElement === video) {
await document.exitPictureInPicture();
- pipAutoEnteredRef.current = false;
- } catch (err) {
- console.error("Failed to exit Picture-in-Picture", err);
- }
- };
-
- const handleVisibilityChange = () => {
- if (document.hidden) {
- enterPictureInPicture();
- } else if (pipAutoEnteredRef.current) {
- exitPictureInPicture();
+ } else {
+ await video.requestPictureInPicture();
}
- };
+ } catch (err) {
+ console.error("Failed to toggle Picture-in-Picture", err);
+ }
+ }, []);
- const handleWindowBlur = () => {
- enterPictureInPicture();
- };
+ useEffect(() => {
+ if (!videoRef.current || !videoDimensions) return;
- const handleWindowFocus = () => {
- if (pipAutoEnteredRef.current) {
- exitPictureInPicture();
- }
- };
+ const video = videoRef.current;
const handlePipEnter = () => {
- pipAutoEnteredRef.current = true;
+ setIsInPictureInPicture(true);
};
const handlePipLeave = () => {
- pipAutoEnteredRef.current = false;
+ setIsInPictureInPicture(false);
};
- document.addEventListener("visibilitychange", handleVisibilityChange);
- window.addEventListener("blur", handleWindowBlur);
- window.addEventListener("focus", handleWindowFocus);
video.addEventListener("enterpictureinpicture", handlePipEnter);
video.addEventListener("leavepictureinpicture", handlePipLeave);
+ if (document.pictureInPictureElement === video) {
+ setIsInPictureInPicture(true);
+ }
+
return () => {
- document.removeEventListener("visibilitychange", handleVisibilityChange);
- window.removeEventListener("blur", handleWindowBlur);
- window.removeEventListener("focus", handleWindowFocus);
video.removeEventListener("enterpictureinpicture", handlePipEnter);
video.removeEventListener("leavepictureinpicture", handlePipLeave);
};
@@ -244,31 +264,22 @@ export const CameraPreviewWindow = ({
return null;
}
- const base = size === "sm" ? 230 : 400;
- const barHeight = 52;
- const aspectRatio = videoDimensions
- ? videoDimensions.width / videoDimensions.height
- : 1;
-
- const windowWidth =
- shape === "full" ? (aspectRatio >= 1 ? base * aspectRatio : base) : base;
- const windowHeight =
- shape === "full" ? (aspectRatio >= 1 ? base : base / aspectRatio) : base;
- const totalHeight = windowHeight + barHeight;
+ const metrics = getPreviewMetrics(size, shape, videoDimensions);
+ const totalHeight = metrics.height + BAR_HEIGHT;
const borderRadius =
shape === "round" ? "9999px" : size === "sm" ? "3rem" : "4rem";
-
return createPortal(
{
- e.stopPropagation();
- }}
>
e.stopPropagation()}
onClick={(e) => e.stopPropagation()}
+ onKeyDown={(e) => {
+ if (e.key === "Escape") {
+ e.stopPropagation();
+ handleClose();
+ }
+ }}
>
+ {document.pictureInPictureEnabled && (
+
+ )}
@@ -356,8 +389,8 @@ export const CameraPreviewWindow = ({
shape === "round" ? "rounded-full" : "rounded-3xl"
)}
style={{
- width: shape === "full" ? `${windowWidth}px` : `${base}px`,
- height: shape === "full" ? `${windowHeight}px` : `${base}px`,
+ width: `${metrics.width}px`,
+ height: `${metrics.height}px`,
}}
>