diff --git a/.gitignore b/.gitignore index ec8de31..535efe1 100644 --- a/.gitignore +++ b/.gitignore @@ -67,7 +67,6 @@ ehthumbs.db Thumbs.db # IDE files -.vscode/ .idea/ *.swp *.swo diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..d36c2c6 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + "recommendations": [ + "esbenp.prettier-vscode", + "dbaeumer.vscode-eslint", + "bradlc.vscode-tailwindcss" + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..e4901c6 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,34 @@ +{ + "eslint.workingDirectories": [ + { + "pattern": "./apps/*/" + }, + { + "pattern": "./packages/*/" + } + ], + "prettier.configPath": "./config/eslint-config/prettier.config.mjs", + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + }, + "[javascript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[javascriptreact]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[typescriptreact]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[json]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[jsonc]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + } +} \ No newline at end of file diff --git a/apps/widget-builder/eslint.config.js b/apps/widget-builder/eslint.config.js index ff71a9e..0e0dc06 100644 --- a/apps/widget-builder/eslint.config.js +++ b/apps/widget-builder/eslint.config.js @@ -1,3 +1,4 @@ -import { web } from "@widget-builder/eslint-config/web.mjs"; +import { react } from "@widget-builder/eslint-config/react.mjs"; +import { defineConfig } from "eslint/config"; -export default web; +export default defineConfig(react); diff --git a/apps/widget-builder/src/App.tsx b/apps/widget-builder/src/App.tsx index 0ed292f..8363769 100644 --- a/apps/widget-builder/src/App.tsx +++ b/apps/widget-builder/src/App.tsx @@ -1,9 +1,10 @@ -import { SidebarProvider, SidebarInset } from "@/components/ui/sidebar"; -import { AppSidebar } from "@/pages/layout"; import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom"; + +import { SidebarProvider, SidebarInset } from "@/components/ui/sidebar"; import { WidgetBuilder } from "@/pages/builder"; -import { WidgetGallery } from "@/pages/gallery"; import { WidgetComponents } from "@/pages/components"; +import { WidgetGallery } from "@/pages/gallery"; +import { AppSidebar } from "@/pages/layout"; function App() { return ( diff --git a/apps/widget-builder/src/components/ErrorBoundary/ErrorDisplay.tsx b/apps/widget-builder/src/components/ErrorBoundary/ErrorDisplay.tsx index edc5183..73bd18a 100644 --- a/apps/widget-builder/src/components/ErrorBoundary/ErrorDisplay.tsx +++ b/apps/widget-builder/src/components/ErrorBoundary/ErrorDisplay.tsx @@ -1,6 +1,7 @@ -import { Button } from "../ui/button"; import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"; +import { Button } from "../ui/button"; + export interface ErrorDisplayProps { error: Error; errorInfo: React.ErrorInfo | null; diff --git a/apps/widget-builder/src/components/JSONEditor/JSONEditor.tsx b/apps/widget-builder/src/components/JSONEditor/JSONEditor.tsx index d341db3..7cafba1 100644 --- a/apps/widget-builder/src/components/JSONEditor/JSONEditor.tsx +++ b/apps/widget-builder/src/components/JSONEditor/JSONEditor.tsx @@ -1,5 +1,6 @@ -import { useRef, useEffect } from "react"; import Editor, { OnMount } from "@monaco-editor/react"; +import { useRef, useEffect } from "react"; + import type { editor } from "monaco-editor"; interface JSONEditorProps { diff --git a/apps/widget-builder/src/components/ui/badge.tsx b/apps/widget-builder/src/components/ui/badge.tsx index fd3a406..12e8d18 100644 --- a/apps/widget-builder/src/components/ui/badge.tsx +++ b/apps/widget-builder/src/components/ui/badge.tsx @@ -1,46 +1,36 @@ -import * as React from "react" -import { Slot } from "@radix-ui/react-slot" -import { cva, type VariantProps } from "class-variance-authority" +import { Slot } from "@radix-ui/react-slot"; +import { cva, type VariantProps } from "class-variance-authority"; +import * as React from "react"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils"; const badgeVariants = cva( "inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden", { variants: { variant: { - default: - "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90", - secondary: - "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90", + default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90", + secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90", destructive: "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", - outline: - "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground", + outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground", }, }, defaultVariants: { variant: "default", }, } -) +); function Badge({ className, variant, asChild = false, ...props -}: React.ComponentProps<"span"> & - VariantProps & { asChild?: boolean }) { - const Comp = asChild ? Slot : "span" +}: React.ComponentProps<"span"> & VariantProps & { asChild?: boolean }) { + const Comp = asChild ? Slot : "span"; - return ( - - ) + return ; } -export { Badge, badgeVariants } +export { Badge, badgeVariants }; diff --git a/apps/widget-builder/src/components/ui/button.tsx b/apps/widget-builder/src/components/ui/button.tsx index 21409a0..f60ad93 100644 --- a/apps/widget-builder/src/components/ui/button.tsx +++ b/apps/widget-builder/src/components/ui/button.tsx @@ -1,8 +1,8 @@ -import * as React from "react" -import { Slot } from "@radix-ui/react-slot" -import { cva, type VariantProps } from "class-variance-authority" +import { Slot } from "@radix-ui/react-slot"; +import { cva, type VariantProps } from "class-variance-authority"; +import * as React from "react"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils"; const buttonVariants = cva( "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", @@ -14,10 +14,8 @@ const buttonVariants = cva( "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", - secondary: - "bg-secondary text-secondary-foreground hover:bg-secondary/80", - ghost: - "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", + secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", link: "text-primary underline-offset-4 hover:underline", }, size: { @@ -34,7 +32,7 @@ const buttonVariants = cva( size: "default", }, } -) +); function Button({ className, @@ -44,17 +42,11 @@ function Button({ ...props }: React.ComponentProps<"button"> & VariantProps & { - asChild?: boolean + asChild?: boolean; }) { - const Comp = asChild ? Slot : "button" + const Comp = asChild ? Slot : "button"; - return ( - - ) + return ; } -export { Button, buttonVariants } +export { Button, buttonVariants }; diff --git a/apps/widget-builder/src/components/ui/dialog.tsx b/apps/widget-builder/src/components/ui/dialog.tsx index c9048ce..d7fef8b 100644 --- a/apps/widget-builder/src/components/ui/dialog.tsx +++ b/apps/widget-builder/src/components/ui/dialog.tsx @@ -1,6 +1,6 @@ -import * as React from "react"; import * as DialogPrimitive from "@radix-ui/react-dialog"; import { X } from "lucide-react"; +import * as React from "react"; import { cn } from "@/lib/utils"; diff --git a/apps/widget-builder/src/components/ui/dropdown-menu.tsx b/apps/widget-builder/src/components/ui/dropdown-menu.tsx index fc790a8..80d9ab8 100644 --- a/apps/widget-builder/src/components/ui/dropdown-menu.tsx +++ b/apps/widget-builder/src/components/ui/dropdown-menu.tsx @@ -1,6 +1,6 @@ -import * as React from "react" import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" import { Check, ChevronRight, Circle } from "lucide-react" +import * as React from "react" import { cn } from "@/lib/utils" diff --git a/apps/widget-builder/src/components/ui/scroll-area.tsx b/apps/widget-builder/src/components/ui/scroll-area.tsx index 9376f59..76fd61e 100644 --- a/apps/widget-builder/src/components/ui/scroll-area.tsx +++ b/apps/widget-builder/src/components/ui/scroll-area.tsx @@ -1,5 +1,5 @@ -import * as React from "react" import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area" +import * as React from "react" import { cn } from "@/lib/utils" diff --git a/apps/widget-builder/src/components/ui/separator.tsx b/apps/widget-builder/src/components/ui/separator.tsx index bb3ad74..9c29252 100644 --- a/apps/widget-builder/src/components/ui/separator.tsx +++ b/apps/widget-builder/src/components/ui/separator.tsx @@ -1,5 +1,5 @@ -import * as React from "react" import * as SeparatorPrimitive from "@radix-ui/react-separator" +import * as React from "react" import { cn } from "@/lib/utils" diff --git a/apps/widget-builder/src/components/ui/sheet.tsx b/apps/widget-builder/src/components/ui/sheet.tsx index 84649ad..558f7f8 100644 --- a/apps/widget-builder/src/components/ui/sheet.tsx +++ b/apps/widget-builder/src/components/ui/sheet.tsx @@ -1,8 +1,8 @@ "use client" -import * as React from "react" import * as SheetPrimitive from "@radix-ui/react-dialog" import { XIcon } from "lucide-react" +import * as React from "react" import { cn } from "@/lib/utils" diff --git a/apps/widget-builder/src/components/ui/sidebar.tsx b/apps/widget-builder/src/components/ui/sidebar.tsx index d276538..3e06564 100644 --- a/apps/widget-builder/src/components/ui/sidebar.tsx +++ b/apps/widget-builder/src/components/ui/sidebar.tsx @@ -1,12 +1,10 @@ "use client"; -import * as React from "react"; import { Slot } from "@radix-ui/react-slot"; import { cva, type VariantProps } from "class-variance-authority"; import { PanelLeft } from "lucide-react"; +import * as React from "react"; -import { useIsMobile } from "@/hooks/use-mobile"; -import { cn } from "@/lib/utils"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Separator } from "@/components/ui/separator"; @@ -24,6 +22,8 @@ import { TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip"; +import { useIsMobile } from "@/hooks/use-mobile"; +import { cn } from "@/lib/utils"; const SIDEBAR_COOKIE_NAME = "sidebar_state"; const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7; diff --git a/apps/widget-builder/src/components/ui/tabs.tsx b/apps/widget-builder/src/components/ui/tabs.tsx index 3d6f3ac..a02715b 100644 --- a/apps/widget-builder/src/components/ui/tabs.tsx +++ b/apps/widget-builder/src/components/ui/tabs.tsx @@ -1,5 +1,5 @@ -import * as React from "react" import * as TabsPrimitive from "@radix-ui/react-tabs" +import * as React from "react" import { cn } from "@/lib/utils" diff --git a/apps/widget-builder/src/components/ui/tooltip.tsx b/apps/widget-builder/src/components/ui/tooltip.tsx index 715bf76..3c33337 100644 --- a/apps/widget-builder/src/components/ui/tooltip.tsx +++ b/apps/widget-builder/src/components/ui/tooltip.tsx @@ -1,5 +1,5 @@ -import * as React from "react" import * as TooltipPrimitive from "@radix-ui/react-tooltip" +import * as React from "react" import { cn } from "@/lib/utils" diff --git a/apps/widget-builder/src/components/widget-components/badge.tsx b/apps/widget-builder/src/components/widget-components/badge.tsx index 2203d4e..12d9234 100644 --- a/apps/widget-builder/src/components/widget-components/badge.tsx +++ b/apps/widget-builder/src/components/widget-components/badge.tsx @@ -1,7 +1,8 @@ -import React from "react"; -import { cn } from "@/lib/utils"; import { cva, type VariantProps } from "class-variance-authority"; import { ComponentDefinition } from "monaco-jsx-editor"; +import React from "react"; + +import { cn } from "@/lib/utils"; const Base = cva( "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", diff --git a/apps/widget-builder/src/components/widget-components/box.tsx b/apps/widget-builder/src/components/widget-components/box.tsx index dafd617..73a66dd 100644 --- a/apps/widget-builder/src/components/widget-components/box.tsx +++ b/apps/widget-builder/src/components/widget-components/box.tsx @@ -1,7 +1,9 @@ +import { ComponentDefinition } from "monaco-jsx-editor"; import React from "react"; + import { cn } from "@/lib/utils"; + import { Background, Border, variants, Padding, Radius, VariantsProps, Size } from "./variants"; -import { ComponentDefinition } from "monaco-jsx-editor"; const Variants = variants({ size: Size, diff --git a/apps/widget-builder/src/components/widget-components/button.tsx b/apps/widget-builder/src/components/widget-components/button.tsx index bcc4342..333d7fe 100644 --- a/apps/widget-builder/src/components/widget-components/button.tsx +++ b/apps/widget-builder/src/components/widget-components/button.tsx @@ -1,4 +1,5 @@ import { ComponentDefinition } from "monaco-jsx-editor"; + import { Button } from "../ui/button"; const ButtonDefinition: ComponentDefinition = { diff --git a/apps/widget-builder/src/components/widget-components/caption.tsx b/apps/widget-builder/src/components/widget-components/caption.tsx index fb84e57..cd70aa7 100644 --- a/apps/widget-builder/src/components/widget-components/caption.tsx +++ b/apps/widget-builder/src/components/widget-components/caption.tsx @@ -1,5 +1,7 @@ import React from "react"; + import { cn } from "@/lib/utils"; + import { variants, FontSize, FontWeight, TextAlign, TextColor, Truncate, VariantsProps } from "./variants"; const Variants = variants({ diff --git a/apps/widget-builder/src/components/widget-components/card.tsx b/apps/widget-builder/src/components/widget-components/card.tsx index d10c018..26c8ec2 100644 --- a/apps/widget-builder/src/components/widget-components/card.tsx +++ b/apps/widget-builder/src/components/widget-components/card.tsx @@ -1,8 +1,11 @@ +import { cva, VariantProps } from "class-variance-authority"; +import { ComponentDefinition } from "monaco-jsx-editor"; import React from "react"; + import { cn } from "@/lib/utils"; -import { cva, VariantProps } from "class-variance-authority"; + import { Background, Border, variants, Padding, Radius, VariantsProps, Width } from "./variants"; -import { ComponentDefinition } from "monaco-jsx-editor"; + const Base = cva("rounded-2xl border bg-card text-card-foreground shadow p-4", { variants: { diff --git a/apps/widget-builder/src/components/widget-components/col.tsx b/apps/widget-builder/src/components/widget-components/col.tsx index e2875ef..ed46191 100644 --- a/apps/widget-builder/src/components/widget-components/col.tsx +++ b/apps/widget-builder/src/components/widget-components/col.tsx @@ -1,6 +1,9 @@ +import { cva } from "class-variance-authority"; +import { ComponentDefinition } from "monaco-jsx-editor"; import React from "react"; + import { cn } from "@/lib/utils"; -import { cva } from "class-variance-authority"; + import { Background, Border, @@ -13,7 +16,6 @@ import { MinWidth, MinHeight, } from "./variants"; -import { ComponentDefinition } from "monaco-jsx-editor"; const Base = cva("flex flex-col", { variants: {}, diff --git a/apps/widget-builder/src/components/widget-components/divider.tsx b/apps/widget-builder/src/components/widget-components/divider.tsx index a763480..ff9b5be 100644 --- a/apps/widget-builder/src/components/widget-components/divider.tsx +++ b/apps/widget-builder/src/components/widget-components/divider.tsx @@ -1,8 +1,10 @@ +import { ComponentDefinition } from "monaco-jsx-editor"; import React from "react"; + +import { Separator } from "@/components/ui/separator"; import { cn } from "@/lib/utils"; + import { BorderColor, variants, VariantsProps } from "./variants"; -import { ComponentDefinition } from "monaco-jsx-editor"; -import { Separator } from "@/components/ui/separator"; const Variants = variants({ color: BorderColor, diff --git a/apps/widget-builder/src/components/widget-components/image.tsx b/apps/widget-builder/src/components/widget-components/image.tsx index 32335b8..e974409 100644 --- a/apps/widget-builder/src/components/widget-components/image.tsx +++ b/apps/widget-builder/src/components/widget-components/image.tsx @@ -1,8 +1,11 @@ +import { cva, type VariantProps } from "class-variance-authority"; +import { ComponentDefinition } from "monaco-jsx-editor"; import React from "react"; + import { cn } from "@/lib/utils"; -import { cva, type VariantProps } from "class-variance-authority"; + import { variants, Margin, Radius, Size, VariantsProps } from "./variants"; -import { ComponentDefinition } from "monaco-jsx-editor"; + const Base = cva("object-cover", { variants: { diff --git a/apps/widget-builder/src/components/widget-components/index.ts b/apps/widget-builder/src/components/widget-components/index.ts index 91771ae..63869ab 100644 --- a/apps/widget-builder/src/components/widget-components/index.ts +++ b/apps/widget-builder/src/components/widget-components/index.ts @@ -1,28 +1,22 @@ +import { ComponentDefinition } from "monaco-jsx-editor"; import React from "react"; + +import { Badge, BadgeDefinition } from "./badge"; import { Box, BoxDefinition } from "./box"; -import { Row, RowDefinition } from "./row"; -import { Col, ColDefinition } from "./col"; -import { - Card, - CardHeader, - CardFooter, - CardTitle, - CardDescription, - CardContent, - CardDefinition, -} from "./card"; -import { Text, TextDefinition } from "./text"; -import { Title, TitleDefinition } from "./title"; +import { Button, ButtonDefinition } from "./button"; import { Caption, CaptionDefinition } from "./caption"; +import { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent, CardDefinition } from "./card"; +import { Col, ColDefinition } from "./col"; import { Divider, DividerDefinition } from "./divider"; -import { Badge, BadgeDefinition } from "./badge"; import { Image, ImageDefinition } from "./image"; import { Progress, ProgressDefinition } from "./progress"; -import { ComponentDefinition } from "monaco-jsx-editor"; -import { Button, ButtonDefinition } from "./button"; +import { Row, RowDefinition } from "./row"; import { Spacer, SpacerDefinition } from "./spacer"; +import { Text, TextDefinition } from "./text"; +import { Title, TitleDefinition } from "./title"; // Component map type for widget renderer +// eslint-disable-next-line @typescript-eslint/no-explicit-any export type ComponentMap = Record>; // Component mapping for JSXSchema tag names to actual components diff --git a/apps/widget-builder/src/components/widget-components/progress.tsx b/apps/widget-builder/src/components/widget-components/progress.tsx index 2aa10d3..c1ebfbf 100644 --- a/apps/widget-builder/src/components/widget-components/progress.tsx +++ b/apps/widget-builder/src/components/widget-components/progress.tsx @@ -1,7 +1,8 @@ -import React from "react"; -import { cn } from "@/lib/utils"; import { cva, type VariantProps } from "class-variance-authority"; import { ComponentDefinition } from "monaco-jsx-editor"; +import React from "react"; + +import { cn } from "@/lib/utils"; const ProgressBase = cva("relative overflow-hidden rounded-full bg-secondary", { variants: { diff --git a/apps/widget-builder/src/components/widget-components/row.tsx b/apps/widget-builder/src/components/widget-components/row.tsx index d237925..bb57469 100644 --- a/apps/widget-builder/src/components/widget-components/row.tsx +++ b/apps/widget-builder/src/components/widget-components/row.tsx @@ -1,6 +1,9 @@ +import { cva } from "class-variance-authority"; +import { ComponentDefinition } from "monaco-jsx-editor"; import React from "react"; + import { cn } from "@/lib/utils"; -import { cva } from "class-variance-authority"; + import { Background, Border, @@ -15,7 +18,7 @@ import { Height, Size, } from "./variants"; -import { ComponentDefinition } from "monaco-jsx-editor"; + const Base = cva("flex flex-row mt-4", { variants: {}, diff --git a/apps/widget-builder/src/components/widget-components/spacer.tsx b/apps/widget-builder/src/components/widget-components/spacer.tsx index fa35ff9..86200c8 100644 --- a/apps/widget-builder/src/components/widget-components/spacer.tsx +++ b/apps/widget-builder/src/components/widget-components/spacer.tsx @@ -1,7 +1,9 @@ -import React from "react"; -import { cn } from "@/lib/utils"; import { cva, type VariantProps } from "class-variance-authority"; import { ComponentDefinition } from "monaco-jsx-editor"; +import React from "react"; + +import { cn } from "@/lib/utils"; + import { Height, MinHeight, MinWidth, variants, VariantsProps, Width } from "./variants"; const Base = cva("flex-1", { diff --git a/apps/widget-builder/src/components/widget-components/text.tsx b/apps/widget-builder/src/components/widget-components/text.tsx index 6269522..30c1816 100644 --- a/apps/widget-builder/src/components/widget-components/text.tsx +++ b/apps/widget-builder/src/components/widget-components/text.tsx @@ -1,7 +1,9 @@ -import React from "react"; -import { cn } from "@/lib/utils"; import { cva, type VariantProps } from "class-variance-authority"; import { ComponentDefinition } from "monaco-jsx-editor"; +import React from "react"; + +import { cn } from "@/lib/utils"; + import { FontSize, FontWeight, Truncate, variants, VariantsProps } from "./variants"; const Base = cva("text-foreground", { @@ -33,9 +35,16 @@ export interface TextProps } const Text = React.forwardRef( - ({ className, variant, as: Component = "span", size, weight, truncate, ...props }, ref) => { + ({ className, variant, as: Component = "span", style, size, weight, truncate, ...props }, ref) => { const [variantClasses, variantStyles] = Variants.format({ size, weight, truncate }); - return ; + return ( + + ); } ); Text.displayName = "Text"; diff --git a/apps/widget-builder/src/components/widget-components/title.tsx b/apps/widget-builder/src/components/widget-components/title.tsx index 4459113..c225c0f 100644 --- a/apps/widget-builder/src/components/widget-components/title.tsx +++ b/apps/widget-builder/src/components/widget-components/title.tsx @@ -1,7 +1,8 @@ -import React from "react"; -import { cn } from "@/lib/utils"; import { cva, type VariantProps } from "class-variance-authority"; import { ComponentDefinition } from "monaco-jsx-editor"; +import React from "react"; + +import { cn } from "@/lib/utils"; const Base = cva("font-semibold text-foreground", { variants: { diff --git a/apps/widget-builder/src/components/widget-components/variants/flex.ts b/apps/widget-builder/src/components/widget-components/variants/flex.ts index 9b50716..a0b15ab 100644 --- a/apps/widget-builder/src/components/widget-components/variants/flex.ts +++ b/apps/widget-builder/src/components/widget-components/variants/flex.ts @@ -20,7 +20,7 @@ export const Align = { format: (align: AlignProps["align"]): string => { if (align === undefined) return ""; - if (Align.variant.hasOwnProperty(align)) { + if (align in Align.variant) { return Align.variant[align as keyof typeof Align.variant]; } @@ -53,7 +53,7 @@ export const Justify = { format: (justify: JustifyProps["justify"]): string => { if (justify === undefined) return ""; - if (Justify.variant.hasOwnProperty(justify)) { + if (justify in Justify.variant) { return Justify.variant[justify as keyof typeof Justify.variant]; } @@ -82,7 +82,7 @@ export const Wrap = { format: (wrap: WrapProps["wrap"]): string => { if (wrap === undefined) return ""; - if (Wrap.variant.hasOwnProperty(wrap)) { + if (wrap in Wrap.variant) { return Wrap.variant[wrap as keyof typeof Wrap.variant]; } @@ -116,7 +116,7 @@ export const Flex = { } if (typeof flex === "string") { - if (Flex.variant.hasOwnProperty(flex)) { + if (flex in Flex.variant) { return `flex-${Flex.variant[flex as keyof typeof Flex.variant]}`; } if (!isNaN(Number(flex))) { diff --git a/apps/widget-builder/src/components/widget-components/variants/index.ts b/apps/widget-builder/src/components/widget-components/variants/index.ts index e7425fb..8d4404f 100644 --- a/apps/widget-builder/src/components/widget-components/variants/index.ts +++ b/apps/widget-builder/src/components/widget-components/variants/index.ts @@ -1,4 +1,5 @@ import { ComponentProp } from "monaco-jsx-editor"; + import { Variant } from "./types"; // Re-export all variant maps @@ -33,10 +34,15 @@ export function variants>( }) => readonly [string, React.CSSProperties]; } { // Merge all variant maps - const variants = Object.keys(variantMaps).reduce((acc, key) => { - acc[key] = variantMaps[key].variant; - return acc; - }, {} as any); + const variants = Object.keys(variantMaps).reduce( + (acc, key) => { + return { + ...acc, + [key]: variantMaps[key].variant, + }; + }, + {} as { [K in keyof T]: T[K]["variant"] } + ); // Merge all definitions const definitions = Object.keys(variantMaps).reduce((acc, key) => { @@ -48,7 +54,7 @@ export function variants>( }, [] as ComponentProp[]); // Create combined format function - const format = (values: any) => { + const format = (values: Record) => { const classNames: string[] = []; const styles: React.CSSProperties = {}; @@ -76,6 +82,7 @@ export function variants>( * Utility type to extract format parameter type from combine result */ export type VariantsProps = T extends { + // eslint-disable-next-line @typescript-eslint/no-explicit-any format: (values: infer P) => any; } ? P diff --git a/apps/widget-builder/src/components/widget-components/variants/types.ts b/apps/widget-builder/src/components/widget-components/variants/types.ts index 2098786..1ceaf42 100644 --- a/apps/widget-builder/src/components/widget-components/variants/types.ts +++ b/apps/widget-builder/src/components/widget-components/variants/types.ts @@ -1,6 +1,6 @@ import { ComponentProp } from "monaco-jsx-editor"; -export type Variant = { +export type Variant = { variant: Record; definition: ComponentProp; format: (value: T) => string | [string, React.CSSProperties]; diff --git a/apps/widget-builder/src/hooks/use-widgets.ts b/apps/widget-builder/src/hooks/use-widgets.ts index b76a670..48079f6 100644 --- a/apps/widget-builder/src/hooks/use-widgets.ts +++ b/apps/widget-builder/src/hooks/use-widgets.ts @@ -1,5 +1,6 @@ -import { useSyncExternalStore, useCallback } from "react"; import { Widget } from "@deer-flow/widget"; +import { useSyncExternalStore, useCallback } from "react"; + import { widgetsStore } from "@/store/widgets-store"; export const defaultWidgetTemplate: Omit = { diff --git a/apps/widget-builder/src/lib/download.ts b/apps/widget-builder/src/lib/download.ts index 6a45dc8..6143793 100644 --- a/apps/widget-builder/src/lib/download.ts +++ b/apps/widget-builder/src/lib/download.ts @@ -30,7 +30,7 @@ export function download(content: string, filename: string, mimeType: string = " * @param data - 要下载的数据对象 * @param filename - 下载的文件名 */ -export function downloadJSON(data: any, filename: string): void { +export function downloadJSON(data: unknown, filename: string): void { const jsonString = JSON.stringify(data, null, 2); download(jsonString, filename, "application/json"); } diff --git a/apps/widget-builder/src/main.tsx b/apps/widget-builder/src/main.tsx index 9b67590..9a877a4 100644 --- a/apps/widget-builder/src/main.tsx +++ b/apps/widget-builder/src/main.tsx @@ -1,5 +1,6 @@ import React from "react"; import ReactDOM from "react-dom/client"; + import App from "./App"; import "./index.css"; diff --git a/apps/widget-builder/src/pages/builder/WidgetBuilder.tsx b/apps/widget-builder/src/pages/builder/WidgetBuilder.tsx index be39cd3..0a168da 100644 --- a/apps/widget-builder/src/pages/builder/WidgetBuilder.tsx +++ b/apps/widget-builder/src/pages/builder/WidgetBuilder.tsx @@ -1,17 +1,18 @@ +import { inferDataSchemaFromState, parseJSXTemplate } from "@deer-flow/widget"; +import { WidgetRenderer } from "@deer-flow/widget-renderer"; +import { Download, PlusIcon } from "lucide-react"; +import { JSXEditor } from "monaco-jsx-editor"; import { useEffect, useState } from "react"; import { useParams, useNavigate } from "react-router-dom"; -import { JSXEditor } from "monaco-jsx-editor"; -import { WidgetRenderer } from "@deer-flow/widget-renderer"; + +import { ErrorBoundary } from "@/components/ErrorBoundary"; import { JSONEditor } from "@/components/JSONEditor"; -import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs"; import { Button } from "@/components/ui/button"; -import { Download, PlusIcon } from "lucide-react"; +import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs"; import { definitions, components } from "@/components/widget-components"; -import { inferDataSchemaFromState, parseJSXTemplate } from "@deer-flow/widget"; -import { ErrorBoundary } from "@/components/ErrorBoundary"; -import { clone } from "@/lib/utils"; -import { download } from "@/lib/download"; import { useWidgets, defaultWidgetTemplate } from "@/hooks/use-widgets"; +import { download } from "@/lib/download"; +import { clone } from "@/lib/utils"; export const WidgetBuilder = () => { const { id } = useParams<{ id?: string }>(); @@ -73,7 +74,7 @@ export const WidgetBuilder = () => { data, }; updateWidget(currentWidget.id, { states }); - } catch (error) { + } catch { // Invalid JSON, ignore or show error } }; diff --git a/apps/widget-builder/src/pages/components/WidgetComponents.tsx b/apps/widget-builder/src/pages/components/WidgetComponents.tsx index f9595bc..dd9fd60 100644 --- a/apps/widget-builder/src/pages/components/WidgetComponents.tsx +++ b/apps/widget-builder/src/pages/components/WidgetComponents.tsx @@ -1,20 +1,17 @@ -import React from "react"; -import { useParams, Link } from "react-router-dom"; -import { components, definitions } from "@/components/widget-components"; -import { ScrollArea } from "@/components/ui/scroll-area"; -import { Badge } from "@/components/ui/badge"; - -import { ComponentDefinition, ComponentProp } from "monaco-jsx-editor"; -import { cn } from "@/lib/utils"; import { parseJSXTemplate } from "@deer-flow/widget"; import { WidgetRenderer } from "@deer-flow/widget-renderer"; -import { Editor } from "@monaco-editor/react"; +import { ComponentDefinition, ComponentProp } from "monaco-jsx-editor"; +import React from "react"; +import { useParams, Link } from "react-router-dom"; import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; import { atomDark } from "react-syntax-highlighter/dist/esm/styles/prism"; -interface WidgetComponentsProps {} +import { Badge } from "@/components/ui/badge"; +import { ScrollArea } from "@/components/ui/scroll-area"; +import { components, definitions } from "@/components/widget-components"; +import { cn } from "@/lib/utils"; -export function WidgetComponents({}: WidgetComponentsProps) { +export function WidgetComponents() { const { name } = useParams<{ name: string }>(); // Find the selected component definition diff --git a/apps/widget-builder/src/pages/layout/AppSidebar.tsx b/apps/widget-builder/src/pages/layout/AppSidebar.tsx index 2cc77a1..42e9ea2 100644 --- a/apps/widget-builder/src/pages/layout/AppSidebar.tsx +++ b/apps/widget-builder/src/pages/layout/AppSidebar.tsx @@ -1,4 +1,6 @@ import { LayoutTemplate, PlusCircleIcon, Package } from "lucide-react"; +import { Link } from "react-router-dom"; + import { Sidebar, SidebarContent, @@ -9,8 +11,8 @@ import { SidebarMenuButton, SidebarMenuItem, } from "@/components/ui/sidebar"; + import { MyWidgets } from "./MyWidgets"; -import { Link } from "react-router-dom"; export function AppSidebar() { return ( diff --git a/apps/widget-builder/src/pages/layout/MyWidgets.tsx b/apps/widget-builder/src/pages/layout/MyWidgets.tsx index 5aa3a5e..2dd9fda 100644 --- a/apps/widget-builder/src/pages/layout/MyWidgets.tsx +++ b/apps/widget-builder/src/pages/layout/MyWidgets.tsx @@ -1,19 +1,8 @@ -import { - SidebarGroup, - SidebarGroupLabel, - SidebarGroupContent, - SidebarMenu, - SidebarMenuItem, - SidebarMenuButton, - SidebarMenuAction, -} from "@/components/ui/sidebar"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu"; +import { MoreHorizontal, Edit, Trash2 } from "lucide-react"; +import { useState } from "react"; +import { Link, useNavigate } from "react-router-dom"; + +import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, @@ -22,12 +11,24 @@ import { DialogHeader, DialogTitle, } from "@/components/ui/dialog"; -import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; import { Input } from "@/components/ui/input"; +import { + SidebarGroup, + SidebarGroupLabel, + SidebarGroupContent, + SidebarMenu, + SidebarMenuItem, + SidebarMenuButton, + SidebarMenuAction, +} from "@/components/ui/sidebar"; import { useWidgets } from "@/hooks/use-widgets"; -import { Link, useParams, useNavigate } from "react-router-dom"; -import { MoreHorizontal, Edit, Trash2 } from "lucide-react"; -import { useState } from "react"; export const MyWidgets = () => { const { currentWidget, widgets, updateWidget, deleteWidget } = useWidgets(); diff --git a/apps/widget-builder/vite.config.ts b/apps/widget-builder/vite.config.ts index 851efd7..51675c3 100644 --- a/apps/widget-builder/vite.config.ts +++ b/apps/widget-builder/vite.config.ts @@ -1,8 +1,10 @@ -import { defineConfig } from "vite"; -import react from "@vitejs/plugin-react"; -import tailwindcss from "@tailwindcss/vite"; import path from "path"; +import tailwindcss from "@tailwindcss/vite"; +import react from "@vitejs/plugin-react"; +import { defineConfig } from "vite"; + + // https://vitejs.dev/config/ export default defineConfig({ base: process.env.NODE_ENV === "production" ? "/widget-builder/" : "/", diff --git a/config/eslint-config/base.mjs b/config/eslint-config/base.mjs new file mode 100644 index 0000000..df45bc0 --- /dev/null +++ b/config/eslint-config/base.mjs @@ -0,0 +1,56 @@ +import json from "@eslint/json"; +import importX from "eslint-plugin-import-x"; +import tseslint from "typescript-eslint"; + +export const base = [ + { + ignores: ["**/build/**", "**/dist/**"], + }, + tseslint.configs.recommended, + { + plugins: { + json, + }, + }, + { + files: ["**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"], + plugins: { + "import-x": importX, + }, + settings: { + "import-x/resolver": { + typescript: true, + node: true, + }, + }, + rules: { + "import-x/order": [ + "error", + { + groups: [ + "builtin", // Built-in Node.js modules are first + "external", // External libraries + "internal", // Internal modules (aliased with @/) + ["parent", "sibling"], // Relative imports (../ and ./) + "index", // index imports + "object", + "type", // Type imports + ], + pathGroups: [ + { + pattern: "@/**", + group: "internal", + position: "before", + }, + ], + pathGroupsExcludedImportTypes: ["builtin"], + "newlines-between": "always", + alphabetize: { + order: "asc", + caseInsensitive: true, + }, + }, + ], + }, + }, +]; diff --git a/config/eslint-config/eslint.config.mjs b/config/eslint-config/eslint.config.mjs index 768a219..45c1d9f 100644 --- a/config/eslint-config/eslint.config.mjs +++ b/config/eslint-config/eslint.config.mjs @@ -1,4 +1,5 @@ import { defineConfig } from "eslint/config"; -import { web } from "./web.mjs"; -export default defineConfig([...web]); +import { base } from "./base.mjs"; + +export default defineConfig(base); diff --git a/config/eslint-config/package.json b/config/eslint-config/package.json index ff49ea0..867f2f3 100644 --- a/config/eslint-config/package.json +++ b/config/eslint-config/package.json @@ -7,6 +7,8 @@ "@eslint/json": "^0.14.0", "@widget-builder/ts-config": "workspace:*", "eslint": "~9.39.1", + "eslint-import-resolver-typescript": "^4.4.4", + "eslint-plugin-import-x": "^4.16.1", "eslint-plugin-react": "^7.37.5", "globals": "^16.5.0", "jiti": "^2.6.1", diff --git a/config/eslint-config/react.mjs b/config/eslint-config/react.mjs new file mode 100644 index 0000000..3fda3a0 --- /dev/null +++ b/config/eslint-config/react.mjs @@ -0,0 +1,28 @@ +import pluginReact from "eslint-plugin-react"; + +import { base } from "./base.mjs"; + +export const react = [ + ...base, + { + files: ["**/*.{jsx,tsx}"], + ...pluginReact.configs.flat.recommended, + languageOptions: { + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + }, + settings: { + react: { + version: "detect", + }, + }, + rules: { + ...pluginReact.configs.flat.recommended.rules, + "react/react-in-jsx-scope": "off", // React 17+ 不需要导入React + "react/jsx-uses-react": "off", // React 17+ 不需要导入React + }, + }, +]; diff --git a/config/eslint-config/web.mjs b/config/eslint-config/web.mjs deleted file mode 100644 index 0d57897..0000000 --- a/config/eslint-config/web.mjs +++ /dev/null @@ -1,21 +0,0 @@ -import js from "@eslint/js"; -import json from "@eslint/json"; -import globals from "globals"; -import tseslint from "typescript-eslint"; -import pluginReact from "eslint-plugin-react"; - -export const web = [ - { - files: ["**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"], - ...js.configs.recommended, - languageOptions: { - globals: globals.browser, - }, - }, - { - files: ["**/*.json", "**/*.jsonc", "**/*.json5"], - ...json.configs.recommended, - }, - ...tseslint.configs.recommended, - pluginReact.configs.flat.recommended, -]; diff --git a/config/ts-config/web.json b/config/ts-config/web.json index 1229925..0aa7e51 100644 --- a/config/ts-config/web.json +++ b/config/ts-config/web.json @@ -1,5 +1,4 @@ { - "$schema": "http://json.schemastore.org/tsconfig", "extends": "./base.json", "compilerOptions": { "jsx": "preserve", diff --git a/packages/monaco-jsx-editor/eslint.config.js b/packages/monaco-jsx-editor/eslint.config.js index 27216a3..0e0dc06 100644 --- a/packages/monaco-jsx-editor/eslint.config.js +++ b/packages/monaco-jsx-editor/eslint.config.js @@ -1,26 +1,4 @@ -import { web } from "@widget-builder/eslint-config/web.mjs"; +import { react } from "@widget-builder/eslint-config/react.mjs"; +import { defineConfig } from "eslint/config"; -export default [ - ...web, - { - files: ["**/*.{js,jsx,ts,tsx}"], - languageOptions: { - parserOptions: { - ecmaFeatures: { - jsx: true, - }, - }, - }, - settings: { - react: { - version: "detect", - }, - }, - rules: { - "react/react-in-jsx-scope": "off", // Not needed in React 17+ - }, - }, - { - ignores: ["dist/", "node_modules/", "**/*.json", "**/*.jsonc"], - }, -]; +export default defineConfig(react); diff --git a/packages/monaco-jsx-editor/examples/index.tsx b/packages/monaco-jsx-editor/examples/index.tsx index 9a6c0d6..d54a1bb 100644 --- a/packages/monaco-jsx-editor/examples/index.tsx +++ b/packages/monaco-jsx-editor/examples/index.tsx @@ -1,8 +1,10 @@ -import { Editor, EditorProps } from "@monaco-editor/react"; +import { Editor } from "@monaco-editor/react"; +import { JSONSchema4 } from "json-schema"; +import { createRoot } from "react-dom/client"; + import { JSXLanguage } from "../src"; import { exampleComponents } from "./component-types"; -import { createRoot } from "react-dom/client"; -import { JSONSchema4 } from "json-schema"; + const dataSchema: JSONSchema4 = { type: "object", diff --git a/packages/monaco-jsx-editor/src/components/useJSXLanguage.ts b/packages/monaco-jsx-editor/src/components/useJSXLanguage.ts index 25bb0bc..bcf0dbd 100644 --- a/packages/monaco-jsx-editor/src/components/useJSXLanguage.ts +++ b/packages/monaco-jsx-editor/src/components/useJSXLanguage.ts @@ -1,4 +1,5 @@ import { useEffect, useRef } from "react"; + import { JSXLanguage, JSXLanguageOptions } from "../jsx"; export function useJSXLanguage(options: JSXLanguageOptions) { diff --git a/packages/monaco-jsx-editor/src/jsx/JSXLanguage.ts b/packages/monaco-jsx-editor/src/jsx/JSXLanguage.ts index 41c3eba..0e938fb 100644 --- a/packages/monaco-jsx-editor/src/jsx/JSXLanguage.ts +++ b/packages/monaco-jsx-editor/src/jsx/JSXLanguage.ts @@ -1,18 +1,18 @@ +import { JSONSchema4 } from "json-schema"; import * as Monaco from "monaco-editor"; import { getWorker, MonacoJsxSyntaxHighlight } from "monaco-jsx-syntax-highlight"; -import { JSONSchema4 } from "json-schema"; import { ComponentDefinition } from "../types"; import { generateComponentTypes } from "./ComponentTypes"; -import { ReactTypes } from "./ReactTypes"; import { generateDataTypes } from "./DataTypes"; +import { ReactTypes } from "./ReactTypes"; export type JSXLanguageOptions = { components?: ComponentDefinition[]; dataSchema?: JSONSchema4; allowedHTMLElements?: string[]; disableAllHTMLElements?: boolean; // if true, no HTML elements are allowed - setupCompilerOptions?: (monaco: typeof Monaco) => Monaco.languages.typescript.CompilerOptions; + setupCompilerOptions?: (_monaco: typeof Monaco) => Monaco.languages.typescript.CompilerOptions; }; export class JSXLanguage { @@ -61,9 +61,9 @@ export class JSXLanguage { if (this.dataTypesDisposable) { this.dataTypesDisposable.dispose(); } - // if (this.jsxCompletionDisposable) { - // this.jsxCompletionDisposable.dispose(); - // } + if (this.jsxCompletionDisposable) { + this.jsxCompletionDisposable.dispose(); + } this.jsxHighlighter = null; }); diff --git a/packages/monaco-jsx-editor/src/types/Component.ts b/packages/monaco-jsx-editor/src/types/Component.ts index 158cdb7..2a0acac 100644 --- a/packages/monaco-jsx-editor/src/types/Component.ts +++ b/packages/monaco-jsx-editor/src/types/Component.ts @@ -3,7 +3,7 @@ export interface ComponentProp { type: string; required?: boolean; description?: string; - defaultValue?: any; + defaultValue?: unknown; } export interface ComponentDefinition { diff --git a/packages/monaco-jsx-editor/vite.config.ts b/packages/monaco-jsx-editor/vite.config.ts index 5b2707a..540a41e 100644 --- a/packages/monaco-jsx-editor/vite.config.ts +++ b/packages/monaco-jsx-editor/vite.config.ts @@ -1,5 +1,5 @@ -import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; +import { defineConfig } from "vite"; // https://vite.dev/config/ export default defineConfig({ diff --git a/packages/widget-renderer/eslint.config.js b/packages/widget-renderer/eslint.config.js new file mode 100644 index 0000000..0e0dc06 --- /dev/null +++ b/packages/widget-renderer/eslint.config.js @@ -0,0 +1,4 @@ +import { react } from "@widget-builder/eslint-config/react.mjs"; +import { defineConfig } from "eslint/config"; + +export default defineConfig(react); diff --git a/packages/widget-renderer/src/WidgetRenderer.tsx b/packages/widget-renderer/src/WidgetRenderer.tsx index 955f961..3429a3f 100644 --- a/packages/widget-renderer/src/WidgetRenderer.tsx +++ b/packages/widget-renderer/src/WidgetRenderer.tsx @@ -5,11 +5,11 @@ import { ComponentType } from "react"; export type WidgetRendererProps = { schema?: JSXElementSchema; components: Record>; - data?: object; + data?: Record; }; // Helper to resolve expression values from data context -function resolveValue(value: any, data: Record): any { +function resolveValue(value: JSXElementSchema["value"], data: Record): unknown { if (typeof value === "object" && value !== null && value.__expression) { const expression = value.__expression; try { @@ -22,11 +22,7 @@ function resolveValue(value: any, data: Record): any { return value; } -export function WidgetRenderer({ - schema, - components, - data, -}: WidgetRendererProps): React.ReactElement | null { +export function WidgetRenderer({ schema, components, data }: WidgetRendererProps): React.ReactElement | null { if (!schema) { return null; } @@ -49,12 +45,12 @@ export function WidgetRenderer({ // Resolve component from the map, or fall back to a string for native HTML elements const Component = components[schema.name] || schema.name; - const props: Record = {}; + const props: Record = {}; if (schema.props) { for (const key in schema.props) { if (Object.prototype.hasOwnProperty.call(schema.props, key)) { // Resolve prop values, which might be expressions - props[key] = resolveValue(schema.props[key], data ?? {}); + props[key] = resolveValue(schema.props[key] as JSXElementSchema["value"], data ?? {}); } } } @@ -62,12 +58,7 @@ export function WidgetRenderer({ // Recursively render children const children = schema.children ? schema.children.map((child, index) => ( - + )) : undefined; diff --git a/packages/widget/eslint.config.js b/packages/widget/eslint.config.js new file mode 100644 index 0000000..0e0dc06 --- /dev/null +++ b/packages/widget/eslint.config.js @@ -0,0 +1,4 @@ +import { react } from "@widget-builder/eslint-config/react.mjs"; +import { defineConfig } from "eslint/config"; + +export default defineConfig(react); diff --git a/packages/widget/src/Expression.ts b/packages/widget/src/Expression.ts index 7dbce4c..3d50044 100644 --- a/packages/widget/src/Expression.ts +++ b/packages/widget/src/Expression.ts @@ -1,7 +1,7 @@ /** * Create a simple sandbox environment to execute expressions */ -function createSandbox(data: Record) { +function createSandbox(data: Record) { // Create a safe globals object const safeGlobals = { // Basic JavaScript constructors and objects @@ -28,7 +28,7 @@ function createSandbox(data: Record) { /** * Execute expression within sandbox */ -export function executeExpression(expression: string, data: Record): any { +export function executeExpression(expression: string, data: Record): unknown { try { // Create sandbox environment const sandbox = createSandbox(data); diff --git a/packages/widget/src/JSXSchema.ts b/packages/widget/src/JSXSchema.ts index cf55a33..d7923ef 100644 --- a/packages/widget/src/JSXSchema.ts +++ b/packages/widget/src/JSXSchema.ts @@ -4,7 +4,7 @@ import * as t from "@babel/types"; export interface JSXElementSchema { type: "element" | "text" | "expression"; name?: string; // Component name - props?: Record; // Component props + props?: Record; // Component props children?: JSXElementSchema[]; // Child elements value?: string | number | boolean | { __expression: string }; // For text/expression nodes position?: { @@ -62,9 +62,7 @@ class BabelJSXParser { } catch (error) { return { success: false, - errors: [ - error instanceof Error ? error.message : "Unknown parsing error", - ], + errors: [error instanceof Error ? error.message : "Unknown parsing error"], }; } } @@ -72,7 +70,7 @@ class BabelJSXParser { private findJSXElement(ast: t.File): t.JSXElement | t.JSXFragment | null { let jsxElement: t.JSXElement | t.JSXFragment | null = null; - const visitor = (node: any) => { + const visitor = (node: t.Node) => { if (t.isJSXElement(node) || t.isJSXFragment(node)) { if (!jsxElement) { jsxElement = node; @@ -82,11 +80,15 @@ class BabelJSXParser { // Recursively visit child nodes for (const key of Object.keys(node)) { - const child = node[key]; + const child = node[key as keyof typeof node]; if (child && typeof child === "object") { if (Array.isArray(child)) { - child.forEach(visitor); - } else if (child.type) { + child.forEach((c) => { + if (t.isNode(c)) { + visitor(c); + } + }); + } else if (t.isNode(child)) { visitor(child); } } @@ -98,12 +100,7 @@ class BabelJSXParser { } private convertToSchema( - node: - | t.JSXElement - | t.JSXFragment - | t.JSXText - | t.JSXExpressionContainer - | any + node: t.JSXFragment | t.JSXText | t.JSXExpressionContainer | t.JSXSpreadChild | t.JSXElement ): JSXElementSchema { if (t.isJSXElement(node)) { return this.convertJSXElement(node); @@ -163,15 +160,10 @@ class BabelJSXParser { }; } - private convertJSXExpression( - expression: t.JSXExpressionContainer - ): JSXElementSchema { + private convertJSXExpression(expression: t.JSXExpressionContainer): JSXElementSchema { let expressionCode = ""; - if ( - expression.expression && - !t.isJSXEmptyExpression(expression.expression) - ) { + if (expression.expression && !t.isJSXEmptyExpression(expression.expression)) { // Extract the expression code from the original input const start = expression.expression.start || 0; const end = expression.expression.end || 0; @@ -185,9 +177,7 @@ class BabelJSXParser { }; } - private getElementName( - name: t.JSXIdentifier | t.JSXMemberExpression | t.JSXNamespacedName - ): string { + private getElementName(name: t.JSXIdentifier | t.JSXMemberExpression | t.JSXNamespacedName): string { if (t.isJSXIdentifier(name)) { return name.name; } else if (t.isJSXMemberExpression(name)) { @@ -198,10 +188,8 @@ class BabelJSXParser { return "Unknown"; } - private convertProps( - attributes: Array - ): Record { - const props: Record = {}; + private convertProps(attributes: Array): Record { + const props: Record = {}; for (const attr of attributes) { if (t.isJSXAttribute(attr)) { @@ -213,10 +201,7 @@ class BabelJSXParser { } else if (t.isStringLiteral(attr.value)) { props[name] = attr.value.value; } else if (t.isJSXExpressionContainer(attr.value)) { - if ( - attr.value.expression && - !t.isJSXEmptyExpression(attr.value.expression) - ) { + if (attr.value.expression && !t.isJSXEmptyExpression(attr.value.expression)) { const start = attr.value.expression.start || 0; const end = attr.value.expression.end || 0; const expressionCode = this.input.slice(start, end); @@ -237,7 +222,7 @@ class BabelJSXParser { return props; } - private getNodePosition(node: any): { + private getNodePosition(node: t.Node): { start: number; end: number; line: number; @@ -263,10 +248,7 @@ export function parseJSXTemplate(template: string): ParseResult { /** * Convert JSX schema back to JSX string (for debugging/visualization) */ -export function schemaToJSX( - schema: JSXElementSchema, - indent: number = 0 -): string { +export function schemaToJSX(schema: JSXElementSchema, indent: number = 0): string { const spacing = " ".repeat(indent); if (schema.type === "text") { @@ -314,12 +296,9 @@ export function schemaToJSX( return `<${name}${propsWithSpace} />`; } - const childrenStr = children - .map((child) => schemaToJSX(child, indent + 1)) - .join(""); + const childrenStr = children.map((child) => schemaToJSX(child, indent + 1)).join(""); - const hasTextOnlyChild = - children.length === 1 && children[0].type === "text"; + const hasTextOnlyChild = children.length === 1 && children[0].type === "text"; if (hasTextOnlyChild) { return `<${name}${propsWithSpace}>${childrenStr}`; diff --git a/packages/widget/src/StateUtils.ts b/packages/widget/src/StateUtils.ts index 91bf13f..c77a87b 100644 --- a/packages/widget/src/StateUtils.ts +++ b/packages/widget/src/StateUtils.ts @@ -1,4 +1,5 @@ -import { JSONSchema4, JSONSchema4TypeName } from "json-schema"; +import { JSONSchema4, JSONSchema4Type, JSONSchema4TypeName } from "json-schema"; + import { WidgetState } from "./Widget"; /** @@ -46,7 +47,7 @@ export function inferDataSchemaFromState(states: WidgetState[]): JSONSchema4 { return schema; } -function inferObjectsSchema(states: object[], defaults?: object): JSONSchema4 { +function inferObjectsSchema(states: Record[], defaults?: Record): JSONSchema4 { const properties: JSONSchema4["properties"] = {}; const required: string[] = []; const schema: JSONSchema4 = { type: "object", properties, required }; @@ -64,8 +65,8 @@ function inferObjectsSchema(states: object[], defaults?: object): JSONSchema4 { }); keys.forEach((key) => { - const values = validStates.map((state) => (state as any)[key]); - const allHaveKey = validStates.every((state) => (state as any).hasOwnProperty(key)); + const values = validStates.map((state) => state[key]); + const allHaveKey = validStates.every((state) => Object.prototype.hasOwnProperty.call(state, key)); if (allHaveKey) { required.push(key); } @@ -73,7 +74,7 @@ function inferObjectsSchema(states: object[], defaults?: object): JSONSchema4 { // Infer type const types = new Set(); const objectValues: WidgetState[] = []; - const arrayValues: any[][] = []; + const arrayValues: unknown[][] = []; values.forEach((value) => { const valueType = Array.isArray(value) ? "array" : typeof value; if ( @@ -90,7 +91,7 @@ function inferObjectsSchema(states: object[], defaults?: object): JSONSchema4 { } if (valueType === "array") { - arrayValues.push(value as any[]); + arrayValues.push(value as unknown[]); } else if (valueType === "object" && value !== null) { objectValues.push(value as WidgetState); } @@ -98,13 +99,13 @@ function inferObjectsSchema(states: object[], defaults?: object): JSONSchema4 { if (objectValues.length === 0 && arrayValues.length === 0 && types.size > 0) { const propertySchema: JSONSchema4 = { type: Array.from(types) }; - if (defaults && (defaults as any).hasOwnProperty(key)) { - propertySchema.default = (defaults as any)[key]; + if (defaults && Object.prototype.hasOwnProperty.call(defaults, key)) { + propertySchema.default = defaults[key] as JSONSchema4Type; } properties[key] = propertySchema; } else if (objectValues.length > 0) { // Complex type - object - const objectSchema = inferObjectsSchema(objectValues, (defaults as any)?.[key]); + const objectSchema = inferObjectsSchema(objectValues, defaults?.[key] as Record); properties[key] = types.size > 1 ? { @@ -119,8 +120,8 @@ function inferObjectsSchema(states: object[], defaults?: object): JSONSchema4 { } else if (arrayValues.length > 0) { // Complex type - array const arraySchema: JSONSchema4 = { type: "array" }; - if (defaults && (defaults as any).hasOwnProperty(key)) { - arraySchema.default = (defaults as any)[key]; + if (defaults && Object.prototype.hasOwnProperty.call(defaults, key)) { + arraySchema.default = defaults[key] as JSONSchema4Type; } properties[key] = arraySchema; } diff --git a/packages/widget/src/Widget.ts b/packages/widget/src/Widget.ts index ba12dff..d80db4b 100644 --- a/packages/widget/src/Widget.ts +++ b/packages/widget/src/Widget.ts @@ -27,5 +27,5 @@ export interface Widget { export type WidgetState = { name: string; - data: object; + data: Record; }; diff --git a/packages/widget/src/__tests__/Expression.test.ts b/packages/widget/src/__tests__/Expression.test.ts index 080e9a6..bd9b1c0 100644 --- a/packages/widget/src/__tests__/Expression.test.ts +++ b/packages/widget/src/__tests__/Expression.test.ts @@ -1,4 +1,5 @@ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; + import { executeExpression } from "../Expression"; describe("executeExpression", () => { diff --git a/packages/widget/src/__tests__/StateUtils.test.ts b/packages/widget/src/__tests__/StateUtils.test.ts index a16d72d..80e0256 100644 --- a/packages/widget/src/__tests__/StateUtils.test.ts +++ b/packages/widget/src/__tests__/StateUtils.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from "vitest"; -import { JSONSchema4 } from "json-schema"; + import { inferDataSchemaFromState } from "../StateUtils"; import { WidgetState } from "../Widget"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7439b9a..0b60a03 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -141,6 +141,12 @@ importers: eslint: specifier: ~9.39.1 version: 9.39.1(jiti@2.6.1) + eslint-import-resolver-typescript: + specifier: ^4.4.4 + version: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)) + eslint-plugin-import-x: + specifier: ^4.16.1 + version: 4.16.1(@typescript-eslint/utils@8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)) eslint-plugin-react: specifier: ^7.37.5 version: 7.37.5(eslint@9.39.1(jiti@2.6.1)) @@ -390,6 +396,15 @@ packages: resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} engines: {node: '>=6.9.0'} + '@emnapi/core@1.7.0': + resolution: {integrity: sha512-pJdKGq/1iquWYtv1RRSljZklxHCOCAJFJrImO5ZLKPJVJlVUcs8yFwNQlqS0Lo8xT1VAXXTCZocF9n26FWEKsw==} + + '@emnapi/runtime@1.7.0': + resolution: {integrity: sha512-oAYoQnCYaQZKVS53Fq23ceWMRxq5EhQsE0x0RdQ55jT7wagMu5k+fS39v1fiSLrtrLQlXwVINenqhLMtTrV/1Q==} + + '@emnapi/wasi-threads@1.1.0': + resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + '@esbuild/aix-ppc64@0.25.12': resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} engines: {node: '>=18'} @@ -649,6 +664,9 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + '@napi-rs/wasm-runtime@0.2.12': + resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -1249,6 +1267,9 @@ packages: peerDependencies: vite: ^5.2.0 || ^6 || ^7 + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -1361,6 +1382,101 @@ packages: resolution: {integrity: sha512-uk574k8IU0rOF/AjniX8qbLSGURJVUCeM5e4MIMKBFFi8weeiLrG1fyQejyLXQpRZbU/1BuQasleV/RfHC3hHg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} + cpu: [arm] + os: [android] + + '@unrs/resolver-binding-android-arm64@1.11.1': + resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} + cpu: [arm64] + os: [android] + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.11.1': + resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} + cpu: [ppc64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} + cpu: [s390x] + os: [linux] + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} + cpu: [x64] + os: [win32] + '@vitejs/plugin-react@5.1.0': resolution: {integrity: sha512-4LuWrg7EKWgQaMJfnN+wcmbAW+VSsCmqGohftWjuct47bv8uE4n/nPpq4XjJPsxgq00GGG5J8dvBczp8uxScew==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1546,6 +1662,10 @@ packages: resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} engines: {node: '>=18'} + comment-parser@1.4.1: + resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} + engines: {node: '>= 12.0.0'} + commondir@1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} @@ -1685,6 +1805,41 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + eslint-import-context@0.1.9: + resolution: {integrity: sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + peerDependencies: + unrs-resolver: ^1.0.0 + peerDependenciesMeta: + unrs-resolver: + optional: true + + eslint-import-resolver-typescript@4.4.4: + resolution: {integrity: sha512-1iM2zeBvrYmUNTj2vSC/90JTHDth+dfOfiNKkxApWRsTJYNrc8rOdxxIf5vazX+BiAXTeOT0UvWpGI/7qIWQOw==} + engines: {node: ^16.17.0 || >=18.6.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + + eslint-plugin-import-x@4.16.1: + resolution: {integrity: sha512-vPZZsiOKaBAIATpFE2uMI4w5IRwdv/FpQ+qZZMR4E+PeOcM4OeoEbqxRMnywdxP19TyB/3h6QBB0EWon7letSQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/utils': ^8.0.0 + eslint: ^8.57.0 || ^9.0.0 + eslint-import-resolver-node: '*' + peerDependenciesMeta: + '@typescript-eslint/utils': + optional: true + eslint-import-resolver-node: + optional: true + eslint-plugin-react@7.37.5: resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} engines: {node: '>=4'} @@ -1854,6 +2009,9 @@ packages: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} + get-tsconfig@4.13.0: + resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} + gh-pages@6.3.0: resolution: {integrity: sha512-Ot5lU6jK0Eb+sszG8pciXdjMXdBJ5wODvgjR+imihTqsUWF2K6dJ9HST55lgqcs8wWcw6o6wAsUzfcYRhJPXbA==} engines: {node: '>=10'} @@ -1974,6 +2132,9 @@ packages: resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} engines: {node: '>= 0.4'} + is-bun-module@2.0.0: + resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} + is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} @@ -2264,6 +2425,11 @@ packages: engines: {node: ^18 || >=20} hasBin: true + napi-postinstall@0.3.4: + resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -2484,6 +2650,9 @@ packages: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve@2.0.0-next.5: resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} hasBin: true @@ -2577,6 +2746,10 @@ packages: space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + stable-hash-x@0.2.0: + resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} + engines: {node: '>=12.0.0'} + stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} @@ -2749,6 +2922,9 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} + unrs-resolver@1.11.1: + resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + update-browserslist-db@1.1.4: resolution: {integrity: sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==} hasBin: true @@ -3005,6 +3181,22 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 + '@emnapi/core@1.7.0': + dependencies: + '@emnapi/wasi-threads': 1.1.0 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.7.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.1.0': + dependencies: + tslib: 2.8.1 + optional: true + '@esbuild/aix-ppc64@0.25.12': optional: true @@ -3196,6 +3388,13 @@ snapshots: react: 19.2.0 react-dom: 19.2.0(react@19.2.0) + '@napi-rs/wasm-runtime@0.2.12': + dependencies: + '@emnapi/core': 1.7.0 + '@emnapi/runtime': 1.7.0 + '@tybys/wasm-util': 0.10.1 + optional: true + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -3713,6 +3912,11 @@ snapshots: tailwindcss: 4.1.16 vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.2) + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.28.5 @@ -3868,6 +4072,65 @@ snapshots: '@typescript-eslint/types': 8.46.3 eslint-visitor-keys: 4.2.1 + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + optional: true + + '@unrs/resolver-binding-android-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + dependencies: + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + optional: true + '@vitejs/plugin-react@5.1.0(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.2))': dependencies: '@babel/core': 7.28.5 @@ -4098,6 +4361,8 @@ snapshots: commander@13.1.0: {} + comment-parser@1.4.1: {} + commondir@1.0.1: {} concat-map@0.0.1: {} @@ -4321,6 +4586,45 @@ snapshots: escape-string-regexp@4.0.0: {} + eslint-import-context@0.1.9(unrs-resolver@1.11.1): + dependencies: + get-tsconfig: 4.13.0 + stable-hash-x: 0.2.0 + optionalDependencies: + unrs-resolver: 1.11.1 + + eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)): + dependencies: + debug: 4.4.3 + eslint: 9.39.1(jiti@2.6.1) + eslint-import-context: 0.1.9(unrs-resolver@1.11.1) + get-tsconfig: 4.13.0 + is-bun-module: 2.0.0 + stable-hash-x: 0.2.0 + tinyglobby: 0.2.15 + unrs-resolver: 1.11.1 + optionalDependencies: + eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)) + transitivePeerDependencies: + - supports-color + + eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)): + dependencies: + '@typescript-eslint/types': 8.46.3 + comment-parser: 1.4.1 + debug: 4.4.3 + eslint: 9.39.1(jiti@2.6.1) + eslint-import-context: 0.1.9(unrs-resolver@1.11.1) + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.3 + stable-hash-x: 0.2.0 + unrs-resolver: 1.11.1 + optionalDependencies: + '@typescript-eslint/utils': 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + transitivePeerDependencies: + - supports-color + eslint-plugin-react@7.37.5(eslint@9.39.1(jiti@2.6.1)): dependencies: array-includes: 3.1.9 @@ -4540,6 +4844,10 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 + get-tsconfig@4.13.0: + dependencies: + resolve-pkg-maps: 1.0.0 + gh-pages@6.3.0: dependencies: async: 3.2.6 @@ -4667,6 +4975,10 @@ snapshots: call-bound: 1.0.4 has-tostringtag: 1.0.2 + is-bun-module@2.0.0: + dependencies: + semver: 7.7.3 + is-callable@1.2.7: {} is-core-module@2.16.1: @@ -4925,6 +5237,8 @@ snapshots: nanoid@5.1.6: {} + napi-postinstall@0.3.4: {} + natural-compare@1.4.0: {} node-releases@2.0.27: {} @@ -5149,6 +5463,8 @@ snapshots: resolve-from@4.0.0: {} + resolve-pkg-maps@1.0.0: {} + resolve@2.0.0-next.5: dependencies: is-core-module: 2.16.1 @@ -5280,6 +5596,8 @@ snapshots: space-separated-tokens@2.0.2: {} + stable-hash-x@0.2.0: {} + stackback@0.0.2: {} state-local@1.0.7: {} @@ -5470,6 +5788,30 @@ snapshots: universalify@2.0.1: {} + unrs-resolver@1.11.1: + dependencies: + napi-postinstall: 0.3.4 + optionalDependencies: + '@unrs/resolver-binding-android-arm-eabi': 1.11.1 + '@unrs/resolver-binding-android-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-x64': 1.11.1 + '@unrs/resolver-binding-freebsd-x64': 1.11.1 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 + '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-musl': 1.11.1 + '@unrs/resolver-binding-wasm32-wasi': 1.11.1 + '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 + '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 + '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 + update-browserslist-db@1.1.4(browserslist@4.27.0): dependencies: browserslist: 4.27.0