diff --git a/.changeset/update-oxlint-and-fixes.md b/.changeset/update-oxlint-and-fixes.md new file mode 100644 index 00000000..d02d3826 --- /dev/null +++ b/.changeset/update-oxlint-and-fixes.md @@ -0,0 +1,5 @@ +--- +"@openworkflowspec/diagram-editor": patch +--- + +Update oxlint and apply fixes diff --git a/packages/open-workflow-diagram-editor/src/components/ui/sidebar.tsx b/packages/open-workflow-diagram-editor/src/components/ui/sidebar.tsx index 52b6fdd5..f931cd97 100644 --- a/packages/open-workflow-diagram-editor/src/components/ui/sidebar.tsx +++ b/packages/open-workflow-diagram-editor/src/components/ui/sidebar.tsx @@ -533,6 +533,7 @@ function SidebarMenuSkeleton({ }) { // Random width between 50 to 90%. const width = React.useMemo(() => { + // oxlint-disable-next-line react/purity return `${Math.floor(Math.random() * 40) + 50}%`; }, []); diff --git a/packages/open-workflow-diagram-editor/src/components/ui/tooltip.tsx b/packages/open-workflow-diagram-editor/src/components/ui/tooltip.tsx index 25e8920e..fa5434b6 100644 --- a/packages/open-workflow-diagram-editor/src/components/ui/tooltip.tsx +++ b/packages/open-workflow-diagram-editor/src/components/ui/tooltip.tsx @@ -48,6 +48,7 @@ function TooltipContent({ }: React.ComponentProps) { const [container, setContainer] = React.useState(); React.useEffect(() => { + // oxlint-disable-next-line react/set-state-in-effect setContainer(document.querySelector(".dec-root") ?? undefined); }, []); return ( diff --git a/packages/open-workflow-diagram-editor/src/hooks/useResolvedColorMode.ts b/packages/open-workflow-diagram-editor/src/hooks/useResolvedColorMode.ts index 1e633744..5973f8ac 100644 --- a/packages/open-workflow-diagram-editor/src/hooks/useResolvedColorMode.ts +++ b/packages/open-workflow-diagram-editor/src/hooks/useResolvedColorMode.ts @@ -14,47 +14,58 @@ * limitations under the License. */ -import { useEffect, useState } from "react"; +import { useCallback, useSyncExternalStore } from "react"; import { ColorMode, ResolvedColorMode } from "../types/colorMode"; const DARK_MEDIA_QUERY = "(prefers-color-scheme: dark)"; function normalizeColorMode(colorMode: string): ColorMode { - return colorMode === "light" || colorMode === "dark" || colorMode === "system" ? colorMode : "system"; + return colorMode === "light" || colorMode === "dark" || colorMode === "system" + ? colorMode + : "system"; } -function getSystemColorMode(): ResolvedColorMode { +function getMediaQueryList(): MediaQueryList | null { if (typeof window !== "undefined" && typeof window.matchMedia === "function") { - return window.matchMedia(DARK_MEDIA_QUERY).matches ? "dark" : "light"; + return window.matchMedia(DARK_MEDIA_QUERY); } - return "light"; // Default to light + return null; } -export function useResolvedColorMode(colorMode: ColorMode): ResolvedColorMode { - const normalized = normalizeColorMode(colorMode); +function getSystemColorMode(): ResolvedColorMode { + return getMediaQueryList()?.matches ? "dark" : "light"; +} - const [resolvedColorMode, setResolvedColorMode] = useState( - normalized === "system" ? getSystemColorMode() : normalized, - ); +function getServerColorMode(): ResolvedColorMode { + return "light"; +} - useEffect(() => { - if (normalized !== "system") { - setResolvedColorMode(normalized); - return; - } +function noopUnsubscribe(): void {} - setResolvedColorMode(getSystemColorMode()); +export function useResolvedColorMode(colorMode: ColorMode): ResolvedColorMode { + const normalized = normalizeColorMode(colorMode); - const mediaQuery = window.matchMedia(DARK_MEDIA_QUERY); - const handler = (e: MediaQueryListEvent) => { - setResolvedColorMode(e.matches ? "dark" : "light"); - }; - mediaQuery.addEventListener("change", handler); + const subscribe = useCallback( + (onStoreChanges: () => void) => { + if (normalized !== "system") { + return noopUnsubscribe; + } - return () => { - mediaQuery.removeEventListener("change", handler); - }; - }, [normalized]); + const mediaQuery = getMediaQueryList(); + if (mediaQuery == null) { + return noopUnsubscribe; + } + mediaQuery.addEventListener("change", onStoreChanges); + return () => { + mediaQuery.removeEventListener("change", onStoreChanges); + }; + }, + [normalized], + ); - return resolvedColorMode; + return useSyncExternalStore( + subscribe, + () => (normalized === "system" ? getSystemColorMode() : normalized), + () => (normalized === "system" ? getServerColorMode() : normalized), + ); } diff --git a/packages/open-workflow-diagram-editor/src/react-flow/diagram/Diagram.tsx b/packages/open-workflow-diagram-editor/src/react-flow/diagram/Diagram.tsx index f45fc687..524fca6a 100644 --- a/packages/open-workflow-diagram-editor/src/react-flow/diagram/Diagram.tsx +++ b/packages/open-workflow-diagram-editor/src/react-flow/diagram/Diagram.tsx @@ -74,20 +74,31 @@ export const Diagram = ({ divRef, colorMode = "light" }: DiagramProps) => { // re-triggering the layout effect when they change independently (e.g. selection, // viewport, undo/redo). const selectedNodeIdRef = React.useRef(selectedNodeId); - selectedNodeIdRef.current = selectedNodeId; const pendingViewportRestoreRef = React.useRef(pendingViewportRestore); - pendingViewportRestoreRef.current = pendingViewportRestore; + const isReadOnlyRef = React.useRef(isReadOnly); - isReadOnlyRef.current = isReadOnly; const modelRef = React.useRef(model); - modelRef.current = model; // Function refs — callbacks change identity across renders but the post-layout // setTimeout must always invoke the latest version without re-running layout. const submitModelRef = React.useRef(submitModel); - submitModelRef.current = submitModel; const clearPendingViewportRestoreRef = React.useRef(clearPendingViewportRestore); - clearPendingViewportRestoreRef.current = clearPendingViewportRestore; + // Assigned after commit rather than during render (a render must not have side effects) + React.useLayoutEffect(() => { + selectedNodeIdRef.current = selectedNodeId; + pendingViewportRestoreRef.current = pendingViewportRestore; + isReadOnlyRef.current = isReadOnly; + modelRef.current = model; + submitModelRef.current = submitModel; + clearPendingViewportRestoreRef.current = clearPendingViewportRestore; + }, [ + selectedNodeId, + pendingViewportRestore, + isReadOnly, + model, + submitModel, + clearPendingViewportRestore, + ]); // True once the first layout has been committed to context — gates rendering the canvas // so React Flow mounts with nodes already positioned and fitView fires on real content. const [layoutReady, setLayoutReady] = React.useState(false); diff --git a/packages/open-workflow-diagram-editor/src/react-flow/hooks/useWorkflowHistory.ts b/packages/open-workflow-diagram-editor/src/react-flow/hooks/useWorkflowHistory.ts index 7101cfdb..b25bda68 100644 --- a/packages/open-workflow-diagram-editor/src/react-flow/hooks/useWorkflowHistory.ts +++ b/packages/open-workflow-diagram-editor/src/react-flow/hooks/useWorkflowHistory.ts @@ -88,12 +88,16 @@ export function useWorkflowHistory(isReadOnly: boolean): UseWorkflowHistoryRetur // closing over it — this prevents them from being recreated on every state change, // which would retrigger layout effects and cause infinite re-render loops. const stateRef = React.useRef(state); - stateRef.current = state; // Keep a ref to the latest isReadOnly so callbacks don't go stale when the prop // changes (e.g. Storybook controls toggling the isReadOnly arg). const isReadOnlyRef = React.useRef(isReadOnly); - isReadOnlyRef.current = isReadOnly; + + // Assigned after commit rather than during render (a render must not have side effects) + React.useLayoutEffect(() => { + stateRef.current = state; + isReadOnlyRef.current = isReadOnly; + }, [state, isReadOnly]); /** * Seeds the model from external props.content. diff --git a/packages/open-workflow-diagram-editor/src/store/DiagramEditorContextProvider.tsx b/packages/open-workflow-diagram-editor/src/store/DiagramEditorContextProvider.tsx index 56bf2f2f..cae0936f 100644 --- a/packages/open-workflow-diagram-editor/src/store/DiagramEditorContextProvider.tsx +++ b/packages/open-workflow-diagram-editor/src/store/DiagramEditorContextProvider.tsx @@ -56,6 +56,13 @@ export const DiagramEditorContextProvider = React.forwardRef< // Config state (non-history) const [locale, setLocale] = React.useState(props.locale); + const [lastPropsLocale, setLastPropsLocale] = React.useState(props.locale); + + if (props.locale !== lastPropsLocale) { + setLastPropsLocale(props.locale); + setLocale(props.locale); + } + const [nodes, setNodes] = React.useState([] as RF.Node[]); const [edges, setEdges] = React.useState([] as RF.Edge[]); const [selectedNodeId, setSelectedNodeId] = React.useState(null); @@ -90,13 +97,18 @@ export const DiagramEditorContextProvider = React.forwardRef< // Keep a ref to the latest selectedNodeId so the effect below can read it // synchronously without taking it as a dependency (avoids re-seeding on every click). const selectedNodeIdRef = React.useRef(selectedNodeId); - selectedNodeIdRef.current = selectedNodeId; + + React.useEffect(() => { + selectedNodeIdRef.current = selectedNodeId; + }, [selectedNodeId]); // Seed history from the external content prop using seedModel (bypasses isReadOnly guard). // The real viewport is set by Diagram.tsx once layout completes in edit mode. // In read-only mode the placeholder viewport is acceptable since fitView always runs. React.useEffect(() => { const { model: parsedModel, errors: parsedErrors } = parseWorkflow(props.content); + // This will be addressed in the editing feature branch as the implemntation is changing + // oxlint-disable-next-line react/set-state-in-effect setErrors(parsedErrors); if (parsedModel === null) { // Content is unparseable — reset history to null so downstream consumers @@ -121,11 +133,6 @@ export const DiagramEditorContextProvider = React.forwardRef< [model], ); - // Sync locale state when the prop changes. - React.useEffect(() => { - setLocale(props.locale); - }, [props.locale]); - /** * Imperative API: load a new workflow from a YAML or JSON string. * Mirrors exactly what the props.content effect does, plus updates contentFormat. diff --git a/packages/open-workflow-diagram-editor/tests/hooks/useResolvedColorMode.test.ts b/packages/open-workflow-diagram-editor/tests/hooks/useResolvedColorMode.test.ts index fa1a0361..a48a05a6 100644 --- a/packages/open-workflow-diagram-editor/tests/hooks/useResolvedColorMode.test.ts +++ b/packages/open-workflow-diagram-editor/tests/hooks/useResolvedColorMode.test.ts @@ -73,6 +73,7 @@ describe("useResolvedColorMode", () => { expect(result.current).toBe("light"); act(() => { + matchesDark = true; for (const listener of listeners) { listener({ matches: true } as MediaQueryListEvent); } @@ -80,7 +81,7 @@ describe("useResolvedColorMode", () => { expect(result.current).toBe("dark"); }); - it('resolves an unknown colorMode value to the system preference', () => { + it("resolves an unknown colorMode value to the system preference", () => { matchesDark = false; // @ts-expect-error testing runtime behavior with an invalid colorMode value const { result } = renderHook(() => useResolvedColorMode("invalid")); diff --git a/packages/open-workflow-diagram-editor/tests/store/DiagramEditorContextProvider.test.tsx b/packages/open-workflow-diagram-editor/tests/store/DiagramEditorContextProvider.test.tsx index a3397f6d..49cc3f3b 100644 --- a/packages/open-workflow-diagram-editor/tests/store/DiagramEditorContextProvider.test.tsx +++ b/packages/open-workflow-diagram-editor/tests/store/DiagramEditorContextProvider.test.tsx @@ -16,7 +16,7 @@ import * as React from "react"; import { act, fireEvent, render, screen, waitFor } from "@testing-library/react"; -import { vi, expect, afterEach, describe, it } from "vitest"; +import { vi, expect, afterEach, describe, it, beforeEach } from "vitest"; import { useDiagramEditorContext } from "../../src/store/DiagramEditorContext"; import { DiagramEditorContextProvider } from "../../src/store/DiagramEditorContextProvider"; import type { DiagramEditorRef } from "../../src/diagram-editor/DiagramEditor"; @@ -26,12 +26,11 @@ import { BASIC_VALID_WORKFLOW_YAML, } from "../fixtures/workflows"; +const renderSpy = vi.fn(); + const TestComponent: React.FC = () => { const { isReadOnly, locale, model, errors } = useDiagramEditorContext(); - const renderCount = React.useRef(0); - - // Increments on every render cycle - renderCount.current++; + renderSpy(); return (
@@ -39,7 +38,6 @@ const TestComponent: React.FC = () => {

{`${locale}`}

{`${model ? model.document?.name : "null"}`}

{`${errors.length}`}

-

{`${renderCount.current}`}

); }; @@ -55,6 +53,10 @@ const SelectionButton: React.FC = () => { }; describe("DiagramEditorContextProvider Component", () => { + beforeEach(() => { + renderSpy.mockClear(); + }); + afterEach(() => { vi.restoreAllMocks(); }); @@ -72,14 +74,13 @@ describe("DiagramEditorContextProvider Component", () => { const readOnlyElement = screen.getByTestId("test-read-only"); const readOnlyLocale = screen.getByTestId("test-locale"); - const renderCount = screen.getByTestId("test-render"); expect(readOnlyElement).toHaveTextContent(/true/i); expect(readOnlyLocale).toHaveTextContent(/en/i); // Two rendering cycles are expected: // 1- initial render, 2- useEffect seeding history from parsedModel - expect(renderCount).toHaveTextContent(/2/i); + expect(renderSpy).toHaveBeenCalledTimes(2); }); it("Context provider props changes shall cause internal component to reload", async () => { @@ -105,15 +106,14 @@ describe("DiagramEditorContextProvider Component", () => { const readOnlyElementChanged = screen.getByTestId("test-read-only"); const readOnlyLocaleChanged = screen.getByTestId("test-locale"); - const renderCount = screen.getByTestId("test-render"); expect(readOnlyElementChanged).toHaveTextContent(/false/i); expect(readOnlyLocaleChanged).toHaveTextContent(/pt/i); // 4 rendering cycles are expected: // 1- initial render, 2- history seed useEffect, - // 3- forced by rerender, 4- state updates from isReadOnly/locale change - expect(renderCount).toHaveTextContent(/4/i); + // 3- forced by rerender + expect(renderSpy).toHaveBeenCalledTimes(3); }); it("Context provider same props shall not cause internal component to reload", async () => { @@ -139,14 +139,13 @@ describe("DiagramEditorContextProvider Component", () => { const readOnlyElementChanged = screen.getByTestId("test-read-only"); const readOnlyLocaleChanged = screen.getByTestId("test-locale"); - const renderCount = screen.getByTestId("test-render"); expect(readOnlyElementChanged).toHaveTextContent(/true/i); expect(readOnlyLocaleChanged).toHaveTextContent(/en/i); // 3 rendering cycles are expected: // 1- initial render, 2- history seed useEffect, 3- forced by rerender (same props, no state change) - expect(renderCount).toHaveTextContent(/3/i); + expect(renderSpy).toHaveBeenCalledTimes(3); }); it("Parses valid workflow content into model with no errors", async () => { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1c4e4c36..fd413fd1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -118,8 +118,8 @@ catalogs: specifier: ^0.65.0 version: 0.65.0 oxlint: - specifier: ^1.77.0 - version: 1.77.0 + specifier: ^1.80.0 + version: 1.80.0 radix-ui: specifier: ^1.6.5 version: 1.6.7 @@ -218,7 +218,7 @@ importers: version: 0.65.0 oxlint: specifier: 'catalog:' - version: 1.77.0 + version: 1.80.0 rimraf: specifier: 'catalog:' version: 6.1.3 @@ -254,7 +254,7 @@ importers: version: 0.65.0 oxlint: specifier: 'catalog:' - version: 1.77.0 + version: 1.80.0 react: specifier: 'catalog:' version: 19.2.8 @@ -288,7 +288,7 @@ importers: version: 0.65.0 oxlint: specifier: 'catalog:' - version: 1.77.0 + version: 1.80.0 rimraf: specifier: 'catalog:' version: 6.1.3 @@ -412,7 +412,7 @@ importers: version: 0.65.0 oxlint: specifier: 'catalog:' - version: 1.77.0 + version: 1.80.0 react: specifier: 'catalog:' version: 19.2.8 @@ -500,7 +500,7 @@ importers: version: 0.65.0 oxlint: specifier: 'catalog:' - version: 1.77.0 + version: 1.80.0 react: specifier: 'catalog:' version: 19.2.8 @@ -1388,124 +1388,124 @@ packages: cpu: [x64] os: [win32] - '@oxlint/binding-android-arm-eabi@1.77.0': - resolution: {integrity: sha512-E06sKWS6PiI6HRxS1wyQg22HvApt01hI7fV+T3wUk3OSbaaP4a3hYGY/MIQDmASqCiRjBdpRQYkgMkqH82cWmQ==} + '@oxlint/binding-android-arm-eabi@1.80.0': + resolution: {integrity: sha512-RM3Plj+biQpxa5d1GOOX6ciDlcUROmm4OZ/pLTpitkQt2mJv4jhtY4cbgaetOm5UKWZe05/TGQ6o1Vl8EOHkrA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxlint/binding-android-arm64@1.77.0': - resolution: {integrity: sha512-NvsKz0KZxTp9cYWPLf+FXaSZwB3oO3peAjtukpOMBgse2vhQSoIIVqeO1yR0lEo/UcdZIDL18uq+kL0LzQ0ytA==} + '@oxlint/binding-android-arm64@1.80.0': + resolution: {integrity: sha512-YlO5JEf0Yr2bUUlu8O8daVcUxtcGGbcSmyV7E7nSbJbfAdxTE0PFPwgnIlw7wXJaTYjb+qs5hI5q3jxUkI7cAw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxlint/binding-darwin-arm64@1.77.0': - resolution: {integrity: sha512-bgjTn6nW4bQCFBvSvuHCpDD+sONvmpo4lGI4PxzMt1quBA+xYxhczk6RiCn3GZ9gY8uhaBbwhj9MdKGfu6T9DA==} + '@oxlint/binding-darwin-arm64@1.80.0': + resolution: {integrity: sha512-BULDOyO3AhsmdWfQeIUCykDt3dd7XZBGLhp1eIh56skRv01O+cNjNPwXMIbeW1x4+pxcln5if72wcRgViVo7PA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxlint/binding-darwin-x64@1.77.0': - resolution: {integrity: sha512-aotaIttH1R6j1Rwhx0M0htgeZyGtVQqYNTVEYMN/UcgHPquGA6kmk9OyuDc3a2GKUQBC+3C3GVQCcrRPMYqAFA==} + '@oxlint/binding-darwin-x64@1.80.0': + resolution: {integrity: sha512-YJ4JzLw7N5TDSQFlA0hAQGHvnDZgyypm1yunObVWcWiF9KM7eGCJKYKLgTC2Fi/57OdnBhbj4OkzPGdFQJ6HyA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxlint/binding-freebsd-x64@1.77.0': - resolution: {integrity: sha512-nNx/wta7ksRAdYvq+l4AWjXkLxEXHALhENxjj2cYbQAIR4ybaA5L+hCbE63HOmft5czQ6ks+hb8vmEAnn7YGPg==} + '@oxlint/binding-freebsd-x64@1.80.0': + resolution: {integrity: sha512-AYUIk5QnL0s8oWAYsREZwkRYy1SupJTXALo93J1TgzHywxQtdM99FecRMQ87MXEdPQ0j1TmEpeeq3fGNkpvMqg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxlint/binding-linux-arm-gnueabihf@1.77.0': - resolution: {integrity: sha512-tMLLjM7xXtzXisVCzkOTXNCy9bZVId2wteNwjohlFDR/jY6WagpEDA1c1wu4xRc20Hojaxj+V6DSR7gbKxijWA==} + '@oxlint/binding-linux-arm-gnueabihf@1.80.0': + resolution: {integrity: sha512-9hBZVANupQ89W9dXyE0n8doCyaW5pDyGn3y6XlIMPZ+rIKuyqkr3SNUXmVJIhuvUq0NBU3RBiSXXE69l4XI6KA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm-musleabihf@1.77.0': - resolution: {integrity: sha512-MiAFDFaqR0tmHTAyo0YDcZ5hyLREdYw/RQhc2R3cbT+8O3tB+zqPM2th9TTQ+Uo3jn/embS+DO+HyX9ztCPkOQ==} + '@oxlint/binding-linux-arm-musleabihf@1.80.0': + resolution: {integrity: sha512-SvS2uKqzY+pbfuvAHzH4338R6Zwo805GAwrIMVvK1KxoOWCIjZUdfzTCvilD7z6JK91v011+zYMryabhDo2AsQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm64-gnu@1.77.0': - resolution: {integrity: sha512-/xqQ3B16i1T4cyt/9Mn+4CpzhUXoBXp7kVpIwzOXNFLj5JmK1bIjsbSnX296Gg8A/o7oDtKWikFgBx0SLwztkw==} + '@oxlint/binding-linux-arm64-gnu@1.80.0': + resolution: {integrity: sha512-tCLadyqRVL3pQTRPNg7cjXKvcvS4fbyXeQHhKk5BTJ1oftQln5/yIIWbu/Xom/DX41zv2P9QGt6+D/TtQVtY3A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-arm64-musl@1.77.0': - resolution: {integrity: sha512-LSbwuRKiNCenPDcbARqAZ5RfBy7gmj7vOvfJRLeCDU3gFtSxWbhv/+VTlaUqzUhNj1gFLHB8h7ALnxa/Az6z6g==} + '@oxlint/binding-linux-arm64-musl@1.80.0': + resolution: {integrity: sha512-XfpCNRlOPcLlJl4Bn/FUhjqlR6BVavEykERBf/MV7YA9VZDa5g5znVqYhyviMafcxS9Pe/i/kPvHNO0U6svEHQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@oxlint/binding-linux-ppc64-gnu@1.77.0': - resolution: {integrity: sha512-QWdcH31mXEUe5Nq1s0CfCpceaKjIo9uZtwDjAuL681g1axf+5x8xrg/eXWaw//4NCxYZ4V4e5Hu5tvdR+pTBlg==} + '@oxlint/binding-linux-ppc64-gnu@1.80.0': + resolution: {integrity: sha512-3I4yMwcFG9NeO8ioY6JBBuKsIm5GL/x7MATt1S4tVWaxPu5HcJ+XnLUbcVBTxG8q2Wu56HSj+NmXQiVYb1lp6A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-riscv64-gnu@1.77.0': - resolution: {integrity: sha512-GnOfYgJxbcElOiPZaDFDl406ONddwvOWk2jvAAAEjwAl4GofNoHF+/HHUIBYa6bFCArlcGPi0XjC4cU1pkgF/Q==} + '@oxlint/binding-linux-riscv64-gnu@1.80.0': + resolution: {integrity: sha512-E1wAKymkpe1/E8helzBKdm81OBOF+ezxRyXRMEuik3ZpWDER5CPOKZwF66RsdwW98uwZv8UTFremUQtC1CzdJA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-riscv64-musl@1.77.0': - resolution: {integrity: sha512-AyEMTUCf0xY+hHF+IxqXFQIX0yQOIR8ykpY0lJNOw9xYqOzUX8dyZfRvlG0RfXwuQn2eonf/8NrMmDSZJjdqsA==} + '@oxlint/binding-linux-riscv64-musl@1.80.0': + resolution: {integrity: sha512-+gLRGD4sIo3+VA++iham5UxD9tKSoJ/VOrROCEXIcknrYtQg6iIQgvjN0cpiRF7N6UYC7pJbvHJlDnMge5LRpQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [musl] - '@oxlint/binding-linux-s390x-gnu@1.77.0': - resolution: {integrity: sha512-sPLzEcNvxd/oyVQ5oZo92CiHkFkpBeRop13E/P3TPY+hZfXHKCOWKI70TE2RYwMKFJDc20EMjH16L7NZICtKTw==} + '@oxlint/binding-linux-s390x-gnu@1.80.0': + resolution: {integrity: sha512-aR0PrzHj9leW3NmzBAAP4EzdoBNoJcs9sjnIQPIwyRnBGYrRbXUIpEB5Q39AqK3PLY5JK5uEhDQDiUa1QSAstw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@oxlint/binding-linux-x64-gnu@1.77.0': - resolution: {integrity: sha512-1Oh2ssH2L7lwyvkdSqaMUfsGfwU2Wfvew+obBUYjRVqhpBcUpwnsPSEr1IzVi9XqkuY10geiLsNKecqaZC34Dw==} + '@oxlint/binding-linux-x64-gnu@1.80.0': + resolution: {integrity: sha512-vSVh5cSo3Xxs6ghBCcFJlpbkbENzDog1qXtoXLa/HC3aCrR4XO76GZbXmQoCPHnu99nQpdCeC3H9tdNICfDh7A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-x64-musl@1.77.0': - resolution: {integrity: sha512-0j/2wRgNGO+Qj/M1uu/p57h/hFTTWWcfie0ufkbabeus2s5+/QqkCflnMOwLLN5m2GsNeWp4xdl4cPa4n7QCOQ==} + '@oxlint/binding-linux-x64-musl@1.80.0': + resolution: {integrity: sha512-FfzBXpNQ8u7/ZI/p8bl73MeZ508Ax3hxWp3SiJpEFiC+BB9XcXy5FAZHTLKDPSzrUpxQZSZJAVdDmuJp/+HDBQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@oxlint/binding-openharmony-arm64@1.77.0': - resolution: {integrity: sha512-BJ/j54qS0usEnyDkLYURMj2iiD9h5Cyy+ppzeMSXBGRXaGRNWnj1Mw14NqWMR5E/PzdgB30OOCCzLzbRoduafw==} + '@oxlint/binding-openharmony-arm64@1.80.0': + resolution: {integrity: sha512-zMzbkumtmprCgRwoYNzcB3iC39fXdJIMLMU33KdCjEGLlJGOEt1+LwQ4LF8ndLzAEKVz4BR0y3V6Xrkk3Nm3yA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxlint/binding-win32-arm64-msvc@1.77.0': - resolution: {integrity: sha512-Yh8w+g2Lpx7StrvtYkoz9JJvXjB9wxgFChFNb85nrXm/wj/XTwGWS1hve9+900HL7llrntYB3YP+y32E3tRqzA==} + '@oxlint/binding-win32-arm64-msvc@1.80.0': + resolution: {integrity: sha512-ib6iRcrXsk4t1fm3iKcwksyWh1ZkZXC/2mEzakl0ai2+6HZunf1WWMZ/xP9EJAvw9g9K4UVTC3NF/+G2qLrbTQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxlint/binding-win32-ia32-msvc@1.77.0': - resolution: {integrity: sha512-zja5b7+6a7UsRFgAQSrnax5vrzliEyNPLCjfXONu/vTWswaIVZGFajJZptaeRvPE4LghtFdAzVFlexTm7MVTGA==} + '@oxlint/binding-win32-ia32-msvc@1.80.0': + resolution: {integrity: sha512-xhRWBMpLxZvgKAH6+DJZmpP+W8Y8UdQOSU1JfxSWNXsaBaRGW77j+1hCuNHlzj7OH4SPN8fYd1q0o2qrDtoVyw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxlint/binding-win32-x64-msvc@1.77.0': - resolution: {integrity: sha512-+teyvPDZ2RjUvo+SuCqS/UhaJl1QtdW5fWT5NJTV61V5MIuIS90Db9LixmtEGvXixyttiK62P96MSu3UlpviBw==} + '@oxlint/binding-win32-x64-msvc@1.80.0': + resolution: {integrity: sha512-yAnO7lwBYQnz2pcfBPIGQQZWIX5zd5R/1aAKIF3oE+TVj7IhoHcROjOkz3sRDngzqhfPKfFaXqug5j5rE5dn6Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -3571,8 +3571,8 @@ packages: vite-plus: optional: true - oxlint@1.77.0: - resolution: {integrity: sha512-qnGh8XJHaQ0dprrDXNQZgS0FgjI6v+V3+X8DwmaV++5Aamy6jGKfDdQ1TUvhUxtmKFAbEf4/WeO5QZX+5WSngg==} + oxlint@1.80.0: + resolution: {integrity: sha512-5nTiSps4qdbCWLbxzuO00alHkEO2exR9YMN/ig6QXWrLsYSG0KaObOAM+l6oU2LcKPWoSAGYbkZIGEu1ViiWKA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -4904,61 +4904,61 @@ snapshots: '@oxfmt/binding-win32-x64-msvc@0.65.0': optional: true - '@oxlint/binding-android-arm-eabi@1.77.0': + '@oxlint/binding-android-arm-eabi@1.80.0': optional: true - '@oxlint/binding-android-arm64@1.77.0': + '@oxlint/binding-android-arm64@1.80.0': optional: true - '@oxlint/binding-darwin-arm64@1.77.0': + '@oxlint/binding-darwin-arm64@1.80.0': optional: true - '@oxlint/binding-darwin-x64@1.77.0': + '@oxlint/binding-darwin-x64@1.80.0': optional: true - '@oxlint/binding-freebsd-x64@1.77.0': + '@oxlint/binding-freebsd-x64@1.80.0': optional: true - '@oxlint/binding-linux-arm-gnueabihf@1.77.0': + '@oxlint/binding-linux-arm-gnueabihf@1.80.0': optional: true - '@oxlint/binding-linux-arm-musleabihf@1.77.0': + '@oxlint/binding-linux-arm-musleabihf@1.80.0': optional: true - '@oxlint/binding-linux-arm64-gnu@1.77.0': + '@oxlint/binding-linux-arm64-gnu@1.80.0': optional: true - '@oxlint/binding-linux-arm64-musl@1.77.0': + '@oxlint/binding-linux-arm64-musl@1.80.0': optional: true - '@oxlint/binding-linux-ppc64-gnu@1.77.0': + '@oxlint/binding-linux-ppc64-gnu@1.80.0': optional: true - '@oxlint/binding-linux-riscv64-gnu@1.77.0': + '@oxlint/binding-linux-riscv64-gnu@1.80.0': optional: true - '@oxlint/binding-linux-riscv64-musl@1.77.0': + '@oxlint/binding-linux-riscv64-musl@1.80.0': optional: true - '@oxlint/binding-linux-s390x-gnu@1.77.0': + '@oxlint/binding-linux-s390x-gnu@1.80.0': optional: true - '@oxlint/binding-linux-x64-gnu@1.77.0': + '@oxlint/binding-linux-x64-gnu@1.80.0': optional: true - '@oxlint/binding-linux-x64-musl@1.77.0': + '@oxlint/binding-linux-x64-musl@1.80.0': optional: true - '@oxlint/binding-openharmony-arm64@1.77.0': + '@oxlint/binding-openharmony-arm64@1.80.0': optional: true - '@oxlint/binding-win32-arm64-msvc@1.77.0': + '@oxlint/binding-win32-arm64-msvc@1.80.0': optional: true - '@oxlint/binding-win32-ia32-msvc@1.77.0': + '@oxlint/binding-win32-ia32-msvc@1.80.0': optional: true - '@oxlint/binding-win32-x64-msvc@1.77.0': + '@oxlint/binding-win32-x64-msvc@1.80.0': optional: true '@playwright/test@1.62.1': @@ -6944,27 +6944,27 @@ snapshots: '@oxfmt/binding-win32-ia32-msvc': 0.65.0 '@oxfmt/binding-win32-x64-msvc': 0.65.0 - oxlint@1.77.0: + oxlint@1.80.0: optionalDependencies: - '@oxlint/binding-android-arm-eabi': 1.77.0 - '@oxlint/binding-android-arm64': 1.77.0 - '@oxlint/binding-darwin-arm64': 1.77.0 - '@oxlint/binding-darwin-x64': 1.77.0 - '@oxlint/binding-freebsd-x64': 1.77.0 - '@oxlint/binding-linux-arm-gnueabihf': 1.77.0 - '@oxlint/binding-linux-arm-musleabihf': 1.77.0 - '@oxlint/binding-linux-arm64-gnu': 1.77.0 - '@oxlint/binding-linux-arm64-musl': 1.77.0 - '@oxlint/binding-linux-ppc64-gnu': 1.77.0 - '@oxlint/binding-linux-riscv64-gnu': 1.77.0 - '@oxlint/binding-linux-riscv64-musl': 1.77.0 - '@oxlint/binding-linux-s390x-gnu': 1.77.0 - '@oxlint/binding-linux-x64-gnu': 1.77.0 - '@oxlint/binding-linux-x64-musl': 1.77.0 - '@oxlint/binding-openharmony-arm64': 1.77.0 - '@oxlint/binding-win32-arm64-msvc': 1.77.0 - '@oxlint/binding-win32-ia32-msvc': 1.77.0 - '@oxlint/binding-win32-x64-msvc': 1.77.0 + '@oxlint/binding-android-arm-eabi': 1.80.0 + '@oxlint/binding-android-arm64': 1.80.0 + '@oxlint/binding-darwin-arm64': 1.80.0 + '@oxlint/binding-darwin-x64': 1.80.0 + '@oxlint/binding-freebsd-x64': 1.80.0 + '@oxlint/binding-linux-arm-gnueabihf': 1.80.0 + '@oxlint/binding-linux-arm-musleabihf': 1.80.0 + '@oxlint/binding-linux-arm64-gnu': 1.80.0 + '@oxlint/binding-linux-arm64-musl': 1.80.0 + '@oxlint/binding-linux-ppc64-gnu': 1.80.0 + '@oxlint/binding-linux-riscv64-gnu': 1.80.0 + '@oxlint/binding-linux-riscv64-musl': 1.80.0 + '@oxlint/binding-linux-s390x-gnu': 1.80.0 + '@oxlint/binding-linux-x64-gnu': 1.80.0 + '@oxlint/binding-linux-x64-musl': 1.80.0 + '@oxlint/binding-openharmony-arm64': 1.80.0 + '@oxlint/binding-win32-arm64-msvc': 1.80.0 + '@oxlint/binding-win32-ia32-msvc': 1.80.0 + '@oxlint/binding-win32-x64-msvc': 1.80.0 package-json-from-dist@1.0.1: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 27e32510..fda1d156 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -39,7 +39,7 @@ catalog: lucide-react: ^1.38.0 lint-staged: ^17.4.1 oxfmt: ^0.65.0 - oxlint: ^1.77.0 + oxlint: ^1.80.0 radix-ui: ^1.6.5 react: ^19.2.8 react-dom: ^19.2.8