From ceb3c5052f029f6bb726943ed5c6a0d5ae4202f9 Mon Sep 17 00:00:00 2001 From: moosebay Date: Sat, 7 Mar 2026 00:45:12 +0300 Subject: [PATCH 1/2] feat: WebSocket flow nodes, Wait node, flow runner overhaul, and dep updates WebSocket Support: - Add WebSocket Connection and Send flow nodes (client + server) - Add WebSocket request page and API - Add drag-and-drop from file tree to flow canvas for WebSocket items - Add WS echo server integration test, migrate to coder/websocket Wait Node: - Add Wait flow node with configurable duration Flow Runner Overhaul: - Extract flow execution into flowexec/flowresult packages (~900 lines) - Wire runner abstractions into strategies with shared helpers - Fix CANCELED status not sent when stopping a flow Bug Fixes: - Fix WS Send node dropdown empty when no selection exists - Fix @lezer/common override for CodeMirror highlight crash - Fix sync insert handler idempotency, node event publisher types - Fix wait node copy/paste, server panic on closed WS channel Dependencies: - Update all npm packages to latest (ESLint pinned to v9, syncpack to v13) - Update Scoop dependencies (7zip, gcc, go, nodejs, etc.) - Fix eslint-plugin-better-tailwindcss v4 config changes - Fix @types/react FormEvent deprecation - Fix matchRoute return type change --- apps/cli/cmd/flow.go | 5 + apps/cli/internal/common/services.go | 37 +- apps/cli/internal/runner/runner.go | 4 +- apps/cli/internal/runner/runner_test.go | 119 + .../yamlflow/integration_yamlflow_test.go | 1 + apps/cli/test/yamlflow/ws_run_example.yaml | 57 + apps/desktop/package.json | 2 +- apps/desktop/src/renderer/main.tsx | 2 +- go.work.sum | 36 +- install.ps1 | 722 + .../client/src/app/router/route-tree.gen.ts | 68 +- .../client/src/features/file-system/index.tsx | 193 +- packages/client/src/pages/flow/add-node.tsx | 61 +- .../client/src/pages/flow/agent-panel.tsx | 6 +- packages/client/src/pages/flow/edge.tsx | 2 +- packages/client/src/pages/flow/edit.tsx | 28 + packages/client/src/pages/flow/handle.tsx | 25 +- packages/client/src/pages/flow/node.tsx | 53 +- packages/client/src/pages/flow/nodes/wait.tsx | 69 + .../src/pages/flow/nodes/ws-connection.tsx | 144 + .../client/src/pages/flow/nodes/ws-send.tsx | 99 + .../client/src/pages/websocket/@x/flow.tsx | 1 + .../src/pages/websocket/@x/workspace.tsx | 3 + packages/client/src/pages/websocket/page.tsx | 47 + .../src/pages/websocket/request/header.tsx | 140 + .../src/pages/websocket/request/index.tsx | 3 + .../src/pages/websocket/request/panel.tsx | 117 + .../src/pages/websocket/request/top-bar.tsx | 78 + .../src/pages/websocket/request/url.tsx | 91 + .../src/pages/websocket/response/index.tsx | 152 + .../websocket/$websocketIdCan/index.tsx | 19 + .../websocket/$websocketIdCan/route.tsx | 11 + packages/client/src/pages/websocket/tab.tsx | 35 + .../src/pages/websocket/use-websocket.ts | 107 + .../$workspaceIdCan/(websocket)/__virtual.ts | 3 + .../src/shared/api/collection.internal.tsx | 6 +- packages/client/src/shared/routes.tsx | 4 + packages/db/pkg/sqlc/gen/db.go | 250 + packages/db/pkg/sqlc/gen/flow.sql.go | 72 + packages/db/pkg/sqlc/gen/models.go | 40 + packages/db/pkg/sqlc/gen/websocket.sql.go | 443 + packages/db/pkg/sqlc/queries/flow.sql | 30 + packages/db/pkg/sqlc/queries/websocket.sql | 134 + packages/db/pkg/sqlc/schema/05_flow.sql | 5 + packages/db/pkg/sqlc/schema/10_websocket.sql | 57 + packages/db/pkg/sqlc/sqlc.yaml | 53 + packages/server/cmd/serverrun/serverrun.go | 58 +- packages/server/go.mod | 5 +- packages/server/go.sum | 2 + .../server/internal/api/rexportv2/export.go | 279 +- .../internal/api/rexportv2/exporter_test.go | 30 +- .../internal/api/rexportv2/rexportv2.go | 70 +- packages/server/internal/api/rfile/rfile.go | 4 + .../internal/api/rflowv2/logging_test.go | 8 +- .../api/rflowv2/node_config_sync_test.go | 4 +- .../server/internal/api/rflowv2/rflowv2.go | 241 +- .../api/rflowv2/rflowv2_copy_paste.go | 148 + .../internal/api/rflowv2/rflowv2_exec.go | 920 +- .../api/rflowv2/rflowv2_exec_publisher.go | 241 + .../internal/api/rflowv2/rflowv2_exec_test.go | 57 +- .../rflowv2/rflowv2_exec_transaction_test.go | 137 +- .../internal/api/rflowv2/rflowv2_flow.go | 82 +- .../rflowv2/rflowv2_node_condition_test.go | 8 +- .../internal/api/rflowv2/rflowv2_node_exec.go | 70 - .../api/rflowv2/rflowv2_node_exec_test.go | 15 +- .../internal/api/rflowv2/rflowv2_node_wait.go | 426 + .../api/rflowv2/rflowv2_node_ws_connection.go | 464 + .../api/rflowv2/rflowv2_node_ws_send.go | 446 + .../rflowv2/rflowv2_sync_zero_value_test.go | 2 +- .../api/rflowv2/rflowv2_testutil_test.go | 8 +- .../api/rflowv2/sync_robustness_test.go | 2 +- .../server/internal/api/rgraphql/rgraphql.go | 5 + .../api/rgraphql/rgraphql_converter.go | 221 + .../api/rgraphql/rgraphql_crud_assert.go | 58 +- .../rgraphql/rgraphql_crud_header_delta.go | 62 +- .../api/rimportv2/integration_test.go | 2 + .../internal/api/rimportv2/integrity.go | 6 + .../internal/api/rimportv2/rimportv2_event.go | 2 +- .../internal/api/rreference/rreference.go | 12 +- .../internal/api/rwebsocket/rwebsocket.go | 790 ++ .../server/internal/converter/converter.go | 6 + .../internal/converter/converter_test.go | 2 + .../migrations/01KJZMR5_add_flow_node_wait.go | 50 + .../01KKFQT8_add_websocket_tables.go | 233 + .../internal/migrations/migrations_test.go | 8 +- .../server/pkg/flow/flowbuilder/builder.go | 123 +- packages/server/pkg/flow/flowexec/session.go | 165 + .../server/pkg/flow/flowexec/session_test.go | 36 + packages/server/pkg/flow/flowexec/snapshot.go | 396 + .../server/pkg/flow/flowexec/snapshot_test.go | 238 + packages/server/pkg/flow/flowresult/drain.go | 212 + packages/server/pkg/flow/flowresult/noop.go | 70 + .../server/pkg/flow/flowresult/processor.go | 152 + .../server/pkg/flow/flowresult/publisher.go | 28 + .../pkg/flow/flowresult/statetracker.go | 247 + packages/server/pkg/flow/node/entry.go | 26 + .../server/pkg/flow/node/nfor/nfor_test.go | 6 +- .../pkg/flow/node/nforeach/nforeach_test.go | 6 +- packages/server/pkg/flow/node/node.go | 37 +- .../server/pkg/flow/node/nstart/nstart.go | 4 + packages/server/pkg/flow/node/nwait/nwait.go | 51 + .../flow/node/nwsconnection/nwsconnection.go | 291 + .../node/nwsconnection/nwsconnection_test.go | 204 + .../server/pkg/flow/node/nwssend/nwssend.go | 111 + .../pkg/flow/node/nwssend/nwssend_test.go | 152 + .../flow/runner/flowlocalrunner/executor.go | 67 + .../runner/flowlocalrunner/flowlocalrunner.go | 1177 +- .../flowlocalrunner_inputdata_test.go | 6 +- .../flowlocalrunner/flowlocalrunner_test.go | 363 +- .../flow/runner/flowlocalrunner/helpers.go | 91 + .../runner/flowlocalrunner/mode_select.go | 72 + .../runner/flowlocalrunner/strategy_multi.go | 281 + .../runner/flowlocalrunner/strategy_single.go | 106 + packages/server/pkg/flow/runner/graph.go | 126 + packages/server/pkg/flow/runner/runner.go | 9 - packages/server/pkg/flow/runner/status.go | 160 + .../server/pkg/flow/simulation/mockflows.go | 18 +- .../pkg/flow/simulation/mockflows_test.go | 14 +- packages/server/pkg/ioworkspace/exporter.go | 62 +- packages/server/pkg/ioworkspace/importer.go | 48 +- .../server/pkg/ioworkspace/importer_flow.go | 98 + packages/server/pkg/ioworkspace/types.go | 19 +- packages/server/pkg/model/mfile/mfile.go | 14 +- packages/server/pkg/model/mflow/edge.go | 1 + packages/server/pkg/model/mflow/node.go | 8 +- packages/server/pkg/model/mflow/node_types.go | 26 +- .../server/pkg/model/mwebsocket/mwebsocket.go | 29 + packages/server/pkg/mutation/delete_file.go | 5 + packages/server/pkg/mutation/event.go | 3 + packages/server/pkg/mutation/insert_flow.go | 337 - packages/server/pkg/mutation/update_flow.go | 383 - .../server/pkg/service/sflow/node_mapper.go | 4 +- .../server/pkg/service/sflow/node_wait.go | 51 + .../pkg/service/sflow/node_wait_mapper.go | 20 + .../pkg/service/sflow/node_wait_reader.go | 34 + .../pkg/service/sflow/node_wait_writer.go | 38 + .../server/pkg/service/sflow/node_writer.go | 20 +- .../pkg/service/sflow/node_ws_connection.go | 49 + .../sflow/node_ws_connection_mapper.go | 24 + .../sflow/node_ws_connection_reader.go | 30 + .../sflow/node_ws_connection_writer.go | 46 + .../server/pkg/service/sflow/node_ws_send.go | 49 + .../pkg/service/sflow/node_ws_send_mapper.go | 22 + .../pkg/service/sflow/node_ws_send_reader.go | 30 + .../pkg/service/sflow/node_ws_send_writer.go | 35 + .../server/pkg/service/sgraphql/header.go | 11 + .../server/pkg/service/swebsocket/header.go | 75 + .../server/pkg/service/swebsocket/mapper.go | 58 + .../pkg/service/swebsocket/swebsocket.go | 72 + .../yamlflowsimplev2/converter_flow.go | 5 + .../yamlflowsimplev2/converter_node.go | 121 + .../translate/yamlflowsimplev2/exporter.go | 80 +- .../pkg/translate/yamlflowsimplev2/types.go | 28 +- .../pkg/translate/yamlflowsimplev2/utils.go | 10 +- .../translate/yamlflowsimplev2/utils_test.go | 5 +- packages/server/test/e2e_har_to_cli_test.go | 10 +- packages/spec/api/export.tsp | 10 + packages/spec/api/file-system.tsp | 1 + packages/spec/api/flow.tsp | 23 + packages/spec/api/main.tsp | 1 + packages/spec/api/websocket.tsp | 23 + packages/spec/package.json | 2 +- pnpm-lock.yaml | 11132 ++++++++-------- pnpm-workspace.yaml | 147 +- scoop.json | 64 +- tools/eslint/config.ts | 2 +- 166 files changed, 18513 insertions(+), 8715 deletions(-) create mode 100644 apps/cli/test/yamlflow/ws_run_example.yaml create mode 100644 install.ps1 create mode 100644 packages/client/src/pages/flow/nodes/wait.tsx create mode 100644 packages/client/src/pages/flow/nodes/ws-connection.tsx create mode 100644 packages/client/src/pages/flow/nodes/ws-send.tsx create mode 100644 packages/client/src/pages/websocket/@x/flow.tsx create mode 100644 packages/client/src/pages/websocket/@x/workspace.tsx create mode 100644 packages/client/src/pages/websocket/page.tsx create mode 100644 packages/client/src/pages/websocket/request/header.tsx create mode 100644 packages/client/src/pages/websocket/request/index.tsx create mode 100644 packages/client/src/pages/websocket/request/panel.tsx create mode 100644 packages/client/src/pages/websocket/request/top-bar.tsx create mode 100644 packages/client/src/pages/websocket/request/url.tsx create mode 100644 packages/client/src/pages/websocket/response/index.tsx create mode 100644 packages/client/src/pages/websocket/routes/websocket/$websocketIdCan/index.tsx create mode 100644 packages/client/src/pages/websocket/routes/websocket/$websocketIdCan/route.tsx create mode 100644 packages/client/src/pages/websocket/tab.tsx create mode 100644 packages/client/src/pages/websocket/use-websocket.ts create mode 100644 packages/client/src/pages/workspace/routes/workspace/$workspaceIdCan/(websocket)/__virtual.ts create mode 100644 packages/db/pkg/sqlc/gen/websocket.sql.go create mode 100644 packages/db/pkg/sqlc/queries/websocket.sql create mode 100644 packages/db/pkg/sqlc/schema/10_websocket.sql create mode 100644 packages/server/internal/api/rflowv2/rflowv2_exec_publisher.go create mode 100644 packages/server/internal/api/rflowv2/rflowv2_node_wait.go create mode 100644 packages/server/internal/api/rflowv2/rflowv2_node_ws_connection.go create mode 100644 packages/server/internal/api/rflowv2/rflowv2_node_ws_send.go create mode 100644 packages/server/internal/api/rwebsocket/rwebsocket.go create mode 100644 packages/server/internal/migrations/01KJZMR5_add_flow_node_wait.go create mode 100644 packages/server/internal/migrations/01KKFQT8_add_websocket_tables.go create mode 100644 packages/server/pkg/flow/flowexec/session.go create mode 100644 packages/server/pkg/flow/flowexec/session_test.go create mode 100644 packages/server/pkg/flow/flowexec/snapshot.go create mode 100644 packages/server/pkg/flow/flowexec/snapshot_test.go create mode 100644 packages/server/pkg/flow/flowresult/drain.go create mode 100644 packages/server/pkg/flow/flowresult/noop.go create mode 100644 packages/server/pkg/flow/flowresult/processor.go create mode 100644 packages/server/pkg/flow/flowresult/publisher.go create mode 100644 packages/server/pkg/flow/flowresult/statetracker.go create mode 100644 packages/server/pkg/flow/node/entry.go create mode 100644 packages/server/pkg/flow/node/nwait/nwait.go create mode 100644 packages/server/pkg/flow/node/nwsconnection/nwsconnection.go create mode 100644 packages/server/pkg/flow/node/nwsconnection/nwsconnection_test.go create mode 100644 packages/server/pkg/flow/node/nwssend/nwssend.go create mode 100644 packages/server/pkg/flow/node/nwssend/nwssend_test.go create mode 100644 packages/server/pkg/flow/runner/flowlocalrunner/executor.go create mode 100644 packages/server/pkg/flow/runner/flowlocalrunner/helpers.go create mode 100644 packages/server/pkg/flow/runner/flowlocalrunner/mode_select.go create mode 100644 packages/server/pkg/flow/runner/flowlocalrunner/strategy_multi.go create mode 100644 packages/server/pkg/flow/runner/flowlocalrunner/strategy_single.go create mode 100644 packages/server/pkg/flow/runner/graph.go create mode 100644 packages/server/pkg/flow/runner/status.go create mode 100644 packages/server/pkg/model/mwebsocket/mwebsocket.go delete mode 100644 packages/server/pkg/mutation/insert_flow.go delete mode 100644 packages/server/pkg/mutation/update_flow.go create mode 100644 packages/server/pkg/service/sflow/node_wait.go create mode 100644 packages/server/pkg/service/sflow/node_wait_mapper.go create mode 100644 packages/server/pkg/service/sflow/node_wait_reader.go create mode 100644 packages/server/pkg/service/sflow/node_wait_writer.go create mode 100644 packages/server/pkg/service/sflow/node_ws_connection.go create mode 100644 packages/server/pkg/service/sflow/node_ws_connection_mapper.go create mode 100644 packages/server/pkg/service/sflow/node_ws_connection_reader.go create mode 100644 packages/server/pkg/service/sflow/node_ws_connection_writer.go create mode 100644 packages/server/pkg/service/sflow/node_ws_send.go create mode 100644 packages/server/pkg/service/sflow/node_ws_send_mapper.go create mode 100644 packages/server/pkg/service/sflow/node_ws_send_reader.go create mode 100644 packages/server/pkg/service/sflow/node_ws_send_writer.go create mode 100644 packages/server/pkg/service/swebsocket/header.go create mode 100644 packages/server/pkg/service/swebsocket/mapper.go create mode 100644 packages/server/pkg/service/swebsocket/swebsocket.go create mode 100644 packages/spec/api/websocket.tsp diff --git a/apps/cli/cmd/flow.go b/apps/cli/cmd/flow.go index 3935bfeea..510547c10 100644 --- a/apps/cli/cmd/flow.go +++ b/apps/cli/cmd/flow.go @@ -184,6 +184,11 @@ var yamlflowRunCmd = &cobra.Command{ &services.NodeAiProvider, &services.NodeMemory, &services.NodeGraphQL, + &services.NodeWsConnection, + &services.NodeWsSend, + &services.NodeWait, + &services.WebSocket, + &services.WebSocketHeader, &services.GraphQL, &services.GraphQLHeader, &services.Workspace, diff --git a/apps/cli/internal/common/services.go b/apps/cli/internal/common/services.go index f2657757c..ee75bfeb1 100644 --- a/apps/cli/internal/common/services.go +++ b/apps/cli/internal/common/services.go @@ -12,6 +12,7 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sflow" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sgraphql" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/shttp" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/swebsocket" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sworkspace" ) @@ -32,16 +33,23 @@ type Services struct { FlowVariable sflow.FlowVariableService // Flow Nodes - Node sflow.NodeService - NodeRequest sflow.NodeRequestService - NodeFor sflow.NodeForService - NodeForEach sflow.NodeForEachService - NodeIf sflow.NodeIfService - NodeJS sflow.NodeJsService - NodeAI sflow.NodeAIService - NodeAiProvider sflow.NodeAiProviderService - NodeMemory sflow.NodeMemoryService - NodeGraphQL sflow.NodeGraphQLService + Node sflow.NodeService + NodeRequest sflow.NodeRequestService + NodeFor sflow.NodeForService + NodeForEach sflow.NodeForEachService + NodeIf sflow.NodeIfService + NodeJS sflow.NodeJsService + NodeAI sflow.NodeAIService + NodeAiProvider sflow.NodeAiProviderService + NodeMemory sflow.NodeMemoryService + NodeGraphQL sflow.NodeGraphQLService + NodeWsConnection sflow.NodeWsConnectionService + NodeWsSend sflow.NodeWsSendService + NodeWait sflow.NodeWaitService + + // WebSocket + WebSocket swebsocket.WebSocketService + WebSocketHeader swebsocket.WebSocketHeaderService // GraphQL GraphQL sgraphql.GraphQLService @@ -94,7 +102,14 @@ func CreateServices(ctx context.Context, db *sql.DB, logger *slog.Logger) (*Serv NodeAI: sflow.NewNodeAIService(queries), NodeAiProvider: sflow.NewNodeAiProviderService(queries), NodeMemory: sflow.NewNodeMemoryService(queries), - NodeGraphQL: sflow.NewNodeGraphQLService(queries), + NodeGraphQL: sflow.NewNodeGraphQLService(queries), + NodeWsConnection: sflow.NewNodeWsConnectionService(queries), + NodeWsSend: sflow.NewNodeWsSendService(queries), + NodeWait: sflow.NewNodeWaitService(queries), + + // WebSocket + WebSocket: swebsocket.New(queries, logger), + WebSocketHeader: swebsocket.NewWebSocketHeaderService(queries), // GraphQL GraphQL: sgraphql.New(queries, logger), diff --git a/apps/cli/internal/runner/runner.go b/apps/cli/internal/runner/runner.go index d4ae4e6b1..325da9dc9 100644 --- a/apps/cli/internal/runner/runner.go +++ b/apps/cli/internal/runner/runner.go @@ -264,7 +264,7 @@ func RunFlow(ctx context.Context, flowPtr *mflow.Flow, services RunnerServices, defer close(gqlRespChan) // Build flow node map using flowbuilder - flowNodeMap, startNodeID, err := services.Builder.BuildNodes( + flowNodeMap, startNodeIDs, err := services.Builder.BuildNodes( ctx, *flowPtr, nodes, @@ -279,7 +279,7 @@ func RunFlow(ctx context.Context, flowPtr *mflow.Flow, services RunnerServices, } // Use the same timeout for the flow runner - runnerInst := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), latestFlowID, startNodeID, flowNodeMap, edgeMap, nodeTimeout, nil) + runnerInst := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), latestFlowID, startNodeIDs, flowNodeMap, edgeMap, nodeTimeout, nil) // Use a large buffer for CLI to avoid blocking flowNodeStatusChan := make(chan runner.FlowNodeStatus, 10000) diff --git a/apps/cli/internal/runner/runner_test.go b/apps/cli/internal/runner/runner_test.go index 67271a7c2..cd11a0105 100644 --- a/apps/cli/internal/runner/runner_test.go +++ b/apps/cli/internal/runner/runner_test.go @@ -26,9 +26,11 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/senv" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sflow" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/shttp" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/swebsocket" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sworkspace" yamlflowsimplev2 "github.com/the-dev-tools/dev-tools/packages/server/pkg/translate/yamlflowsimplev2" "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/api/private/node_js_executor/v1/node_js_executorv1connect" + "github.com/coder/websocket" ) // flowTestFixture provides a common test environment for flow execution tests @@ -88,6 +90,13 @@ func newFlowTestFixture(t *testing.T) *flowTestFixture { httpBodyRawService := shttp.NewHttpBodyRawService(queries) httpAssertService := shttp.NewHttpAssertService(queries) + // WebSocket services + nodeWsConnectionService := sflow.NewNodeWsConnectionService(queries) + nodeWsSendService := sflow.NewNodeWsSendService(queries) + nodeWaitService := sflow.NewNodeWaitService(queries) + webSocketService := swebsocket.New(queries, logger) + webSocketHeaderService := swebsocket.NewWebSocketHeaderService(queries) + // Additional services for builder varService := senv.NewVariableService(queries, logger) @@ -114,6 +123,11 @@ func newFlowTestFixture(t *testing.T) *flowTestFixture { nil, // NodeAiProviderService - not needed for CLI tests nil, // NodeMemoryService - not needed for CLI tests nil, // NodeGraphQLService - not needed for CLI tests + &nodeWsConnectionService, + &nodeWsSendService, + &nodeWaitService, + &webSocketService, + &webSocketHeaderService, nil, // GraphQLService - not needed for CLI tests nil, // GraphQLHeaderService - not needed for CLI tests &workspaceService, @@ -149,6 +163,11 @@ func newFlowTestFixture(t *testing.T) *flowTestFixture { HTTPBodyUrlEncoded: httpBodyUrlEncodedService, HTTPBodyRaw: httpBodyRawService, HTTPAssert: httpAssertService, + NodeWsConnection: nodeWsConnectionService, + NodeWsSend: nodeWsSendService, + NodeWait: nodeWaitService, + WebSocket: webSocketService, + WebSocketHeader: webSocketHeaderService, Logger: logger, } @@ -763,3 +782,103 @@ flows: t.Error("OrphanRequest should NOT have been executed (it's an orphan node)") } } + +// echoWSServer creates a test WebSocket server that echoes messages back. +func echoWSServer(t *testing.T) *httptest.Server { + t.Helper() + return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + conn, err := websocket.Accept(w, r, nil) + if err != nil { + return + } + defer conn.Close(websocket.StatusNormalClosure, "") //nolint:errcheck // best-effort cleanup + for { + typ, msg, err := conn.Read(r.Context()) + if err != nil { + return + } + if err := conn.Write(r.Context(), typ, msg); err != nil { + return + } + } + })) +} + +func wsURL(s *httptest.Server) string { + return "ws" + strings.TrimPrefix(s.URL, "http") +} + +// TestFlowRun_WebSocket tests a flow with WebSocket connection and send nodes. +func TestFlowRun_WebSocket(t *testing.T) { + if testing.Short() { + t.Skip("skipping integration test in short mode") + } + + fixture := newFlowTestFixture(t) + + wsSrv := echoWSServer(t) + defer wsSrv.Close() + + yamlContent := fmt.Sprintf(`workspace_name: WS Test +flows: + - name: WSFlow + steps: + - manual_start: + name: Start + - ws_connection: + name: MyWS + depends_on: Start + url: %s + - ws_send: + name: SendHello + depends_on: MyWS + ws_connection_node_name: MyWS + message: '{"hello":"world"}' +`, wsURL(wsSrv)) + + resolved, err := yamlflowsimplev2.ConvertSimplifiedYAML([]byte(yamlContent), yamlflowsimplev2.ConvertOptionsV2{ + WorkspaceID: fixture.workspaceID, + }) + if err != nil { + t.Fatalf("failed to convert YAML: %v", err) + } + + fixture.importWorkspaceBundle(resolved) + + flow := fixture.getFlowByName("WSFlow") + if flow == nil { + t.Fatal("WSFlow not found") + } + + ctx, cancel := context.WithTimeout(fixture.ctx, 10*time.Second) + defer cancel() + + result, err := runner.RunFlow(ctx, flow, fixture.getRunnerServices(nil), nil) + + if err != nil { + t.Errorf("flow execution failed: %v", err) + } + + if result.Status != "success" { + t.Errorf("expected status 'success', got '%s'. Error: %s", result.Status, result.Error) + } + + // Verify both WS nodes were executed + foundConn := false + foundSend := false + for _, node := range result.Nodes { + switch node.Name { + case "MyWS": + foundConn = true + case "SendHello": + foundSend = true + } + } + + if !foundConn { + t.Error("WS connection node 'MyWS' was not executed") + } + if !foundSend { + t.Error("WS send node 'SendHello' was not executed") + } +} diff --git a/apps/cli/test/yamlflow/integration_yamlflow_test.go b/apps/cli/test/yamlflow/integration_yamlflow_test.go index 95d09ed26..a53ee1f17 100644 --- a/apps/cli/test/yamlflow/integration_yamlflow_test.go +++ b/apps/cli/test/yamlflow/integration_yamlflow_test.go @@ -76,3 +76,4 @@ func TestYAMLFlow_TestRunField(t *testing.T) { func TestYAMLFlow_GraphQLRun(t *testing.T) { runCLI(t, "graphql_run_example.yaml") } + diff --git a/apps/cli/test/yamlflow/ws_run_example.yaml b/apps/cli/test/yamlflow/ws_run_example.yaml new file mode 100644 index 000000000..400c8ce6c --- /dev/null +++ b/apps/cli/test/yamlflow/ws_run_example.yaml @@ -0,0 +1,57 @@ +workspace_name: New Workspace +run: + - flow: ws-integration +flows: + - name: ws-integration + steps: + - manual_start: + name: Start + position_x: -182.05 + position_y: -3.7 + - wait: + name: wait_4 + depends_on: Start + position_x: 201 + position_y: -139.77 + duration_ms: '8000' + - ws_connection: + name: ws_connection_5 + depends_on: Start + position_x: 218.43 + position_y: -3.21 + url: http://localhost:8080/ + - for: + name: for_6 + depends_on: ws_connection_5 + position_x: 462.56 + position_y: -146.17 + iter_count: '10' + - wait: + name: wait_7 + depends_on: ws_connection_5 + position_x: 470.57 + position_y: 88.8 + duration_ms: '1000' + - ws_send: + name: ws_send_6 + depends_on: for_6.loop + position_x: 592.26 + position_y: -52.7 + ws_connection_node_name: ws_connection_5 + message: '{"a":"{{ for_6.index }}"}' + - ws_send: + name: ws_send_6_1 + depends_on: wait_7 + position_x: 631.96 + position_y: 99.13 + ws_connection_node_name: ws_connection_5 + message: '{"a":"2"}' + - wait: + name: wait_7 + depends_on: ws_send_6 + position_x: 803.84 + position_y: -54.89 + duration_ms: '1000' +environments: + - name: default + variables: {} diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 5e22dcbe5..d617a2a1c 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -37,7 +37,7 @@ "electron": "catalog:", "electron-builder": "catalog:", "electron-devtools-installer": "catalog:", - "electron-updater": "6.7.3", + "electron-updater": "catalog:", "electron-vite": "catalog:", "eslint": "catalog:", "react": "catalog:", diff --git a/apps/desktop/src/renderer/main.tsx b/apps/desktop/src/renderer/main.tsx index d1fee1941..a79d93a31 100644 --- a/apps/desktop/src/renderer/main.tsx +++ b/apps/desktop/src/renderer/main.tsx @@ -68,7 +68,7 @@ const UpdateAvailable = ({ children }: UpdateAvailableProps) => {
Update available!
- {/* eslint-disable-next-line better-tailwindcss/no-unregistered-classes */} + {/* eslint-disable-next-line better-tailwindcss/no-unknown-classes */}
{children}
diff --git a/go.work.sum b/go.work.sum index f04746243..1b3e66c8e 100644 --- a/go.work.sum +++ b/go.work.sum @@ -25,18 +25,12 @@ cloud.google.com/go v0.112.2/go.mod h1:iEqjp//KquGIJV/m+Pk3xecgKNhV+ry+vVTsy4TbD cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= cloud.google.com/go v0.118.3/go.mod h1:Lhs3YLnBlwJ4KA6nuObNMZ/fCbOQBPuWKPoE0Wa/9Vc= cloud.google.com/go v0.120.0/go.mod h1:/beW32s8/pGRuj4IILWQNd4uuebeT4dkOhKmkfit64Q= -cloud.google.com/go v0.121.2 h1:v2qQpN6Dx9x2NmwrqlesOt3Ys4ol5/lFZ6Mg1B7OJCg= -cloud.google.com/go v0.121.2/go.mod h1:nRFlrHq39MNVWu+zESP2PosMWA0ryJw8KUBZ2iZpxbw= cloud.google.com/go/accessapproval v1.8.6/go.mod h1:FfmTs7Emex5UvfnnpMkhuNkRCP85URnBFt5ClLxhZaQ= cloud.google.com/go/accessapproval v1.8.8/go.mod h1:RFwPY9JDKseP4gJrX1BlAVsP5O6kI8NdGlTmaeDefmk= cloud.google.com/go/accesscontextmanager v1.9.6/go.mod h1:884XHwy1AQpCX5Cj2VqYse77gfLaq9f8emE2bYriilk= cloud.google.com/go/accesscontextmanager v1.9.7/go.mod h1:i6e0nd5CPcrh7+YwGq4bKvju5YB9sgoAip+mXU73aMM= cloud.google.com/go/ai v0.8.0 h1:rXUEz8Wp2OlrM8r1bfmpF2+VKqc1VJpafE3HgzRnD/w= cloud.google.com/go/ai v0.8.0/go.mod h1:t3Dfk4cM61sytiggo2UyGsDVW3RF1qGZaUKDrZFyqkE= -cloud.google.com/go/ai v0.12.1 h1:m1n/VjUuHS+pEO/2R4/VbuuEIkgk0w67fDQvFaMngM0= -cloud.google.com/go/ai v0.12.1/go.mod h1:5vIPNe1ZQsVZqCliXIPL4QnhObQQY4d9hAGHdVc4iw4= -cloud.google.com/go/aiplatform v1.89.0 h1:niSJYc6ldWWVM9faXPo1Et1MVSQoLvVGriD7fwbJdtE= -cloud.google.com/go/aiplatform v1.89.0/go.mod h1:TzZtegPkinfXTtXVvZZpxx7noINFMVDrLkE7cEWhYEk= cloud.google.com/go/aiplatform v1.109.0/go.mod h1:4rwKOMdubQOND81AlO3EckcskvEFCYSzXKfn42GMm8k= cloud.google.com/go/alloydb v1.14.0/go.mod h1:OTBY1HoL0Z8PsHoMMVhkaUPKyY8oP7hzIAe/Dna6UHk= cloud.google.com/go/alloydbconn v1.13.2/go.mod h1:0wlYQAOr2XuvxYsvNNVckmG2v17WVUKzMD+gmTOibSU= @@ -67,12 +61,8 @@ cloud.google.com/go/auth v0.16.0/go.mod h1:1howDHJ5IETh/LwYs3ZxvlkXF48aSqqJUM+5o cloud.google.com/go/auth v0.16.1/go.mod h1:1howDHJ5IETh/LwYs3ZxvlkXF48aSqqJUM+5o02dNOI= cloud.google.com/go/auth v0.16.2 h1:QvBAGFPLrDeoiNjyfVunhQ10HKNYuOwZ5noee0M5df4= cloud.google.com/go/auth v0.16.2/go.mod h1:sRBas2Y1fB1vZTdurouM0AzuYQBMZinrUYL8EufhtEA= -cloud.google.com/go/auth v0.16.3 h1:kabzoQ9/bobUmnseYnBO6qQG7q4a/CffFRlJSxv2wCc= -cloud.google.com/go/auth v0.16.3/go.mod h1:NucRGjaXfzP1ltpcQ7On/VTZ0H4kWB5Jy+Y9Dnm76fA= cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q= cloud.google.com/go/auth/oauth2adapt v0.2.6/go.mod h1:AlmsELtlEBnaNTL7jCj8VQFLy6mbZv0s4Q7NGBeQ5E8= -cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= -cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/automl v1.14.7/go.mod h1:8a4XbIH5pdvrReOU72oB+H3pOw2JBxo9XTk39oljObE= cloud.google.com/go/automl v1.15.0/go.mod h1:U9zOtQb8zVrFNGTuW3BfxeqmLyeleLgT9B12EaXfODg= cloud.google.com/go/baremetalsolution v1.3.6/go.mod h1:7/CS0LzpLccRGO0HL3q2Rofxas2JwjREKut414sE9iM= @@ -115,8 +105,6 @@ cloud.google.com/go/compute v1.49.1/go.mod h1:1uoZvP8Avyfhe3Y4he7sMOR16ZiAm2Q+Rc cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/compute/metadata v0.5.2 h1:UxK4uu/Tn+I3p2dYWTfiX4wva7aYlKixAHn3fyqngqo= cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k= -cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU= -cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo= cloud.google.com/go/contactcenterinsights v1.17.3/go.mod h1:7Uu2CpxS3f6XxhRdlEzYAkrChpR5P5QfcdGAFEdHOG8= cloud.google.com/go/contactcenterinsights v1.17.4/go.mod h1:kZe6yOnKDfpPz2GphDHynxk/Spx+53UX/pGf+SmWAKM= cloud.google.com/go/container v1.43.0/go.mod h1:ETU9WZ1KM9ikEKLzrhRVao7KHtalDQu6aPqM34zDr/U= @@ -182,8 +170,6 @@ cloud.google.com/go/gkemulticloud v1.5.4/go.mod h1:7l9+6Tp4jySSGj4PStO8CE6RrHFdc cloud.google.com/go/grafeas v0.3.15/go.mod h1:irwcwIQOBlLBotGdMwme8PipnloOPqILfIvMwlmu8Pk= cloud.google.com/go/gsuiteaddons v1.7.7/go.mod h1:zTGmmKG/GEBCONsvMOY2ckDiEsq3FN+lzWGUiXccF9o= cloud.google.com/go/gsuiteaddons v1.7.8/go.mod h1:DBKNHH4YXAdd/rd6zVvtOGAJNGo0ekOh+nIjTUDEJ5U= -cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8= -cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE= cloud.google.com/go/iam v1.5.3/go.mod h1:MR3v9oLkZCTlaqljW6Eb2d3HGDGK5/bDv93jhfISFvU= cloud.google.com/go/iap v1.11.2/go.mod h1:Bh99DMUpP5CitL9lK0BC8MYgjjYO4b3FbyhgW1VHJvg= cloud.google.com/go/iap v1.11.3/go.mod h1:+gXO0ClH62k2LVlfhHzrpiHQNyINlEVmGAE3+DB4ShU= @@ -203,8 +189,6 @@ cloud.google.com/go/longrunning v0.5.6/go.mod h1:vUaDrWYOMKRuhiv6JBnn49YxCPz2Ayn cloud.google.com/go/longrunning v0.5.7 h1:WLbHekDbjK1fVFD3ibpFFVoyizlLRl73I7YKuAKilhU= cloud.google.com/go/longrunning v0.5.7/go.mod h1:8GClkudohy1Fxm3owmBGid8W0pSgodEMwEAztp38Xng= cloud.google.com/go/longrunning v0.6.6/go.mod h1:hyeGJUrPHcx0u2Uu1UFSoYZLn4lkMrccJig0t4FI7yw= -cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE= -cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY= cloud.google.com/go/longrunning v0.7.0/go.mod h1:ySn2yXmjbK9Ba0zsQqunhDkYi0+9rlXIwnoAf+h+TPY= cloud.google.com/go/managedidentities v1.7.6/go.mod h1:pYCWPaI1AvR8Q027Vtp+SFSM/VOVgbjBF4rxp1/z5p4= cloud.google.com/go/managedidentities v1.7.7/go.mod h1:nwNlMxtBo2YJMvsKXRtAD1bL41qiCI9npS7cbqrsJUs= @@ -472,7 +456,6 @@ github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHf github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cristalhq/acmd v0.12.0 h1:RdlKnxjN+txbQosg8p/TRNZ+J1Rdne43MVQZ1zDhGWk= github.com/cristalhq/acmd v0.12.0/go.mod h1:LG5oa43pE/BbxtfMoImHCQN++0Su7dzipdgBjMCBVDQ= github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 h1:iwZdTE0PVqJCos1vaoKsclOGD3ADKpshg3SRtYBbwso= @@ -605,8 +588,6 @@ github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl76 github.com/google/flatbuffers v23.5.26+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/generative-ai-go v0.19.0 h1:R71szggh8wHMCUlEMsW2A/3T+5LdEIkiaHSYgSpUgdg= github.com/google/generative-ai-go v0.19.0/go.mod h1:JYolL13VG7j79kM5BtHz4qwONHkeJQzOCkKXnpqtS/E= -github.com/google/generative-ai-go v0.20.1 h1:6dEIujpgN2V0PgLhr6c/M1ynRdc7ARtiIDPFzj45uNQ= -github.com/google/generative-ai-go v0.20.1/go.mod h1:TjOnZJmZKzarWbjUJgy+r3Ee7HGBRVLhOIgupnwR4Bg= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -646,22 +627,19 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/cloud-bigtable-clients-test v0.0.3/go.mod h1:TWtDzrrAI70C3dNLDY+nZN3gxHtFdZIbpL9rCTFyxE0= github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/enterprise-certificate-proxy v0.3.5/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= -github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= -github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= github.com/googleapis/gax-go/v2 v2.12.5/go.mod h1:BUDKcWo+RaKq5SC9vVYL0wLADa3VcfswbOMMRmB9H3E= github.com/googleapis/gax-go/v2 v2.14.2 h1:eBLnkZ9635krYIPD+ag1USrOAI0Nr0QYF3+/3GqO0k0= github.com/googleapis/gax-go/v2 v2.14.2/go.mod h1:ON64QhlJkhVtSqp4v1uaK92VyZ2gmvDQsweuyLV+8+w= -github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo= -github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= github.com/goph/emperror v0.17.2 h1:yLapQcmEsO0ipe9p5TaN22djm3OFV/TfM/fcYP0/J18= github.com/goph/emperror v0.17.2/go.mod h1:+ZbQ+fUNO/6FNiUo0ujtMjhgad9Xa6fQL9KhH4LNHic= github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= @@ -735,7 +713,6 @@ github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= @@ -829,7 +806,6 @@ github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2 github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pinecone-io/go-pinecone v0.4.1/go.mod h1:KwWSueZFx9zccC+thBk13+LDiOgii8cff9bliUI4tQs= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= @@ -847,7 +823,6 @@ github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71 h1:CN github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50= github.com/redis/rueidis v1.0.34/go.mod h1:g8nPmgR4C68N3abFiOc/gUOSEKw3Tom6/teYMehg4RE= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -990,8 +965,6 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.5 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0/go.mod h1:vy+2G/6NvVMpwGX/NyLqcC41fxepnuKHk16E6IZUcJc= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= @@ -1253,8 +1226,6 @@ golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= -golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= -golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1346,8 +1317,6 @@ google.golang.org/api v0.235.0/go.mod h1:QpeJkemzkFKe5VCE/PMv7GsUfn9ZF+u+q1Q7w6c google.golang.org/api v0.237.0 h1:MP7XVsGZesOsx3Q8WVa4sUdbrsTvDSOERd3Vh4xj/wc= google.golang.org/api v0.237.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50= google.golang.org/api v0.239.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50= -google.golang.org/api v0.246.0 h1:H0ODDs5PnMZVZAEtdLMn2Ul2eQi7QNjqM2DIFp8TlTM= -google.golang.org/api v0.246.0/go.mod h1:dMVhVcylamkirHdzEBAIQWUCgqY885ivNeZYd7VAVr8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1398,8 +1367,6 @@ google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:sAo5UzpjUwgFBCzupwhcLcxHVDK7vG5IqI30YnwX2eE= google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:49MsLSx0oWMOZqcpB3uL8ZOkAh1+TndpJ8ONoCBWiZk= -google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= -google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= google.golang.org/genproto/googleapis/api v0.0.0-20240429193739-8cf5692501f6/go.mod h1:10yRODfgim2/T8csjQsMPgZOMvtytXKTDRzH6HRGzRw= google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= @@ -1528,6 +1495,7 @@ modernc.org/scannertest v1.0.2 h1:JPtfxcVdbRvzmRf2YUvsDibJsQRw8vKA/3jb31y7cy0= modernc.org/scannertest v1.0.2/go.mod h1:RzTm5RwglF/6shsKoEivo8N91nQIoWtcWI7ns+zPyGA= modernc.org/y v1.1.0 h1:JdIvLry+rKeSsVNRCdr6YWYimwwNm0GXtzxid77VfWc= modernc.org/y v1.1.0/go.mod h1:Iz3BmyIS4OwAbwGaUS7cqRrLsSsfp2sFWtpzX+P4CsE= +nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/install.ps1 b/install.ps1 new file mode 100644 index 000000000..c16f16ef1 --- /dev/null +++ b/install.ps1 @@ -0,0 +1,722 @@ +# Issue Tracker: https://github.com/ScoopInstaller/Install/issues +# Unlicense License: +# +# This is free and unencumbered software released into the public domain. +# +# Anyone is free to copy, modify, publish, use, compile, sell, or +# distribute this software, either in source code form or as a compiled +# binary, for any purpose, commercial or non-commercial, and by any +# means. +# +# In jurisdictions that recognize copyright laws, the author or authors +# of this software dedicate any and all copyright interest in the +# software to the public domain. We make this dedication for the benefit +# of the public at large and to the detriment of our heirs and +# successors. We intend this dedication to be an overt act of +# relinquishment in perpetuity of all present and future rights to this +# software under copyright law. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +# For more information, please refer to + +<# +.SYNOPSIS + Scoop installer. +.DESCRIPTION + The installer of Scoop. For details please check the website and wiki. +.PARAMETER ScoopDir + Specifies Scoop root path. + If not specified, Scoop will be installed to '$env:USERPROFILE\scoop'. +.PARAMETER ScoopGlobalDir + Specifies directory to store global apps. + If not specified, global apps will be installed to '$env:ProgramData\scoop'. +.PARAMETER ScoopCacheDir + Specifies cache directory. + If not specified, caches will be downloaded to '$ScoopDir\cache'. +.PARAMETER NoProxy + Bypass system proxy during the installation. +.PARAMETER Proxy + Specifies proxy to use during the installation. +.PARAMETER ProxyCredential + Specifies credential for the given proxy. +.PARAMETER ProxyUseDefaultCredentials + Use the credentials of the current user for the proxy server that is specified by the -Proxy parameter. +.PARAMETER RunAsAdmin + Force to run the installer as administrator. +.LINK + https://scoop.sh +.LINK + https://github.com/ScoopInstaller/Scoop/wiki +#> +param( + [String] $ScoopDir, + [String] $ScoopGlobalDir, + [String] $ScoopCacheDir, + [Switch] $NoProxy, + [Uri] $Proxy, + [System.Management.Automation.PSCredential] $ProxyCredential, + [Switch] $ProxyUseDefaultCredentials, + [Switch] $RunAsAdmin +) + +# Disable StrictMode in this script +Set-StrictMode -Off + +function Write-InstallInfo { + param( + [Parameter(Mandatory = $True, Position = 0)] + [String] $String, + [Parameter(Mandatory = $False, Position = 1)] + [System.ConsoleColor] $ForegroundColor = $host.UI.RawUI.ForegroundColor + ) + + $backup = $host.UI.RawUI.ForegroundColor + + if ($ForegroundColor -ne $host.UI.RawUI.ForegroundColor) { + $host.UI.RawUI.ForegroundColor = $ForegroundColor + } + + Write-Output "$String" + + $host.UI.RawUI.ForegroundColor = $backup +} + +function Exit-Install { + param( + [Int] $ErrorCode = 1 + ) + + if ($IS_EXECUTED_FROM_IEX) { + # Don't abort with `exit` that would close the PS session if invoked + # with iex, yet set `LASTEXITCODE` for the caller to check + $Global:LASTEXITCODE = $ErrorCode + break + } else { + exit $ErrorCode + } +} + +function Deny-Install { + param( + [String] $Message, + [Int] $ErrorCode = 1 + ) + + Write-InstallInfo -String $Message -ForegroundColor DarkRed + Write-InstallInfo 'Abort.' + Exit-Install -ErrorCode $ErrorCode +} + +function Test-LanguageMode { + if ($ExecutionContext.SessionState.LanguageMode -ne 'FullLanguage') { + # `Write-InstallInfo` cannot be used here as it depends on FullLanguage mode + Write-Output 'Scoop requires PowerShell FullLanguage mode to run, current PowerShell environment is restricted.' + Write-Output 'Abort.' + Exit-Install + } +} + +function Test-ValidateParameter { + if ($null -eq $Proxy -and ($null -ne $ProxyCredential -or $ProxyUseDefaultCredentials)) { + Deny-Install 'Provide a valid proxy URI for the -Proxy parameter when using the -ProxyCredential or -ProxyUseDefaultCredentials.' + } + + if ($ProxyUseDefaultCredentials -and $null -ne $ProxyCredential) { + Deny-Install "ProxyUseDefaultCredentials is conflict with ProxyCredential. Don't use the -ProxyCredential and -ProxyUseDefaultCredentials together." + } +} + +function Test-IsAdministrator { + return ([Security.Principal.WindowsPrincipal]` + [Security.Principal.WindowsIdentity]::GetCurrent()` + ).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) +} + +function Test-Prerequisite { + # Scoop requires PowerShell 5 at least + if (($PSVersionTable.PSVersion.Major) -lt 5) { + Deny-Install 'PowerShell 5 or later is required to run Scoop. Go to https://microsoft.com/powershell to get the latest version of PowerShell.' + } + + # Scoop requires TLS 1.2 SecurityProtocol, which exists in .NET Framework 4.5+ + if ([System.Enum]::GetNames([System.Net.SecurityProtocolType]) -notcontains 'Tls12') { + Deny-Install 'Scoop requires .NET Framework 4.5+ to work. Go to https://microsoft.com/net/download to get the latest version of .NET Framework.' + } + + # Ensure Robocopy.exe is accessible + if (!(Test-CommandAvailable('robocopy'))) { + Deny-Install "Scoop requires 'C:\Windows\System32\Robocopy.exe' to work. Please make sure 'C:\Windows\System32' is in your PATH." + } + + # Detect if RunAsAdministrator, there is no need to run as administrator when installing Scoop + if (!$RunAsAdmin -and (Test-IsAdministrator)) { + # Exception: Windows Sandbox, GitHub Actions CI + $exception = ($env:USERNAME -eq 'WDAGUtilityAccount') -or ($env:GITHUB_ACTIONS -eq 'true' -and $env:CI -eq 'true') + if (!$exception) { + Deny-Install 'Running the installer as administrator is disabled by default, see https://github.com/ScoopInstaller/Install#for-admin for details.' + } + } + + # Show notification to change execution policy + $allowedExecutionPolicy = @('Unrestricted', 'RemoteSigned', 'ByPass') + if ((Get-ExecutionPolicy).ToString() -notin $allowedExecutionPolicy) { + Deny-Install "PowerShell requires an execution policy in [$($allowedExecutionPolicy -join ', ')] to run Scoop. For example, to set the execution policy to 'RemoteSigned' please run 'Set-ExecutionPolicy RemoteSigned -Scope CurrentUser'." + } + + # Test if scoop is installed, by checking if scoop command exists. + if (Test-CommandAvailable('scoop')) { + Deny-Install "Scoop is already installed. Run 'scoop update' to get the latest version." -ErrorCode 0 + } +} + +function Optimize-SecurityProtocol { + # .NET Framework 4.7+ has a default security protocol called 'SystemDefault', + # which allows the operating system to choose the best protocol to use. + # If SecurityProtocolType contains 'SystemDefault' (means .NET4.7+ detected) + # and the value of SecurityProtocol is 'SystemDefault', just do nothing on SecurityProtocol, + # 'SystemDefault' will use TLS 1.2 if the webrequest requires. + $isNewerNetFramework = ([System.Enum]::GetNames([System.Net.SecurityProtocolType]) -contains 'SystemDefault') + $isSystemDefault = ([System.Net.ServicePointManager]::SecurityProtocol.Equals([System.Net.SecurityProtocolType]::SystemDefault)) + + # If not, change it to support TLS 1.2 + if (!($isNewerNetFramework -and $isSystemDefault)) { + # Set to TLS 1.2 (3072), then TLS 1.1 (768), and TLS 1.0 (192). Ssl3 has been superseded, + # https://docs.microsoft.com/en-us/dotnet/api/system.net.securityprotocoltype?view=netframework-4.5 + [System.Net.ServicePointManager]::SecurityProtocol = 3072 -bor 768 -bor 192 + Write-Verbose 'SecurityProtocol has been updated to support TLS 1.2' + } +} + +function Get-Downloader { + $downloadSession = New-Object System.Net.WebClient + + # Set proxy to null if NoProxy is specified + if ($NoProxy) { + $downloadSession.Proxy = $null + } elseif ($Proxy) { + # Prepend protocol if not provided + if (!$Proxy.IsAbsoluteUri) { + $Proxy = New-Object System.Uri('http://' + $Proxy.OriginalString) + } + + $Proxy = New-Object System.Net.WebProxy($Proxy) + + if ($null -ne $ProxyCredential) { + $Proxy.Credentials = $ProxyCredential.GetNetworkCredential() + } elseif ($ProxyUseDefaultCredentials) { + $Proxy.UseDefaultCredentials = $true + } + + $downloadSession.Proxy = $Proxy + } + + return $downloadSession +} + +function Test-isFileLocked { + param( + [String] $path + ) + + $file = New-Object System.IO.FileInfo $path + + if (!(Test-Path $path)) { + return $false + } + + try { + $stream = $file.Open( + [System.IO.FileMode]::Open, + [System.IO.FileAccess]::ReadWrite, + [System.IO.FileShare]::None + ) + if ($stream) { + $stream.Close() + } + return $false + } catch { + # The file is locked by a process. + return $true + } +} + +function Expand-ZipArchive { + param( + [String] $path, + [String] $to + ) + + if (!(Test-Path $path)) { + Deny-Install "Unzip failed: can't find $path to unzip." + } + + # Check if the zip file is locked, by antivirus software for example + $retries = 0 + while ($retries -le 10) { + if ($retries -eq 10) { + Deny-Install "Unzip failed: can't unzip because a process is locking the file." + } + if (Test-isFileLocked $path) { + Write-InstallInfo "Waiting for $path to be unlocked by another process... ($retries/10)" + $retries++ + Start-Sleep -Seconds 2 + } else { + break + } + } + + # Workaround to suspend Expand-Archive verbose output, + # upstream issue: https://github.com/PowerShell/Microsoft.PowerShell.Archive/issues/98 + $oldVerbosePreference = $VerbosePreference + $global:VerbosePreference = 'SilentlyContinue' + + # Disable progress bar to gain performance + $oldProgressPreference = $ProgressPreference + $global:ProgressPreference = 'SilentlyContinue' + + # PowerShell 5+: use Expand-Archive to extract zip files + Microsoft.PowerShell.Archive\Expand-Archive -Path $path -DestinationPath $to -Force + $global:VerbosePreference = $oldVerbosePreference + $global:ProgressPreference = $oldProgressPreference +} + +function Out-UTF8File { + param( + [Parameter(Mandatory = $True, Position = 0)] + [Alias('Path')] + [String] $FilePath, + [Switch] $Append, + [Switch] $NoNewLine, + [Parameter(ValueFromPipeline = $True)] + [PSObject] $InputObject + ) + process { + if ($Append) { + [System.IO.File]::AppendAllText($FilePath, $InputObject) + } else { + if (!$NoNewLine) { + # Ref: https://stackoverflow.com/questions/5596982 + # Performance Note: `WriteAllLines` throttles memory usage while + # `WriteAllText` needs to keep the complete string in memory. + [System.IO.File]::WriteAllLines($FilePath, $InputObject) + } else { + # However `WriteAllText` does not add ending newline. + [System.IO.File]::WriteAllText($FilePath, $InputObject) + } + } + } +} + +function Import-ScoopShim { + Write-InstallInfo 'Creating shim...' + # The scoop executable + $path = "$SCOOP_APP_DIR\bin\scoop.ps1" + + if (!(Test-Path $SCOOP_SHIMS_DIR)) { + New-Item -Type Directory $SCOOP_SHIMS_DIR | Out-Null + } + + # The scoop shim + $shim = "$SCOOP_SHIMS_DIR\scoop" + + # Convert to relative path + Push-Location $SCOOP_SHIMS_DIR + $relativePath = Resolve-Path -Relative $path + Pop-Location + $absolutePath = Resolve-Path $path + + # if $path points to another drive resolve-path prepends .\ which could break shims + $ps1text = if ($relativePath -match '^(\.\\)?\w:.*$') { + @( + "# $absolutePath", + "`$path = `"$path`"", + "if (`$MyInvocation.ExpectingInput) { `$input | & `$path $arg @args } else { & `$path $arg @args }", + "exit `$LASTEXITCODE" + ) + } else { + @( + "# $absolutePath", + "`$path = Join-Path `$PSScriptRoot `"$relativePath`"", + "if (`$MyInvocation.ExpectingInput) { `$input | & `$path $arg @args } else { & `$path $arg @args }", + "exit `$LASTEXITCODE" + ) + } + $ps1text -join "`r`n" | Out-UTF8File "$shim.ps1" + + # make ps1 accessible from cmd.exe + @( + "@rem $absolutePath", + '@echo off', + 'setlocal enabledelayedexpansion', + 'set args=%*', + ':: replace problem characters in arguments', + "set args=%args:`"='%", + "set args=%args:(=``(%", + "set args=%args:)=``)%", + "set invalid=`"='", + 'if !args! == !invalid! ( set args= )', + 'where /q pwsh.exe', + 'if %errorlevel% equ 0 (', + " pwsh -noprofile -ex unrestricted -file `"$absolutePath`" $arg %args%", + ') else (', + " powershell -noprofile -ex unrestricted -file `"$absolutePath`" $arg %args%", + ')' + ) -join "`r`n" | Out-UTF8File "$shim.cmd" + + @( + '#!/bin/sh', + "# $absolutePath", + 'if command -v pwsh.exe > /dev/null 2>&1; then', + " pwsh.exe -noprofile -ex unrestricted -file `"$absolutePath`" $arg `"$@`"", + 'else', + " powershell.exe -noprofile -ex unrestricted -file `"$absolutePath`" $arg `"$@`"", + 'fi' + ) -join "`n" | Out-UTF8File $shim -NoNewLine +} + +function Get-Env { + param( + [String] $name, + [Switch] $global + ) + + $RegisterKey = if ($global) { + Get-Item -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' + } else { + Get-Item -Path 'HKCU:' + } + + $EnvRegisterKey = $RegisterKey.OpenSubKey('Environment') + $RegistryValueOption = [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames + $EnvRegisterKey.GetValue($name, $null, $RegistryValueOption) +} + +function Publish-Env { + if (-not ('Win32.NativeMethods' -as [Type])) { + Add-Type -Namespace Win32 -Name NativeMethods -MemberDefinition @' +[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] +public static extern IntPtr SendMessageTimeout( + IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam, + uint fuFlags, uint uTimeout, out UIntPtr lpdwResult); +'@ + } + + $HWND_BROADCAST = [IntPtr] 0xffff + $WM_SETTINGCHANGE = 0x1a + $result = [UIntPtr]::Zero + + [Win32.Nativemethods]::SendMessageTimeout($HWND_BROADCAST, + $WM_SETTINGCHANGE, + [UIntPtr]::Zero, + 'Environment', + 2, + 5000, + [ref] $result + ) | Out-Null +} + +function Write-Env { + param( + [String] $name, + [String] $val, + [Switch] $global + ) + + $RegisterKey = if ($global) { + Get-Item -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' + } else { + Get-Item -Path 'HKCU:' + } + + $EnvRegisterKey = $RegisterKey.OpenSubKey('Environment', $true) + if ($val -eq $null) { + $EnvRegisterKey.DeleteValue($name) + } else { + $RegistryValueKind = if ($val.Contains('%')) { + [Microsoft.Win32.RegistryValueKind]::ExpandString + } elseif ($EnvRegisterKey.GetValue($name)) { + $EnvRegisterKey.GetValueKind($name) + } else { + [Microsoft.Win32.RegistryValueKind]::String + } + $EnvRegisterKey.SetValue($name, $val, $RegistryValueKind) + } + Publish-Env +} + +function Add-ShimsDirToPath { + # Get $env:PATH of current user + $userEnvPath = Get-Env 'PATH' + + if ($userEnvPath -notmatch [Regex]::Escape($SCOOP_SHIMS_DIR)) { + $h = (Get-PSProvider 'FileSystem').Home + if (!$h.EndsWith('\')) { + $h += '\' + } + + if (!($h -eq '\')) { + $friendlyPath = "$SCOOP_SHIMS_DIR" -replace ([Regex]::Escape($h)), '~\' + Write-InstallInfo "Adding $friendlyPath to your path." + } else { + Write-InstallInfo "Adding $SCOOP_SHIMS_DIR to your path." + } + + # For future sessions + Write-Env 'PATH' "$SCOOP_SHIMS_DIR;$userEnvPath" + # For current session + $env:PATH = "$SCOOP_SHIMS_DIR;$env:PATH" + } +} + +function Use-Config { + if (!(Test-Path $SCOOP_CONFIG_FILE)) { + return $null + } + + try { + return (Get-Content $SCOOP_CONFIG_FILE -Raw | ConvertFrom-Json -ErrorAction Stop) + } catch { + Deny-Install "ERROR loading $SCOOP_CONFIG_FILE`: $($_.Exception.Message)" + } +} + +function Add-Config { + param ( + [Parameter(Mandatory = $True, Position = 0)] + [String] $Name, + [Parameter(Mandatory = $True, Position = 1)] + [String] $Value + ) + + $scoopConfig = Use-Config + + if ($scoopConfig -is [System.Management.Automation.PSObject]) { + if ($Value -eq [bool]::TrueString -or $Value -eq [bool]::FalseString) { + $Value = [System.Convert]::ToBoolean($Value) + } + if ($null -eq $scoopConfig.$Name) { + $scoopConfig | Add-Member -MemberType NoteProperty -Name $Name -Value $Value + } else { + $scoopConfig.$Name = $Value + } + } else { + $baseDir = Split-Path -Path $SCOOP_CONFIG_FILE + if (!(Test-Path $baseDir)) { + New-Item -Type Directory $baseDir | Out-Null + } + + $scoopConfig = New-Object PSObject + $scoopConfig | Add-Member -MemberType NoteProperty -Name $Name -Value $Value + } + + if ($null -eq $Value) { + $scoopConfig.PSObject.Properties.Remove($Name) + } + + ConvertTo-Json $scoopConfig | Set-Content $SCOOP_CONFIG_FILE -Encoding ASCII + return $scoopConfig +} + +function Add-DefaultConfig { + # If user-level SCOOP env not defined, save to root_path + if (!(Get-Env 'SCOOP')) { + if ($SCOOP_DIR -ne "$env:USERPROFILE\scoop") { + Write-Verbose "Adding config root_path: $SCOOP_DIR" + Add-Config -Name 'root_path' -Value $SCOOP_DIR | Out-Null + } + } + + # Use system SCOOP_GLOBAL, or set system SCOOP_GLOBAL + # with $env:SCOOP_GLOBAL if RunAsAdmin, otherwise save to global_path + if (!(Get-Env 'SCOOP_GLOBAL' -global)) { + if ((Test-IsAdministrator) -and $env:SCOOP_GLOBAL) { + Write-Verbose "Setting System Environment Variable SCOOP_GLOBAL: $env:SCOOP_GLOBAL" + [Environment]::SetEnvironmentVariable('SCOOP_GLOBAL', $env:SCOOP_GLOBAL, 'Machine') + } else { + if ($SCOOP_GLOBAL_DIR -ne "$env:ProgramData\scoop") { + Write-Verbose "Adding config global_path: $SCOOP_GLOBAL_DIR" + Add-Config -Name 'global_path' -Value $SCOOP_GLOBAL_DIR | Out-Null + } + } + } + + # Use system SCOOP_CACHE, or set system SCOOP_CACHE + # with $env:SCOOP_CACHE if RunAsAdmin, otherwise save to cache_path + if (!(Get-Env 'SCOOP_CACHE' -global)) { + if ((Test-IsAdministrator) -and $env:SCOOP_CACHE) { + Write-Verbose "Setting System Environment Variable SCOOP_CACHE: $env:SCOOP_CACHE" + [Environment]::SetEnvironmentVariable('SCOOP_CACHE', $env:SCOOP_CACHE, 'Machine') + } else { + if ($SCOOP_CACHE_DIR -ne "$SCOOP_DIR\cache") { + Write-Verbose "Adding config cache_path: $SCOOP_CACHE_DIR" + Add-Config -Name 'cache_path' -Value $SCOOP_CACHE_DIR | Out-Null + } + } + } + + # save current datetime to last_update + Add-Config -Name 'last_update' -Value ([System.DateTime]::Now.ToString('o')) | Out-Null +} + +function Test-CommandAvailable { + param ( + [Parameter(Mandatory = $True, Position = 0)] + [String] $Command + ) + return [Boolean](Get-Command $Command -ErrorAction SilentlyContinue) +} + +function Install-Scoop { + Write-InstallInfo 'Initializing...' + # Validate install parameters + Test-ValidateParameter + # Check prerequisites + Test-Prerequisite + # Enable TLS 1.2 + Optimize-SecurityProtocol + + # Download scoop from GitHub + Write-InstallInfo 'Downloading...' + $downloader = Get-Downloader + [bool]$downloadZipsRequired = $True + + if (Test-CommandAvailable('git')) { + $old_https = $env:HTTPS_PROXY + $old_http = $env:HTTP_PROXY + try { + if ($downloader.Proxy) { + #define env vars for git when behind a proxy + $Env:HTTP_PROXY = $downloader.Proxy.Address + $Env:HTTPS_PROXY = $downloader.Proxy.Address + } + Write-Verbose "Cloning $SCOOP_PACKAGE_GIT_REPO to $SCOOP_APP_DIR" + git clone -q $SCOOP_PACKAGE_GIT_REPO $SCOOP_APP_DIR + if (-not $?) { + throw 'Cloning failed. Falling back to downloading zip files.' + } + Write-Verbose "Cloning $SCOOP_MAIN_BUCKET_GIT_REPO to $SCOOP_MAIN_BUCKET_DIR" + git clone -q $SCOOP_MAIN_BUCKET_GIT_REPO $SCOOP_MAIN_BUCKET_DIR + if (-not $?) { + throw 'Cloning failed. Falling back to downloading zip files.' + } + $downloadZipsRequired = $False + } catch { + Write-Warning "$($_.Exception.Message)" + $Global:LASTEXITCODE = 0 + } finally { + $env:HTTPS_PROXY = $old_https + $env:HTTP_PROXY = $old_http + } + } + + if ($downloadZipsRequired) { + # 1. download scoop + $scoopZipfile = "$SCOOP_APP_DIR\scoop.zip" + if (!(Test-Path $SCOOP_APP_DIR)) { + New-Item -Type Directory $SCOOP_APP_DIR | Out-Null + } + Write-Verbose "Downloading $SCOOP_PACKAGE_REPO to $scoopZipfile" + $downloader.downloadFile($SCOOP_PACKAGE_REPO, $scoopZipfile) + # 2. download scoop main bucket + $scoopMainZipfile = "$SCOOP_MAIN_BUCKET_DIR\scoop-main.zip" + if (!(Test-Path $SCOOP_MAIN_BUCKET_DIR)) { + New-Item -Type Directory $SCOOP_MAIN_BUCKET_DIR | Out-Null + } + Write-Verbose "Downloading $SCOOP_MAIN_BUCKET_REPO to $scoopMainZipfile" + $downloader.downloadFile($SCOOP_MAIN_BUCKET_REPO, $scoopMainZipfile) + + # Extract files from downloaded zip + Write-InstallInfo 'Extracting...' + # 1. extract scoop + $scoopUnzipTempDir = "$SCOOP_APP_DIR\_tmp" + Write-Verbose "Extracting $scoopZipfile to $scoopUnzipTempDir" + Expand-ZipArchive $scoopZipfile $scoopUnzipTempDir + Copy-Item "$scoopUnzipTempDir\scoop-*\*" $SCOOP_APP_DIR -Recurse -Force + # 2. extract scoop main bucket + $scoopMainUnzipTempDir = "$SCOOP_MAIN_BUCKET_DIR\_tmp" + Write-Verbose "Extracting $scoopMainZipfile to $scoopMainUnzipTempDir" + Expand-ZipArchive $scoopMainZipfile $scoopMainUnzipTempDir + Copy-Item "$scoopMainUnzipTempDir\Main-*\*" $SCOOP_MAIN_BUCKET_DIR -Recurse -Force + + # Cleanup + Remove-Item $scoopUnzipTempDir -Recurse -Force + Remove-Item $scoopZipfile + Remove-Item $scoopMainUnzipTempDir -Recurse -Force + Remove-Item $scoopMainZipfile + } + # Create the scoop shim + Import-ScoopShim + # Ensure scoop shims is in the PATH + Add-ShimsDirToPath + # Setup initial configuration of Scoop + Add-DefaultConfig + + Write-InstallInfo 'Scoop was installed successfully!' -ForegroundColor DarkGreen + Write-InstallInfo "Type 'scoop help' for instructions." +} + +function Write-DebugInfo { + param($BoundArgs) + + Write-Verbose '-------- PSBoundParameters --------' + $BoundArgs.GetEnumerator() | ForEach-Object { Write-Verbose $_ } + Write-Verbose '-------- Environment Variables --------' + Write-Verbose "`$env:USERPROFILE: $env:USERPROFILE" + Write-Verbose "`$env:ProgramData: $env:ProgramData" + Write-Verbose "`$env:SCOOP: $env:SCOOP" + Write-Verbose "`$env:SCOOP_CACHE: $SCOOP_CACHE" + Write-Verbose "`$env:SCOOP_GLOBAL: $env:SCOOP_GLOBAL" + Write-Verbose '-------- Selected Variables --------' + Write-Verbose "SCOOP_DIR: $SCOOP_DIR" + Write-Verbose "SCOOP_CACHE_DIR: $SCOOP_CACHE_DIR" + Write-Verbose "SCOOP_GLOBAL_DIR: $SCOOP_GLOBAL_DIR" + Write-Verbose "SCOOP_CONFIG_HOME: $SCOOP_CONFIG_HOME" +} + +# Prepare variables +$IS_EXECUTED_FROM_IEX = ($null -eq $MyInvocation.MyCommand.Path) + +# Abort when the language mode is restricted +Test-LanguageMode + +# Scoop root directory +$SCOOP_DIR = $ScoopDir, $env:SCOOP, "$env:USERPROFILE\scoop" | Where-Object { -not [String]::IsNullOrEmpty($_) } | Select-Object -First 1 +# Scoop global apps directory +$SCOOP_GLOBAL_DIR = $ScoopGlobalDir, $env:SCOOP_GLOBAL, "$env:ProgramData\scoop" | Where-Object { -not [String]::IsNullOrEmpty($_) } | Select-Object -First 1 +# Scoop cache directory +$SCOOP_CACHE_DIR = $ScoopCacheDir, $env:SCOOP_CACHE, "$SCOOP_DIR\cache" | Where-Object { -not [String]::IsNullOrEmpty($_) } | Select-Object -First 1 +# Scoop shims directory +$SCOOP_SHIMS_DIR = "$SCOOP_DIR\shims" +# Scoop itself directory +$SCOOP_APP_DIR = "$SCOOP_DIR\apps\scoop\current" +# Scoop main bucket directory +$SCOOP_MAIN_BUCKET_DIR = "$SCOOP_DIR\buckets\main" +# Scoop config file location +$SCOOP_CONFIG_HOME = $env:XDG_CONFIG_HOME, "$env:USERPROFILE\.config" | Select-Object -First 1 +$SCOOP_CONFIG_FILE = "$SCOOP_CONFIG_HOME\scoop\config.json" + +# TODO: Use a specific version of Scoop and the main bucket +$SCOOP_PACKAGE_REPO = 'https://github.com/ScoopInstaller/Scoop/archive/master.zip' +$SCOOP_MAIN_BUCKET_REPO = 'https://github.com/ScoopInstaller/Main/archive/master.zip' + +$SCOOP_PACKAGE_GIT_REPO = 'https://github.com/ScoopInstaller/Scoop.git' +$SCOOP_MAIN_BUCKET_GIT_REPO = 'https://github.com/ScoopInstaller/Main.git' + +# Quit if anything goes wrong +$oldErrorActionPreference = $ErrorActionPreference +$ErrorActionPreference = 'Stop' + +# Logging debug info +Write-DebugInfo $PSBoundParameters +# Bootstrap function +Install-Scoop + +# Reset $ErrorActionPreference to original value +$ErrorActionPreference = $oldErrorActionPreference diff --git a/packages/client/src/app/router/route-tree.gen.ts b/packages/client/src/app/router/route-tree.gen.ts index 6cd100d81..5d073f254 100644 --- a/packages/client/src/app/router/route-tree.gen.ts +++ b/packages/client/src/app/router/route-tree.gen.ts @@ -14,9 +14,11 @@ import { Route as dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDot import { Route as dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotUserRoutesSignInRouteImport } from './../../pages/user/routes/signIn' import { Route as dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWorkspaceRoutesWorkspaceWorkspaceIdCanRouteRouteImport } from './../../pages/workspace/routes/workspace/$workspaceIdCan/route' import { Route as dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWorkspaceRoutesWorkspaceWorkspaceIdCanIndexRouteImport } from './../../pages/workspace/routes/workspace/$workspaceIdCan/index' +import { Route as dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanRouteRouteImport } from './../../pages/websocket/routes/websocket/$websocketIdCan/route' import { Route as dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotHttpRoutesHttpHttpIdCanRouteRouteImport } from './../../pages/http/routes/http/$httpIdCan/route' import { Route as dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotGraphqlRoutesGraphqlGraphqlIdCanRouteRouteImport } from './../../pages/graphql/routes/graphql/$graphqlIdCan/route' import { Route as dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotFlowRoutesFlowFlowIdCanRouteRouteImport } from './../../pages/flow/routes/flow/$flowIdCan/route' +import { Route as dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanIndexRouteImport } from './../../pages/websocket/routes/websocket/$websocketIdCan/index' import { Route as dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotHttpRoutesHttpHttpIdCanIndexRouteImport } from './../../pages/http/routes/http/$httpIdCan/index' import { Route as dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotGraphqlRoutesGraphqlGraphqlIdCanIndexRouteImport } from './../../pages/graphql/routes/graphql/$graphqlIdCan/index' import { Route as dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotFlowRoutesFlowFlowIdCanIndexRouteImport } from './../../pages/flow/routes/flow/$flowIdCan/index' @@ -64,6 +66,15 @@ const dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWorkspace dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWorkspaceRoutesWorkspaceWorkspaceIdCanRouteRoute, } as any, ) +const dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanRouteRoute = + dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanRouteRouteImport.update( + { + id: '/(websocket)/websocket/$websocketIdCan', + path: '/websocket/$websocketIdCan', + getParentRoute: () => + dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWorkspaceRoutesWorkspaceWorkspaceIdCanRouteRoute, + } as any, + ) const dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotHttpRoutesHttpHttpIdCanRouteRoute = dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotHttpRoutesHttpHttpIdCanRouteRouteImport.update( { @@ -91,6 +102,15 @@ const dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotFlowRoute dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWorkspaceRoutesWorkspaceWorkspaceIdCanRouteRoute, } as any, ) +const dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanIndexRoute = + dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanIndexRouteImport.update( + { + id: '/', + path: '/', + getParentRoute: () => + dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanRouteRoute, + } as any, + ) const dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotHttpRoutesHttpHttpIdCanIndexRoute = dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotHttpRoutesHttpHttpIdCanIndexRouteImport.update( { @@ -164,11 +184,13 @@ export interface FileRoutesByFullPath { '/workspace/$workspaceIdCan/flow/$flowIdCan': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotFlowRoutesFlowFlowIdCanRouteRouteWithChildren '/workspace/$workspaceIdCan/graphql/$graphqlIdCan': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotGraphqlRoutesGraphqlGraphqlIdCanRouteRouteWithChildren '/workspace/$workspaceIdCan/http/$httpIdCan': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotHttpRoutesHttpHttpIdCanRouteRouteWithChildren + '/workspace/$workspaceIdCan/websocket/$websocketIdCan': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanRouteRouteWithChildren '/workspace/$workspaceIdCan/flow/$flowIdCan/history': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotFlowRoutesFlowFlowIdCanHistoryRoute - '/workspace/$workspaceIdCan/credential/$credentialIdCan': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotCredentialRoutesCredentialCredentialIdCanIndexRoute + '/workspace/$workspaceIdCan/credential/$credentialIdCan/': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotCredentialRoutesCredentialCredentialIdCanIndexRoute '/workspace/$workspaceIdCan/flow/$flowIdCan/': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotFlowRoutesFlowFlowIdCanIndexRoute '/workspace/$workspaceIdCan/graphql/$graphqlIdCan/': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotGraphqlRoutesGraphqlGraphqlIdCanIndexRoute '/workspace/$workspaceIdCan/http/$httpIdCan/': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotHttpRoutesHttpHttpIdCanIndexRoute + '/workspace/$workspaceIdCan/websocket/$websocketIdCan/': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanIndexRoute '/workspace/$workspaceIdCan/graphql/$graphqlIdCan/delta/$deltaGraphqlIdCan': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotGraphqlRoutesGraphqlGraphqlIdCanDeltaDotdeltaGraphqlIdCanRoute '/workspace/$workspaceIdCan/http/$httpIdCan/delta/$deltaHttpIdCan': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotHttpRoutesHttpHttpIdCanDeltaDotdeltaHttpIdCanRoute } @@ -182,6 +204,7 @@ export interface FileRoutesByTo { '/workspace/$workspaceIdCan/flow/$flowIdCan': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotFlowRoutesFlowFlowIdCanIndexRoute '/workspace/$workspaceIdCan/graphql/$graphqlIdCan': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotGraphqlRoutesGraphqlGraphqlIdCanIndexRoute '/workspace/$workspaceIdCan/http/$httpIdCan': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotHttpRoutesHttpHttpIdCanIndexRoute + '/workspace/$workspaceIdCan/websocket/$websocketIdCan': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanIndexRoute '/workspace/$workspaceIdCan/graphql/$graphqlIdCan/delta/$deltaGraphqlIdCan': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotGraphqlRoutesGraphqlGraphqlIdCanDeltaDotdeltaGraphqlIdCanRoute '/workspace/$workspaceIdCan/http/$httpIdCan/delta/$deltaHttpIdCan': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotHttpRoutesHttpHttpIdCanDeltaDotdeltaHttpIdCanRoute } @@ -195,11 +218,13 @@ export interface FileRoutesById { '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(flow)/flow/$flowIdCan': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotFlowRoutesFlowFlowIdCanRouteRouteWithChildren '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(graphql)/graphql/$graphqlIdCan': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotGraphqlRoutesGraphqlGraphqlIdCanRouteRouteWithChildren '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(http)/http/$httpIdCan': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotHttpRoutesHttpHttpIdCanRouteRouteWithChildren + '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(websocket)/websocket/$websocketIdCan': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanRouteRouteWithChildren '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(flow)/flow/$flowIdCan/history': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotFlowRoutesFlowFlowIdCanHistoryRoute '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(credential)/credential/$credentialIdCan/': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotCredentialRoutesCredentialCredentialIdCanIndexRoute '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(flow)/flow/$flowIdCan/': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotFlowRoutesFlowFlowIdCanIndexRoute '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(graphql)/graphql/$graphqlIdCan/': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotGraphqlRoutesGraphqlGraphqlIdCanIndexRoute '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(http)/http/$httpIdCan/': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotHttpRoutesHttpHttpIdCanIndexRoute + '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(websocket)/websocket/$websocketIdCan/': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanIndexRoute '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(graphql)/graphql/$graphqlIdCan/delta/$deltaGraphqlIdCan': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotGraphqlRoutesGraphqlGraphqlIdCanDeltaDotdeltaGraphqlIdCanRoute '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(http)/http/$httpIdCan/delta/$deltaHttpIdCan': typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotHttpRoutesHttpHttpIdCanDeltaDotdeltaHttpIdCanRoute } @@ -214,11 +239,13 @@ export interface FileRouteTypes { | '/workspace/$workspaceIdCan/flow/$flowIdCan' | '/workspace/$workspaceIdCan/graphql/$graphqlIdCan' | '/workspace/$workspaceIdCan/http/$httpIdCan' + | '/workspace/$workspaceIdCan/websocket/$websocketIdCan' | '/workspace/$workspaceIdCan/flow/$flowIdCan/history' - | '/workspace/$workspaceIdCan/credential/$credentialIdCan' + | '/workspace/$workspaceIdCan/credential/$credentialIdCan/' | '/workspace/$workspaceIdCan/flow/$flowIdCan/' | '/workspace/$workspaceIdCan/graphql/$graphqlIdCan/' | '/workspace/$workspaceIdCan/http/$httpIdCan/' + | '/workspace/$workspaceIdCan/websocket/$websocketIdCan/' | '/workspace/$workspaceIdCan/graphql/$graphqlIdCan/delta/$deltaGraphqlIdCan' | '/workspace/$workspaceIdCan/http/$httpIdCan/delta/$deltaHttpIdCan' fileRoutesByTo: FileRoutesByTo @@ -232,6 +259,7 @@ export interface FileRouteTypes { | '/workspace/$workspaceIdCan/flow/$flowIdCan' | '/workspace/$workspaceIdCan/graphql/$graphqlIdCan' | '/workspace/$workspaceIdCan/http/$httpIdCan' + | '/workspace/$workspaceIdCan/websocket/$websocketIdCan' | '/workspace/$workspaceIdCan/graphql/$graphqlIdCan/delta/$deltaGraphqlIdCan' | '/workspace/$workspaceIdCan/http/$httpIdCan/delta/$deltaHttpIdCan' id: @@ -244,11 +272,13 @@ export interface FileRouteTypes { | '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(flow)/flow/$flowIdCan' | '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(graphql)/graphql/$graphqlIdCan' | '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(http)/http/$httpIdCan' + | '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(websocket)/websocket/$websocketIdCan' | '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(flow)/flow/$flowIdCan/history' | '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(credential)/credential/$credentialIdCan/' | '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(flow)/flow/$flowIdCan/' | '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(graphql)/graphql/$graphqlIdCan/' | '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(http)/http/$httpIdCan/' + | '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(websocket)/websocket/$websocketIdCan/' | '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(graphql)/graphql/$graphqlIdCan/delta/$deltaGraphqlIdCan' | '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(http)/http/$httpIdCan/delta/$deltaHttpIdCan' fileRoutesById: FileRoutesById @@ -297,6 +327,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWorkspaceRoutesWorkspaceWorkspaceIdCanIndexRouteImport parentRoute: typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWorkspaceRoutesWorkspaceWorkspaceIdCanRouteRoute } + '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(websocket)/websocket/$websocketIdCan': { + id: '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(websocket)/websocket/$websocketIdCan' + path: '/websocket/$websocketIdCan' + fullPath: '/workspace/$workspaceIdCan/websocket/$websocketIdCan' + preLoaderRoute: typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanRouteRouteImport + parentRoute: typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWorkspaceRoutesWorkspaceWorkspaceIdCanRouteRoute + } '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(http)/http/$httpIdCan': { id: '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(http)/http/$httpIdCan' path: '/http/$httpIdCan' @@ -318,6 +355,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotFlowRoutesFlowFlowIdCanRouteRouteImport parentRoute: typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWorkspaceRoutesWorkspaceWorkspaceIdCanRouteRoute } + '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(websocket)/websocket/$websocketIdCan/': { + id: '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(websocket)/websocket/$websocketIdCan/' + path: '/' + fullPath: '/workspace/$workspaceIdCan/websocket/$websocketIdCan/' + preLoaderRoute: typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanIndexRouteImport + parentRoute: typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanRouteRoute + } '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(http)/http/$httpIdCan/': { id: '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(http)/http/$httpIdCan/' path: '/' @@ -342,7 +386,7 @@ declare module '@tanstack/react-router' { '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(credential)/credential/$credentialIdCan/': { id: '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(credential)/credential/$credentialIdCan/' path: '/credential/$credentialIdCan' - fullPath: '/workspace/$workspaceIdCan/credential/$credentialIdCan' + fullPath: '/workspace/$workspaceIdCan/credential/$credentialIdCan/' preLoaderRoute: typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotCredentialRoutesCredentialCredentialIdCanIndexRouteImport parentRoute: typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWorkspaceRoutesWorkspaceWorkspaceIdCanRouteRoute } @@ -424,11 +468,27 @@ const dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotHttpRoute dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotHttpRoutesHttpHttpIdCanRouteRouteChildren, ) +interface dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanRouteRouteChildren { + dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanIndexRoute: typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanIndexRoute +} + +const dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanRouteRouteChildren: dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanRouteRouteChildren = + { + dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanIndexRoute: + dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanIndexRoute, + } + +const dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanRouteRouteWithChildren = + dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanRouteRoute._addFileChildren( + dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanRouteRouteChildren, + ) + interface dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWorkspaceRoutesWorkspaceWorkspaceIdCanRouteRouteChildren { dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWorkspaceRoutesWorkspaceWorkspaceIdCanIndexRoute: typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWorkspaceRoutesWorkspaceWorkspaceIdCanIndexRoute dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotFlowRoutesFlowFlowIdCanRouteRoute: typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotFlowRoutesFlowFlowIdCanRouteRouteWithChildren dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotGraphqlRoutesGraphqlGraphqlIdCanRouteRoute: typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotGraphqlRoutesGraphqlGraphqlIdCanRouteRouteWithChildren dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotHttpRoutesHttpHttpIdCanRouteRoute: typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotHttpRoutesHttpHttpIdCanRouteRouteWithChildren + dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanRouteRoute: typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanRouteRouteWithChildren dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotCredentialRoutesCredentialCredentialIdCanIndexRoute: typeof dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotCredentialRoutesCredentialCredentialIdCanIndexRoute } @@ -442,6 +502,8 @@ const dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWorkspace dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotGraphqlRoutesGraphqlGraphqlIdCanRouteRouteWithChildren, dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotHttpRoutesHttpHttpIdCanRouteRoute: dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotHttpRoutesHttpHttpIdCanRouteRouteWithChildren, + dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanRouteRoute: + dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotWebsocketRoutesWebsocketWebsocketIdCanRouteRouteWithChildren, dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotCredentialRoutesCredentialCredentialIdCanIndexRoute: dashboardDotDotDotDotDotDotDotDotPagesDashboardRoutesDotDotDotDotCredentialRoutesCredentialCredentialIdCanIndexRoute, } diff --git a/packages/client/src/features/file-system/index.tsx b/packages/client/src/features/file-system/index.tsx index 72bb20001..5cb800586 100644 --- a/packages/client/src/features/file-system/index.tsx +++ b/packages/client/src/features/file-system/index.tsx @@ -15,7 +15,7 @@ import { TreeProps, useDragAndDrop, } from 'react-aria-components'; -import { FiFolder, FiMoreHorizontal, FiX } from 'react-icons/fi'; +import { FiFolder, FiMoreHorizontal, FiWifi, FiX } from 'react-icons/fi'; import { RiAnthropicFill, RiGeminiFill, RiOpenaiFill } from 'react-icons/ri'; import { TbGauge } from 'react-icons/tb'; import { twJoin } from 'tailwind-merge'; @@ -31,6 +31,7 @@ import { import { FlowSchema, FlowService } from '@the-dev-tools/spec/buf/api/flow/v1/flow_pb'; import { GraphQLSchema as GraphQLItemSchema } from '@the-dev-tools/spec/buf/api/graph_q_l/v1/graph_q_l_pb'; import { HttpDeltaSchema, HttpMethod, HttpSchema, HttpService } from '@the-dev-tools/spec/buf/api/http/v1/http_pb'; +import { WebSocketSchema as WebSocketItemSchema } from '@the-dev-tools/spec/buf/api/web_socket/v1/web_socket_pb'; import { CredentialAnthropicCollectionSchema, CredentialCollectionSchema, @@ -41,6 +42,7 @@ import { FileCollectionSchema, FolderCollectionSchema } from '@the-dev-tools/spe import { FlowCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/flow'; import { GraphQLCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/graph_q_l'; import { HttpCollectionSchema, HttpDeltaCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/http'; +import { WebSocketCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/web_socket'; import { Button } from '@the-dev-tools/ui/button'; import { FlowsIcon, FolderOpenedIcon } from '@the-dev-tools/ui/icons'; import { Menu, MenuItem, useContextMenuState } from '@the-dev-tools/ui/menu'; @@ -89,6 +91,7 @@ export const FileCreateMenu = ({ parentFolderId, ...props }: FileCreateMenuProps const graphqlCollection = useApiCollection(GraphQLCollectionSchema); const httpCollection = useApiCollection(HttpCollectionSchema); const flowCollection = useApiCollection(FlowCollectionSchema); + const websocketCollection = useApiCollection(WebSocketCollectionSchema); const insertFile = useInsertFile(parentFolderId); @@ -152,6 +155,16 @@ export const FileCreateMenu = ({ parentFolderId, ...props }: FileCreateMenuProps Flow + { + const websocketUlid = Ulid.generate(); + websocketCollection.utils.insert({ name: 'New WebSocket', url: '', websocketId: websocketUlid.bytes }); + await insertFile({ fileId: websocketUlid.bytes, kind: FileKind.WEB_SOCKET }); + }} + > + WebSocket + + ); @@ -353,6 +366,7 @@ const FileItem = ({ id }: FileItemProps) => { Match.when(FileKind.FLOW, () => ), Match.when(FileKind.GRAPH_Q_L, () => ), Match.when(FileKind.CREDENTIAL, () => ), + Match.when(FileKind.WEB_SOCKET, () => ), Match.orElse(() => null), ); }; @@ -908,6 +922,10 @@ const GraphQLFile = ({ id }: FileItemProps) => { const router = useRouter(); const matchRoute = useMatchRoute(); + const { theme } = useTheme(); + + const { workspaceId } = routes.dashboard.workspace.route.useLoaderData(); + const fileCollection = useApiCollection(FileCollectionSchema); const { fileId: graphqlId } = useMemo(() => fileCollection.utils.parseKeyUnsafe(id), [fileCollection.utils, id]); @@ -924,6 +942,11 @@ const GraphQLFile = ({ id }: FileItemProps) => { [graphqlCollection, graphqlId], ).data ?? create(GraphQLItemSchema); + const modal = useProgrammaticModal(); + + const exportMutation = useConnectMutation(ExportService.method.export); + const exportCurlGraphQLMutation = useConnectMutation(ExportService.method.exportCurlGraphQL); + const { containerRef, navigate: toNavigate = false, showControls } = useContext(FileTreeContext); const { escapeRef, escapeRender } = useEscapePortal(containerRef); @@ -943,6 +966,8 @@ const GraphQLFile = ({ id }: FileItemProps) => { const content = ( <> + {modal.children && } + GQL @@ -968,6 +993,167 @@ const GraphQLFile = ({ id }: FileItemProps) => { void edit()}>Rename + + Export + + + { + const { data, name } = await exportMutation.mutateAsync({ + fileIds: [graphqlId], + workspaceId, + }); + saveFile({ blobParts: [data], name }); + }} + > + YAML (DevTools) + + + { + const { data } = await exportCurlGraphQLMutation.mutateAsync({ + graphqlIds: [graphqlId], + workspaceId, + }); + modal.onOpenChange( + true, + + {({ close }) => ( + <> +
+ + cURL export + + + +
+ + + + )} +
, + ); + }} + > + cURL +
+
+
+ + pipe(fileCollection.utils.parseKeyUnsafe(id), (_) => fileCollection.utils.delete(_))} + variant='danger' + > + Delete + +
+ + )} + + ); + + const props = { + children: content, + className: toNavigate && matchRoute(route) !== false ? tw`bg-neutral` : '', + id, + onContextMenu, + textValue: name, + } satisfies TreeItemProps; + + return toNavigate ? : ; +}; + +const WebSocketFile = ({ id }: FileItemProps) => { + const router = useRouter(); + const matchRoute = useMatchRoute(); + + const { workspaceId } = routes.dashboard.workspace.route.useLoaderData(); + + const fileCollection = useApiCollection(FileCollectionSchema); + + const { fileId: websocketId } = useMemo(() => fileCollection.utils.parseKeyUnsafe(id), [fileCollection.utils, id]); + + const websocketCollection = useApiCollection(WebSocketCollectionSchema); + + const { name } = + useLiveQuery( + (_) => + _.from({ item: websocketCollection }) + .where((_) => eq(_.item.websocketId, websocketId)) + .select((_) => pick(_.item, 'name')) + .findOne(), + [websocketCollection, websocketId], + ).data ?? create(WebSocketItemSchema); + + const exportMutation = useConnectMutation(ExportService.method.export); + + const { containerRef, navigate: toNavigate = false, showControls } = useContext(FileTreeContext); + + const { escapeRef, escapeRender } = useEscapePortal(containerRef); + + const { edit, isEditing, textFieldProps } = useEditableTextState({ + onSuccess: (_) => websocketCollection.utils.update({ name: _, websocketId }), + value: name, + }); + + const { menuProps, menuTriggerProps, onContextMenu } = useContextMenuState(); + + const route = { + from: router.routesById[routes.dashboard.workspace.route.id].fullPath, + params: { websocketIdCan: Ulid.construct(websocketId).toCanonical() }, + to: router.routesById[routes.dashboard.workspace.websocket.route.id].fullPath, + } satisfies ToOptions; + + const content = ( + <> + + + + {name} + + + {isEditing && + escapeRender( + , + )} + + {showControls && ( + + + + + void edit()}>Rename + + + Export + + + { + const { data, name } = await exportMutation.mutateAsync({ + fileIds: [websocketId], + workspaceId, + }); + saveFile({ blobParts: [data], name }); + }} + > + YAML (DevTools) + + + + pipe(fileCollection.utils.parseKeyUnsafe(id), (_) => fileCollection.utils.delete(_))} variant='danger' @@ -1028,6 +1214,8 @@ const CredentialFile = ({ id }: FileItemProps) => { to: router.routesById[routes.dashboard.workspace.credential.id].fullPath, }); + + const content = ( <> {pipe( @@ -1075,7 +1263,8 @@ const CredentialFile = ({ id }: FileItemProps) => { const props = { children: content, - className: toNavigate && matchRoute(route) !== false ? tw`bg-neutral` : '', + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + className: toNavigate && matchRoute(route) ? tw`bg-neutral` : '', id, onContextMenu, textValue: name, diff --git a/packages/client/src/pages/flow/add-node.tsx b/packages/client/src/pages/flow/add-node.tsx index 5a0a644dd..c8dc9f8b7 100644 --- a/packages/client/src/pages/flow/add-node.tsx +++ b/packages/client/src/pages/flow/add-node.tsx @@ -3,7 +3,7 @@ import * as XF from '@xyflow/react'; import { Ulid } from 'id128'; import { ReactNode, use } from 'react'; import * as RAC from 'react-aria-components'; -import { FiArrowLeft, FiBriefcase, FiChevronRight, FiTerminal, FiX } from 'react-icons/fi'; +import { FiArrowLeft, FiBriefcase, FiChevronRight, FiClock, FiSend, FiTerminal, FiWifi, FiX } from 'react-icons/fi'; import { TbRobotFace } from 'react-icons/tb'; import { FileKind } from '@the-dev-tools/spec/buf/api/file_system/v1/file_system_pb'; import { @@ -24,9 +24,13 @@ import { NodeGraphQLCollectionSchema, NodeHttpCollectionSchema, NodeJsCollectionSchema, + NodeWaitCollectionSchema, + NodeWsConnectionCollectionSchema, + NodeWsSendCollectionSchema, } from '@the-dev-tools/spec/tanstack-db/v1/api/flow'; import { GraphQLCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/graph_q_l'; import { HttpCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/http'; +import { WebSocketCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/web_socket'; import { Button } from '@the-dev-tools/ui/button'; import { FlowsIcon, ForIcon, IfIcon, SendRequestIcon } from '@the-dev-tools/ui/icons'; import { ListBoxItem } from '@the-dev-tools/ui/list-box'; @@ -181,6 +185,7 @@ const AddFlowNodeSidebar = ({ handleKind, position, previous, sourceId, targetId const conditionCollection = useApiCollection(NodeConditionCollectionSchema); const forCollection = useApiCollection(NodeForCollectionSchema); const forEachCollection = useApiCollection(NodeForEachCollectionSchema); + const waitCollection = useApiCollection(NodeWaitCollectionSchema); return ( <> @@ -219,6 +224,17 @@ const AddFlowNodeSidebar = ({ handleKind, position, previous, sourceId, targetId }} title='For each loop' /> + + } + onAction={() => { + const nodeId = Ulid.generate().bytes; + waitCollection.utils.insert({ durationMs: 1000n, nodeId }); + insertNode({ handleKind, kind: NodeKind.WAIT, name: 'wait', nodeId, position, sourceId, targetId }); + }} + title='Wait' + /> ); @@ -231,6 +247,9 @@ const AddCoreNodeSidebar = (props: AddNodeSidebarProps) => { const insertNode = useInsertNode(); const jsCollection = useApiCollection(NodeJsCollectionSchema); + const websocketCollection = useApiCollection(WebSocketCollectionSchema); + const wsConnectionCollection = useApiCollection(NodeWsConnectionCollectionSchema); + const wsSendCollection = useApiCollection(NodeWsSendCollectionSchema); return ( <> @@ -261,6 +280,46 @@ const AddCoreNodeSidebar = (props: AddNodeSidebarProps) => { onAction={() => void setSidebar?.((_) => )} title='GraphQL Request' /> + + } + onAction={() => { + const websocketId = Ulid.generate().bytes; + websocketCollection.utils.insert({ name: 'New WebSocket', url: '', websocketId }); + const nodeId = Ulid.generate().bytes; + wsConnectionCollection.utils.insert({ nodeId, websocketId }); + insertNode({ + handleKind, + kind: NodeKind.WS_CONNECTION, + name: 'ws_connection', + nodeId, + position, + sourceId, + targetId, + }); + }} + title='WebSocket Connection' + /> + + } + onAction={() => { + const nodeId = Ulid.generate().bytes; + wsSendCollection.utils.insert({ nodeId }); + insertNode({ + handleKind, + kind: NodeKind.WS_SEND, + name: 'ws_send', + nodeId, + position, + sourceId, + targetId, + }); + }} + title='WebSocket Send' + /> ); diff --git a/packages/client/src/pages/flow/agent-panel.tsx b/packages/client/src/pages/flow/agent-panel.tsx index 71a08e8c3..e658bc065 100644 --- a/packages/client/src/pages/flow/agent-panel.tsx +++ b/packages/client/src/pages/flow/agent-panel.tsx @@ -1,6 +1,6 @@ import { eq, useLiveQuery } from '@tanstack/react-db'; import { Ulid } from 'id128'; -import { FormEvent, KeyboardEvent, use, useEffect, useMemo, useRef, useState } from 'react'; +import { type SyntheticEvent, KeyboardEvent, use, useEffect, useMemo, useRef, useState } from 'react'; import { FiArrowUp, FiChevronUp, FiEdit, FiSettings, FiX } from 'react-icons/fi'; import Markdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; @@ -133,7 +133,7 @@ export const AgentPanel = () => { el.style.height = `${el.scrollHeight}px`; }; - const handleSubmit = (e?: FormEvent) => { + const handleSubmit = (e?: SyntheticEvent) => { e?.preventDefault(); if (!input.trim() || isLoading) return; void sendMessage(input.trim()); @@ -369,7 +369,7 @@ const ApiKeyPrompt = ({ setValue(''); }, [provider]); - const handleSubmit = (e?: FormEvent) => { + const handleSubmit = (e?: SyntheticEvent) => { e?.preventDefault(); if (!value.trim()) return; onSubmit(value); diff --git a/packages/client/src/pages/flow/edge.tsx b/packages/client/src/pages/flow/edge.tsx index 07d726b14..c730d1a5f 100644 --- a/packages/client/src/pages/flow/edge.tsx +++ b/packages/client/src/pages/flow/edge.tsx @@ -147,7 +147,7 @@ const DefaultEdge = ({ id, sourcePosition, sourceX, sourceY, targetPosition, tar
diff --git a/packages/client/src/pages/flow/edit.tsx b/packages/client/src/pages/flow/edit.tsx index fc58004c7..d0bccf96c 100644 --- a/packages/client/src/pages/flow/edit.tsx +++ b/packages/client/src/pages/flow/edit.tsx @@ -35,6 +35,7 @@ import { NodeCollectionSchema, NodeGraphQLCollectionSchema, NodeHttpCollectionSchema, + NodeWsConnectionCollectionSchema, } from '@the-dev-tools/spec/tanstack-db/v1/api/flow'; import { Button, ButtonAsRouteLink } from '@the-dev-tools/ui/button'; import { Checkbox } from '@the-dev-tools/ui/checkbox'; @@ -83,6 +84,9 @@ import { GraphQLNode, GraphQLSettings } from './nodes/graphql'; import { HttpNode, HttpSettings } from './nodes/http'; import { JavaScriptNode, JavaScriptSettings } from './nodes/javascript'; import { ManualStartNode } from './nodes/manual-start'; +import { WaitNode, WaitSettings } from './nodes/wait'; +import { WsConnectionNode, WsConnectionSettings } from './nodes/ws-connection'; +import { WsSendNode, WsSendSettings } from './nodes/ws-send'; import { useFlowSelection } from './selection'; import { useUndoStack } from './undo'; import { useViewport, VIEWPORT_MAX_ZOOM, VIEWPORT_MIN_ZOOM } from './viewport'; @@ -99,6 +103,9 @@ export const nodeTypes: XF.NodeTypes = { [NodeKind.JS]: JavaScriptNode, [NodeKind.MANUAL_START]: ManualStartNode, [NodeKind.UNSPECIFIED]: () => null, + [NodeKind.WAIT]: WaitNode, + [NodeKind.WS_CONNECTION]: WsConnectionNode, + [NodeKind.WS_SEND]: WsSendNode, }; export const FlowEditPage = () => { @@ -153,6 +160,7 @@ export const Flow = ({ children }: PropsWithChildren) => { const nodeCollection = useApiCollection(NodeCollectionSchema); const nodeGraphQLCollection = useApiCollection(NodeGraphQLCollectionSchema); const nodeHttpCollection = useApiCollection(NodeHttpCollectionSchema); + const nodeWsConnectionCollection = useApiCollection(NodeWsConnectionCollectionSchema); const nodeEditDialog = useNodeEditDialog(); @@ -461,6 +469,23 @@ export const Flow = ({ children }: PropsWithChildren) => { position, }); } + + if (file?.kind === FileKind.WEB_SOCKET) { + const nodeId = Ulid.generate().bytes; + + nodeWsConnectionCollection.utils.insert({ + nodeId, + websocketId: file.fileId, + }); + + nodeCollection.utils.insert({ + flowId, + kind: NodeKind.WS_CONNECTION, + name: `ws_connection_${getNodes().length}`, + nodeId, + position, + }); + } }, ref, }); @@ -881,6 +906,9 @@ const useNodeEditDialog = () => { Match.when({ kind: NodeKind.AI }, (_) => ), Match.when({ kind: NodeKind.AI_PROVIDER }, (_) => ), Match.when({ kind: NodeKind.AI_MEMORY }, (_) => ), + Match.when({ kind: NodeKind.WAIT }, () => ), + Match.when({ kind: NodeKind.WS_CONNECTION }, () => ), + Match.when({ kind: NodeKind.WS_SEND }, () => ), Match.orElse(() => null), ); diff --git a/packages/client/src/pages/flow/handle.tsx b/packages/client/src/pages/flow/handle.tsx index e85a4e763..48e47bd36 100644 --- a/packages/client/src/pages/flow/handle.tsx +++ b/packages/client/src/pages/flow/handle.tsx @@ -16,6 +16,7 @@ import { FlowContext } from './context'; interface HandleProps extends Omit { alwaysVisible?: boolean; kind?: HandleKind; + label?: string; nodeId: Uint8Array; nodeOffset?: { x?: number; y?: number }; Sidebar?: (props: AddNodeSidebarProps) => ReactNode; @@ -25,6 +26,7 @@ export const Handle = ({ alwaysVisible, className, kind = HandleKind.UNSPECIFIED, + label: labelOverride, nodeId, nodeOffset, Sidebar = AddNodeSidebar, @@ -38,16 +40,19 @@ export const Handle = ({ const id = kind === HandleKind.UNSPECIFIED ? null : kind.toString(); - const label = pipe( - Match.value(kind), - Match.when(HandleKind.ELSE, () => 'Else'), - Match.when(HandleKind.THEN, () => 'Then'), - Match.when(HandleKind.LOOP, () => 'Loop'), - Match.when(HandleKind.AI_PROVIDER, () => 'Provider'), - Match.when(HandleKind.AI_MEMORY, () => 'Memory'), - Match.when(HandleKind.AI_TOOLS, () => 'Tools'), - Match.orElse(() => null), - ); + const label = + labelOverride ?? + pipe( + Match.value(kind), + Match.when(HandleKind.ELSE, () => 'Else'), + Match.when(HandleKind.THEN, () => 'Then'), + Match.when(HandleKind.LOOP, () => 'Loop'), + Match.when(HandleKind.AI_PROVIDER, () => 'Provider'), + Match.when(HandleKind.AI_MEMORY, () => 'Memory'), + Match.when(HandleKind.AI_TOOLS, () => 'Tools'), + Match.when(HandleKind.WS_MESSAGE, () => 'Message'), + Match.orElse(() => null), + ); const edgeCollection = useApiCollection(EdgeCollectionSchema); diff --git a/packages/client/src/pages/flow/node.tsx b/packages/client/src/pages/flow/node.tsx index 4fb6b6ad8..f431f88ef 100644 --- a/packages/client/src/pages/flow/node.tsx +++ b/packages/client/src/pages/flow/node.tsx @@ -9,7 +9,7 @@ import { usePacedMutations, } from '@tanstack/react-db'; import * as XF from '@xyflow/react'; -import { Array, Match, Option, pipe, Schema } from 'effect'; +import { Array, Match, pipe, Schema } from 'effect'; import { Ulid } from 'id128'; import { ReactNode, useCallback, useContext, useRef, useState } from 'react'; import { Button as AriaButton, Key, Tooltip, TooltipTrigger, Tree } from 'react-aria-components'; @@ -454,46 +454,42 @@ interface NodeSettingsBodyProps { export const NodeSettingsBody = ({ children, input, nodeId, output, settingsHeader, title }: NodeSettingsBodyProps) => { const executionCollection = useApiCollection(NodeExecutionCollectionSchema); - const { data: executions } = useLiveQuery( + const { data: rawExecutions } = useLiveQuery( (_) => { const item = _.from({ item: executionCollection }) .where((_) => eq(_.item.nodeId, nodeId)) .fn.select((_) => ({ ...pick(_.item, 'nodeExecutionId', 'name'), - order: Ulid.construct(_.item.nodeExecutionId).toCanonical(), + key: Ulid.construct(_.item.nodeExecutionId).toCanonical(), })); - return _.from({ item }).orderBy((_) => _.item.order, 'desc'); + return _.from({ item }).orderBy((_) => _.item.key, 'desc'); }, [executionCollection, nodeId], ); - const latestExecutionId = pipe( - Array.head(executions), - Option.map((_) => _.nodeExecutionId), - Option.getOrNull, - ); + // Deduplicate by canonical ULID — reactive queries can transiently emit duplicates during sync + const executions = Array.dedupeWith(rawExecutions, (a, b) => a.key === b.key); - const latestExecutionIdCan = latestExecutionId ? Ulid.construct(latestExecutionId).toCanonical() : null; + const latestKey = executions[0]?.key ?? null; - const [selectedExecKey, setSelectedExecKey] = useState(latestExecutionId ? 'latest' : null); + // Track whether user is "following" the latest execution (auto-advance on new arrivals) + // vs pinned to a specific historical execution. + const [pinnedKey, setPinnedKey] = useState(null); + const selectedKey = pinnedKey ?? latestKey; - const selectedExecutionId = - selectedExecKey === 'latest' - ? latestExecutionId - : typeof selectedExecKey === 'string' - ? Ulid.fromCanonical(selectedExecKey).bytes - : null; + const handleSelectionChange = (key: Key | null) => { + // If user selects the latest execution, clear the pin so we follow new arrivals + setPinnedKey(key === latestKey ? null : typeof key === 'string' ? key : null); + }; - const selectedExecutionIdCan = selectedExecutionId ? Ulid.construct(selectedExecutionId).toCanonical() : null; + const selectedExecutionId = + typeof selectedKey === 'string' ? (executions.find((_) => _.key === selectedKey)?.nodeExecutionId ?? null) : null; - // Fix React Aria over-rendering non-visible components + // React Aria workaround: only render full list when dropdown is open // https://github.com/adobe/react-spectrum/issues/8783#issuecomment-3233350825 - // TODO: move the workaround to an improved select component const [isExecListOpen, setIsExecListOpen] = useState(false); - const execItems = isExecListOpen - ? executions - : executions.filter((_) => Ulid.construct(_.nodeExecutionId).toCanonical() === selectedExecutionIdCan); + const execItems = isExecListOpen ? executions : executions.filter((_) => _.key === selectedKey); const nodeSettingsLayout = useDefaultLayout({ id: 'node-settings' }); @@ -506,16 +502,11 @@ export const NodeSettingsBody = ({ children, input, nodeId, output, settingsHead aria-label='Node execution' isOpen={isExecListOpen} items={execItems} - onChange={setSelectedExecKey} + onChange={handleSelectionChange} onOpenChange={setIsExecListOpen} - value={selectedExecKey} + value={selectedKey} > - {(_) => { - let key = Ulid.construct(_.nodeExecutionId).toCanonical(); - if (key === latestExecutionIdCan) key = 'latest'; - - return {_.name}; - }} + {(_) => {_.name}} ) } diff --git a/packages/client/src/pages/flow/nodes/wait.tsx b/packages/client/src/pages/flow/nodes/wait.tsx new file mode 100644 index 000000000..05619ab0a --- /dev/null +++ b/packages/client/src/pages/flow/nodes/wait.tsx @@ -0,0 +1,69 @@ +import { create } from '@bufbuild/protobuf'; +import { eq, useLiveQuery } from '@tanstack/react-db'; +import * as XF from '@xyflow/react'; +import { Ulid } from 'id128'; +import { use } from 'react'; +import { FiClock } from 'react-icons/fi'; +import { NodeWaitSchema } from '@the-dev-tools/spec/buf/api/flow/v1/flow_pb'; +import { NodeWaitCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/flow'; +import { NumberField } from '@the-dev-tools/ui/number-field'; +import { tw } from '@the-dev-tools/ui/tailwind-literal'; +import { useApiCollection } from '~/shared/api'; +import { pick } from '~/shared/lib'; +import { FlowContext } from '../context'; +import { Handle } from '../handle'; +import { NodeSettingsBody, NodeSettingsProps, NodeTitle, SimpleNode } from '../node'; + +const defaultNodeWait = create(NodeWaitSchema); + +export const WaitNode = ({ id, selected }: XF.NodeProps) => { + const nodeId = Ulid.fromCanonical(id).bytes; + + return ( + + + + + } + icon={} + nodeId={nodeId} + selected={selected} + > + Wait + + ); +}; + +export const WaitSettings = ({ nodeId }: NodeSettingsProps) => { + const collection = useApiCollection(NodeWaitCollectionSchema); + + const data = + useLiveQuery( + (_) => + _.from({ item: collection }) + .where((_) => eq(_.item.nodeId, nodeId)) + .select((_) => pick(_.item, 'durationMs')) + .findOne(), + [collection, nodeId], + ).data ?? defaultNodeWait; + + const { isReadOnly = false } = use(FlowContext); + + return ( + +
+ collection.utils.updatePaced({ durationMs: BigInt(_), nodeId })} + value={Number(data.durationMs)} + /> +
+
+ ); +}; diff --git a/packages/client/src/pages/flow/nodes/ws-connection.tsx b/packages/client/src/pages/flow/nodes/ws-connection.tsx new file mode 100644 index 000000000..89ca512f4 --- /dev/null +++ b/packages/client/src/pages/flow/nodes/ws-connection.tsx @@ -0,0 +1,144 @@ +import { create } from '@bufbuild/protobuf'; +import { eq, useLiveQuery } from '@tanstack/react-db'; +import { useRouter } from '@tanstack/react-router'; +import * as XF from '@xyflow/react'; +import { Ulid } from 'id128'; +import { use } from 'react'; +import { FiExternalLink, FiWifi } from 'react-icons/fi'; +import { HandleKind, NodeWsConnectionSchema } from '@the-dev-tools/spec/buf/api/flow/v1/flow_pb'; +import { NodeWsConnectionCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/flow'; +import { WebSocketCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/web_socket'; +import { ButtonAsLink } from '@the-dev-tools/ui/button'; +import { FieldLabel } from '@the-dev-tools/ui/field'; +import { tw } from '@the-dev-tools/ui/tailwind-literal'; +import { ReferenceContext, ReferenceField } from '~/features/expression'; +import { WebSocketHeaderTable } from '~/pages/websocket/@x/flow'; +import { useApiCollection } from '~/shared/api'; +import { eqStruct, pick } from '~/shared/lib'; +import { routes } from '~/shared/routes'; +import { FlowContext } from '../context'; +import { Handle } from '../handle'; +import { NodeSettingsBody, NodeSettingsProps, SimpleNode } from '../node'; + +const defaultNodeWsConnection = create(NodeWsConnectionSchema); + +export const WsConnectionNode = ({ id, selected }: XF.NodeProps) => { + const nodeId = Ulid.fromCanonical(id).bytes; + + const nodeWsCollection = useApiCollection(NodeWsConnectionCollectionSchema); + const wsCollection = useApiCollection(WebSocketCollectionSchema); + + const { websocketId } = + useLiveQuery( + (_) => + _.from({ item: nodeWsCollection }) + .where((_) => eq(_.item.nodeId, nodeId)) + .select((_) => pick(_.item, 'websocketId')) + .findOne(), + [nodeWsCollection, nodeId], + ).data ?? defaultNodeWsConnection; + + const { url } = + useLiveQuery( + (_) => + _.from({ item: wsCollection }) + .where((_) => (websocketId ? eqStruct({ websocketId })(_) : eq(true, false))) + .select((_) => pick(_.item, 'url')) + .findOne(), + [wsCollection, websocketId], + ).data ?? {}; + + return ( + + + + + + } + icon={} + nodeId={nodeId} + selected={selected} + title='WS Connection' + > +
+ WS +
{url ?? 'No URL'}
+
+
+ ); +}; + +export const WsConnectionSettings = ({ nodeId }: NodeSettingsProps) => { + const router = useRouter(); + + const { isReadOnly = false } = use(FlowContext); + + const { workspaceId } = routes.dashboard.workspace.route.useLoaderData(); + const { workspaceIdCan } = routes.dashboard.workspace.route.useParams(); + + const nodeWsCollection = useApiCollection(NodeWsConnectionCollectionSchema); + const wsCollection = useApiCollection(WebSocketCollectionSchema); + + const { websocketId } = + useLiveQuery( + (_) => + _.from({ item: nodeWsCollection }) + .where((_) => eq(_.item.nodeId, nodeId)) + .select((_) => pick(_.item, 'websocketId')) + .findOne(), + [nodeWsCollection, nodeId], + ).data ?? defaultNodeWsConnection; + + const { url } = + useLiveQuery( + (_) => + _.from({ item: wsCollection }) + .where((_) => (websocketId ? eqStruct({ websocketId })(_) : eq(true, false))) + .select((_) => pick(_.item, 'url')) + .findOne(), + [wsCollection, websocketId], + ).data ?? {}; + + return ( + + + Open WebSocket + + ) + } + title='WebSocket Connection' + > + + URL + websocketId && wsCollection.utils.update({ url: _, websocketId })} + readOnly={isReadOnly || !websocketId} + value={url ?? ''} + /> + + {websocketId && ( + <> + Headers + + + )} + + + ); +}; diff --git a/packages/client/src/pages/flow/nodes/ws-send.tsx b/packages/client/src/pages/flow/nodes/ws-send.tsx new file mode 100644 index 000000000..46bc9f011 --- /dev/null +++ b/packages/client/src/pages/flow/nodes/ws-send.tsx @@ -0,0 +1,99 @@ +import { create } from '@bufbuild/protobuf'; +import { eq, useLiveQuery } from '@tanstack/react-db'; +import * as XF from '@xyflow/react'; +import { Ulid } from 'id128'; +import { use, useState } from 'react'; +import { FiSend } from 'react-icons/fi'; +import { NodeKind, NodeWsSendSchema } from '@the-dev-tools/spec/buf/api/flow/v1/flow_pb'; +import { NodeCollectionSchema, NodeWsSendCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/flow'; +import { FieldLabel } from '@the-dev-tools/ui/field'; +import { Select, SelectItem } from '@the-dev-tools/ui/select'; +import { tw } from '@the-dev-tools/ui/tailwind-literal'; +import { ReferenceField } from '~/features/expression'; +import { useApiCollection } from '~/shared/api'; +import { eqStruct, pick } from '~/shared/lib'; +import { FlowContext } from '../context'; +import { Handle } from '../handle'; +import { NodeSettingsBody, NodeSettingsProps, SimpleNode } from '../node'; + +const defaultNodeWsSend = create(NodeWsSendSchema); + +export const WsSendNode = ({ id, selected }: XF.NodeProps) => { + const nodeId = Ulid.fromCanonical(id).bytes; + + return ( + + + + + } + icon={} + nodeId={nodeId} + selected={selected} + title='WS Send' + /> + ); +}; + +export const WsSendSettings = ({ nodeId }: NodeSettingsProps) => { + const collection = useApiCollection(NodeWsSendCollectionSchema); + const nodeCollection = useApiCollection(NodeCollectionSchema); + + const { flowId, isReadOnly = false } = use(FlowContext); + + const { message, wsConnectionNodeName } = + useLiveQuery( + (_) => + _.from({ item: collection }) + .where((_) => eq(_.item.nodeId, nodeId)) + .select((_) => pick(_.item, 'message', 'wsConnectionNodeName')) + .findOne(), + [collection, nodeId], + ).data ?? defaultNodeWsSend; + + const { data: wsConnectionNodes } = useLiveQuery( + (_) => + _.from({ item: nodeCollection }) + .where(eqStruct({ flowId, kind: NodeKind.WS_CONNECTION })) + .select((_) => pick(_.item, 'name', 'nodeId')), + [flowId, nodeCollection], + ); + + // React Aria workaround: only render full list when dropdown is open + // https://github.com/adobe/react-spectrum/issues/8783#issuecomment-3233350825 + const [isConnListOpen, setIsConnListOpen] = useState(false); + const connItems = + isConnListOpen || !wsConnectionNodeName + ? wsConnectionNodes + : wsConnectionNodes.filter((_) => _.name === wsConnectionNodeName); + + return ( + + Connection + + + Message + collection.utils.updatePaced({ message: _, nodeId })} + readOnly={isReadOnly} + value={message} + /> + + ); +}; diff --git a/packages/client/src/pages/websocket/@x/flow.tsx b/packages/client/src/pages/websocket/@x/flow.tsx new file mode 100644 index 000000000..86595cee3 --- /dev/null +++ b/packages/client/src/pages/websocket/@x/flow.tsx @@ -0,0 +1 @@ +export { WebSocketHeaderTable } from '../request/header'; diff --git a/packages/client/src/pages/websocket/@x/workspace.tsx b/packages/client/src/pages/websocket/@x/workspace.tsx new file mode 100644 index 000000000..13825d610 --- /dev/null +++ b/packages/client/src/pages/websocket/@x/workspace.tsx @@ -0,0 +1,3 @@ +import { resolveRoutesTo } from '../../../shared/lib/router'; + +export const resolveRoutesFrom = resolveRoutesTo(import.meta.dirname, '../routes'); diff --git a/packages/client/src/pages/websocket/page.tsx b/packages/client/src/pages/websocket/page.tsx new file mode 100644 index 000000000..a7c29dd29 --- /dev/null +++ b/packages/client/src/pages/websocket/page.tsx @@ -0,0 +1,47 @@ +import { Panel, Group as PanelGroup, useDefaultLayout } from 'react-resizable-panels'; +import { PanelResizeHandle } from '@the-dev-tools/ui/resizable-panel'; +import { ReferenceContext } from '~/features/expression'; +import { routes } from '~/shared/routes'; + +import { WebSocketRequestPanel, WebSocketTopBar, WebSocketUrlBar } from './request'; +import { WebSocketMessageLog } from './response'; +import { useWebSocket } from './use-websocket'; + +export const WebSocketPage = () => { + const { websocketId } = routes.dashboard.workspace.websocket.route.useRouteContext(); + const { workspaceId } = routes.dashboard.workspace.route.useLoaderData(); + + const ws = useWebSocket(); + + const endpointLayout = useDefaultLayout({ id: 'websocket-endpoint' }); + + return ( + + + + + + + + + + + + + + + + + + ); +}; diff --git a/packages/client/src/pages/websocket/request/header.tsx b/packages/client/src/pages/websocket/request/header.tsx new file mode 100644 index 000000000..958175a49 --- /dev/null +++ b/packages/client/src/pages/websocket/request/header.tsx @@ -0,0 +1,140 @@ +import { Query, useLiveQuery } from '@tanstack/react-db'; +import { Ulid } from 'id128'; +import { useDragAndDrop } from 'react-aria-components'; +import { FiPlus } from 'react-icons/fi'; +import { WebSocketHeaderCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/web_socket'; +import { Button } from '@the-dev-tools/ui/button'; +import { Checkbox } from '@the-dev-tools/ui/checkbox'; +import { DropIndicatorHorizontal } from '@the-dev-tools/ui/reorder'; +import { Table, TableBody, TableCell, TableColumn, TableFooter, TableHeader, TableRow } from '@the-dev-tools/ui/table'; +import { tw } from '@the-dev-tools/ui/tailwind-literal'; +import { TextInputField } from '@the-dev-tools/ui/text-field'; +import { ReferenceField } from '~/features/expression'; +import { ColumnActionDelete } from '~/features/form-table'; +import { useApiCollection } from '~/shared/api'; +import { eqStruct, getNextOrder, handleCollectionReorder, LiveQuery, pickStruct } from '~/shared/lib'; + +export interface WebSocketHeaderTableProps { + websocketId: Uint8Array; +} + +export const WebSocketHeaderTable = ({ websocketId }: WebSocketHeaderTableProps) => { + const collection = useApiCollection(WebSocketHeaderCollectionSchema); + + const { data: items } = useLiveQuery( + (_) => + _.from({ item: collection }) + .where(eqStruct({ websocketId })) + .orderBy((_) => _.item.order) + .select(pickStruct('websocketHeaderId', 'order')), + [collection, websocketId], + ); + + const { dragAndDropHooks } = useDragAndDrop({ + getItems: (keys) => [...keys].map((key) => ({ key: key.toString() })), + onReorder: handleCollectionReorder(collection), + renderDropIndicator: () => , + }); + + return ( + + + + Key + Value + Description + + + + + {({ websocketHeaderId }) => { + const query = new Query().from({ item: collection }).where(eqStruct({ websocketHeaderId })).findOne(); + + return ( + + + query.select(pickStruct('enabled'))}> + {({ data }) => ( + void collection.utils.update({ enabled: _, websocketHeaderId })} + /> + )} + + + + + query.select(pickStruct('key'))}> + {({ data }) => ( + void collection.utils.update({ key: _, websocketHeaderId })} + placeholder='Enter key' + value={data?.key ?? ''} + variant='table-cell' + /> + )} + + + + + query.select(pickStruct('value'))}> + {({ data }) => ( + void collection.utils.update({ value: _, websocketHeaderId })} + placeholder='Enter value' + value={data?.value ?? ''} + variant='table-cell' + /> + )} + + + + + query.select(pickStruct('description'))}> + {({ data }) => ( + void collection.utils.update({ description: _, websocketHeaderId })} + placeholder='Enter description' + value={data?.description ?? ''} + /> + )} + + + + + void collection.utils.delete({ websocketHeaderId })} /> + + + ); + }} + + + + + +
+ ); +}; diff --git a/packages/client/src/pages/websocket/request/index.tsx b/packages/client/src/pages/websocket/request/index.tsx new file mode 100644 index 000000000..c4e213def --- /dev/null +++ b/packages/client/src/pages/websocket/request/index.tsx @@ -0,0 +1,3 @@ +export { WebSocketRequestPanel } from './panel'; +export { WebSocketTopBar } from './top-bar'; +export { WebSocketUrlBar } from './url'; diff --git a/packages/client/src/pages/websocket/request/panel.tsx b/packages/client/src/pages/websocket/request/panel.tsx new file mode 100644 index 000000000..89f0150dc --- /dev/null +++ b/packages/client/src/pages/websocket/request/panel.tsx @@ -0,0 +1,117 @@ +import { count, useLiveQuery } from '@tanstack/react-db'; +import CodeMirror from '@uiw/react-codemirror'; +import { Suspense, useState } from 'react'; +import { Tab, TabList, TabPanel, Tabs } from 'react-aria-components'; +import { twMerge } from 'tailwind-merge'; +import { WebSocketHeaderCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/web_socket'; +import { Button } from '@the-dev-tools/ui/button'; +import { Spinner } from '@the-dev-tools/ui/spinner'; +import { tw } from '@the-dev-tools/ui/tailwind-literal'; +import { useTheme } from '@the-dev-tools/ui/theme'; +import { useCodeMirrorLanguageExtensions } from '~/features/expression'; +import { useApiCollection } from '~/shared/api'; +import { eqStruct } from '~/shared/lib'; + +import { type ConnectionState } from '../use-websocket'; +import { WebSocketHeaderTable } from './header'; + +export interface WebSocketRequestPanelProps { + connectionState: ConnectionState; + onSend: (message: string) => void; + websocketId: Uint8Array; +} + +export const WebSocketRequestPanel = ({ connectionState, onSend, websocketId }: WebSocketRequestPanelProps) => { + const headerCollection = useApiCollection(WebSocketHeaderCollectionSchema); + + const { headerCount = 0 } = + useLiveQuery( + (_) => + _.from({ item: headerCollection }) + .where(eqStruct({ websocketId })) + .select((_) => ({ headerCount: count(_.item.websocketId) })) + .findOne(), + [headerCollection, websocketId], + ).data ?? {}; + + const tabClass = ({ isSelected }: { isSelected: boolean }) => + twMerge( + tw` + -mb-px cursor-pointer border-b-2 border-transparent py-1.5 text-md leading-5 font-medium tracking-tight + text-on-neutral-low transition-colors + `, + isSelected && tw`border-b-accent text-on-neutral`, + ); + + return ( + + + + Message + + + Headers + {headerCount > 0 && ({headerCount})} + + + + + +
+ } + > + + + + + + + + + + ); +}; + +interface MessageComposerProps { + connectionState: ConnectionState; + onSend: (message: string) => void; +} + +const MessageComposer = ({ connectionState, onSend }: MessageComposerProps) => { + const { theme } = useTheme(); + const extensions = useCodeMirrorLanguageExtensions('json'); + const [message, setMessage] = useState(''); + + const isConnected = connectionState === 'connected'; + + return ( + <> +
+ +
+ +
+ +
+ + ); +}; diff --git a/packages/client/src/pages/websocket/request/top-bar.tsx b/packages/client/src/pages/websocket/request/top-bar.tsx new file mode 100644 index 000000000..e3dd89243 --- /dev/null +++ b/packages/client/src/pages/websocket/request/top-bar.tsx @@ -0,0 +1,78 @@ +import { useLiveQuery } from '@tanstack/react-db'; +import { Button as AriaButton, MenuTrigger } from 'react-aria-components'; +import { FiMoreHorizontal } from 'react-icons/fi'; +import { WebSocketCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/web_socket'; +import { Button } from '@the-dev-tools/ui/button'; +import { Menu, MenuItem, useContextMenuState } from '@the-dev-tools/ui/menu'; +import { tw } from '@the-dev-tools/ui/tailwind-literal'; +import { TextInputField, useEditableTextState } from '@the-dev-tools/ui/text-field'; +import { useApiCollection } from '~/shared/api'; +import { eqStruct, pick } from '~/shared/lib'; + +export interface WebSocketTopBarProps { + websocketId: Uint8Array; +} + +export const WebSocketTopBar = ({ websocketId }: WebSocketTopBarProps) => { + const collection = useApiCollection(WebSocketCollectionSchema); + + const name = + useLiveQuery( + (_) => + _.from({ item: collection }) + .where(eqStruct({ websocketId })) + .select((_) => pick(_.item, 'name')) + .findOne(), + [collection, websocketId], + ).data?.name ?? 'WebSocket'; + + const { menuProps, menuTriggerProps, onContextMenu } = useContextMenuState(); + + const { edit, isEditing, textFieldProps } = useEditableTextState({ + onSuccess: (_) => { + if (_ === name) return; + void collection.utils.update({ name: _, websocketId }); + }, + value: name, + }); + + return ( +
+
+ {isEditing ? ( + + ) : ( + void edit()} + > + {name} + + )} +
+ + + + + + void edit()}>Rename + + collection.utils.delete({ websocketId })} variant='danger'> + Delete + + + +
+ ); +}; diff --git a/packages/client/src/pages/websocket/request/url.tsx b/packages/client/src/pages/websocket/request/url.tsx new file mode 100644 index 000000000..1960d0ab3 --- /dev/null +++ b/packages/client/src/pages/websocket/request/url.tsx @@ -0,0 +1,91 @@ +import { useLiveQuery } from '@tanstack/react-db'; +import { useState } from 'react'; +import { WebSocketCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/web_socket'; +import { Button } from '@the-dev-tools/ui/button'; +import { Separator } from '@the-dev-tools/ui/separator'; +import { tw } from '@the-dev-tools/ui/tailwind-literal'; +import { ReferenceField } from '~/features/expression'; +import { useApiCollection } from '~/shared/api'; +import { eqStruct, pick } from '~/shared/lib'; + +import { type ConnectionState } from '../use-websocket'; + +export interface WebSocketUrlBarProps { + connectionState: ConnectionState; + onConnect: (url: string) => void; + onDisconnect: () => void; + websocketId: Uint8Array; +} + +export const WebSocketUrlBar = ({ connectionState, onConnect, onDisconnect, websocketId }: WebSocketUrlBarProps) => { + const collection = useApiCollection(WebSocketCollectionSchema); + + const { data } = useLiveQuery( + (_) => + _.from({ item: collection }) + .where(eqStruct({ websocketId })) + .select((_) => pick(_.item, 'url')) + .findOne(), + [collection, websocketId], + ); + + const url = data?.url ?? ''; + + const [urlState, setUrlState] = useState(); + + const saveUrl = () => { + if (urlState !== undefined && urlState !== url) { + collection.utils.update({ url: urlState, websocketId }); + } + setUrlState(undefined); + }; + + const handleConnect = () => { + const currentUrl = urlState ?? url; + if (urlState !== undefined) { + collection.utils.update({ url: urlState, websocketId }); + setUrlState(undefined); + } + onConnect(currentUrl); + }; + + const isConnected = connectionState === 'connected'; + const isConnecting = connectionState === 'connecting'; + + return ( +
+
+ + WS + + + + + void saveUrl()} + onChange={(_) => void setUrlState(_)} + value={urlState ?? url} + /> +
+ + {isConnected ? ( + + ) : ( + + )} +
+ ); +}; diff --git a/packages/client/src/pages/websocket/response/index.tsx b/packages/client/src/pages/websocket/response/index.tsx new file mode 100644 index 000000000..fc381c809 --- /dev/null +++ b/packages/client/src/pages/websocket/response/index.tsx @@ -0,0 +1,152 @@ +import { useQuery } from '@tanstack/react-query'; +import CodeMirror from '@uiw/react-codemirror'; +import { useEffect, useRef, useState } from 'react'; +import { FiArrowDown, FiArrowUp, FiTrash2 } from 'react-icons/fi'; +import { twJoin } from 'tailwind-merge'; +import { Button } from '@the-dev-tools/ui/button'; +import { tw } from '@the-dev-tools/ui/tailwind-literal'; +import { useTheme } from '@the-dev-tools/ui/theme'; +import { guessLanguage, prettierFormatQueryOptions, useCodeMirrorLanguageExtensions } from '~/features/expression'; + +import { type ConnectionState, type WsMessage } from '../use-websocket'; + +export interface WebSocketMessageLogProps { + clearMessages: () => void; + error: string | undefined; + messages: WsMessage[]; + state: ConnectionState; +} + +const statusConfig = { + connected: { color: tw`bg-success`, label: 'Connected' }, + connecting: { color: tw`bg-info`, label: 'Connecting...' }, + disconnected: { color: tw`bg-neutral-high`, label: 'Disconnected' }, + error: { color: tw`bg-danger`, label: 'Error' }, +} as const; + +const formatTimestamp = (ts: number) => { + const d = new Date(ts); + return `${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}:${d.getSeconds().toString().padStart(2, '0')}.${d.getMilliseconds().toString().padStart(3, '0')}`; +}; + +export const WebSocketMessageLog = ({ clearMessages, error, messages, state }: WebSocketMessageLogProps) => { + const bottomRef = useRef(null); + + useEffect(() => { + bottomRef.current?.scrollIntoView({ behavior: 'smooth' }); + }, [messages.length]); + + const { color, label } = statusConfig[state]; + + return ( +
+
+
+
+ {label} +
+ + {error && {error}} + +
+ + {messages.length > 0 && {messages.length} messages} + + +
+ +
+ {messages.length === 0 ? ( +
+ No messages yet. Connect to start. +
+ ) : ( +
+ {messages.map((msg) => ( + + ))} +
+
+ )} +
+
+ ); +}; + +interface MessageRowProps { + message: WsMessage; +} + +const MessageRow = ({ message }: MessageRowProps) => { + const [expanded, setExpanded] = useState(false); + const isSent = message.direction === 'sent'; + const isJson = isJsonString(message.data); + + const preview = message.data.length > 120 ? message.data.slice(0, 120) + '...' : message.data; + + return ( +
+ + + {expanded && ( +
+ {isJson ? ( + + ) : ( +
{message.data}
+ )} +
+ )} +
+ ); +}; + +const isJsonString = (str: string): boolean => { + try { + JSON.parse(str); + return true; + } catch { + return false; + } +}; + +interface JsonViewerProps { + data: string; +} + +const JsonViewer = ({ data }: JsonViewerProps) => { + const { theme } = useTheme(); + const language = guessLanguage(data); + const result = useQuery(prettierFormatQueryOptions({ language, text: data })); + const extensions = useCodeMirrorLanguageExtensions(language); + + return ( + + ); +}; diff --git a/packages/client/src/pages/websocket/routes/websocket/$websocketIdCan/index.tsx b/packages/client/src/pages/websocket/routes/websocket/$websocketIdCan/index.tsx new file mode 100644 index 000000000..2e32a210d --- /dev/null +++ b/packages/client/src/pages/websocket/routes/websocket/$websocketIdCan/index.tsx @@ -0,0 +1,19 @@ +import { createFileRoute } from '@tanstack/react-router'; +import { openTab } from '~/widgets/tabs'; +import { WebSocketPage } from '../../../page'; +import { WebSocketTab, websocketTabId } from '../../../tab'; + +export const Route = createFileRoute( + '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(websocket)/websocket/$websocketIdCan/', +)({ + component: WebSocketPage, + onEnter: async (match) => { + const { websocketId } = match.context; + + await openTab({ + id: websocketTabId({ websocketId }), + match, + node: , + }); + }, +}); diff --git a/packages/client/src/pages/websocket/routes/websocket/$websocketIdCan/route.tsx b/packages/client/src/pages/websocket/routes/websocket/$websocketIdCan/route.tsx new file mode 100644 index 000000000..66c867f12 --- /dev/null +++ b/packages/client/src/pages/websocket/routes/websocket/$websocketIdCan/route.tsx @@ -0,0 +1,11 @@ +import { createFileRoute } from '@tanstack/react-router'; +import { Ulid } from 'id128'; + +export const Route = createFileRoute( + '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(websocket)/websocket/$websocketIdCan', +)({ + context: ({ params: { websocketIdCan } }) => { + const websocketId = Ulid.fromCanonical(websocketIdCan).bytes; + return { websocketId }; + }, +}); diff --git a/packages/client/src/pages/websocket/tab.tsx b/packages/client/src/pages/websocket/tab.tsx new file mode 100644 index 000000000..d5fef1ec5 --- /dev/null +++ b/packages/client/src/pages/websocket/tab.tsx @@ -0,0 +1,35 @@ +import { useLiveQuery } from '@tanstack/react-db'; +import { FiWifi } from 'react-icons/fi'; +import { WebSocketCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/web_socket'; +import { tw } from '@the-dev-tools/ui/tailwind-literal'; +import { useApiCollection } from '~/shared/api'; +import { eqStruct } from '~/shared/lib'; +import { routes } from '~/shared/routes'; + +export interface WebSocketTabProps { + websocketId: Uint8Array; +} + +export const websocketTabId = ({ websocketId }: WebSocketTabProps) => + JSON.stringify({ route: routes.dashboard.workspace.websocket.route.id, websocketId }); + +export const WebSocketTab = ({ websocketId }: WebSocketTabProps) => { + const websocketCollection = useApiCollection(WebSocketCollectionSchema); + + const name = + useLiveQuery( + (_) => + _.from({ item: websocketCollection }) + .where(eqStruct({ websocketId })) + .select((_) => ({ name: _.item.name })) + .findOne(), + [websocketCollection, websocketId], + ).data?.name ?? 'WebSocket'; + + return ( + <> + + {name} + + ); +}; diff --git a/packages/client/src/pages/websocket/use-websocket.ts b/packages/client/src/pages/websocket/use-websocket.ts new file mode 100644 index 000000000..c8fe6e14b --- /dev/null +++ b/packages/client/src/pages/websocket/use-websocket.ts @@ -0,0 +1,107 @@ +import { useCallback, useEffect, useRef, useState } from 'react'; + +export type ConnectionState = 'connected' | 'connecting' | 'disconnected' | 'error'; + +export interface WsMessage { + data: string; + direction: 'received' | 'sent'; + id: string; + timestamp: number; +} + +const MAX_MESSAGES = 1000; + +export interface UseWebSocketReturn { + clearMessages: () => void; + connect: (url: string) => void; + disconnect: () => void; + error: string | undefined; + messages: WsMessage[]; + send: (message: string) => void; + state: ConnectionState; +} + +export const useWebSocket = (): UseWebSocketReturn => { + const wsRef = useRef(null); + const [state, setState] = useState('disconnected'); + const [messages, setMessages] = useState([]); + const [error, setError] = useState(); + + const disconnect = useCallback(() => { + if (wsRef.current) { + wsRef.current.close(); + wsRef.current = null; + } + }, []); + + const connect = useCallback( + (url: string) => { + disconnect(); + setError(undefined); + setState('connecting'); + + let wsUrl = url; + if (wsUrl.startsWith('http://')) wsUrl = 'ws://' + wsUrl.slice(7); + else if (wsUrl.startsWith('https://')) wsUrl = 'wss://' + wsUrl.slice(8); + + try { + const ws = new WebSocket(wsUrl); + wsRef.current = ws; + + ws.onopen = () => { + setState('connected'); + }; + + ws.onclose = () => { + setState('disconnected'); + wsRef.current = null; + }; + + ws.onerror = () => { + setError('Connection failed'); + setState('error'); + }; + + ws.onmessage = (event: MessageEvent) => { + const msg: WsMessage = { + data: typeof event.data === 'string' ? event.data : String(event.data), + direction: 'received', + id: crypto.randomUUID(), + timestamp: Date.now(), + }; + setMessages((prev) => (prev.length >= MAX_MESSAGES ? [...prev.slice(1), msg] : [...prev, msg])); + }; + } catch { + setError('Invalid WebSocket URL'); + setState('error'); + } + }, + [disconnect], + ); + + const send = useCallback((message: string) => { + const ws = wsRef.current; + if (ws?.readyState !== WebSocket.OPEN) return; + + ws.send(message); + const msg: WsMessage = { + data: message, + direction: 'sent', + id: crypto.randomUUID(), + timestamp: Date.now(), + }; + setMessages((prev) => (prev.length >= MAX_MESSAGES ? [...prev.slice(1), msg] : [...prev, msg])); + }, []); + + const clearMessages = useCallback(() => { + setMessages([]); + }, []); + + useEffect(() => { + return () => { + wsRef.current?.close(); + }; + }, []); + + return { clearMessages, connect, disconnect, error, messages, send, state }; +}; diff --git a/packages/client/src/pages/workspace/routes/workspace/$workspaceIdCan/(websocket)/__virtual.ts b/packages/client/src/pages/workspace/routes/workspace/$workspaceIdCan/(websocket)/__virtual.ts new file mode 100644 index 000000000..a74b3fae4 --- /dev/null +++ b/packages/client/src/pages/workspace/routes/workspace/$workspaceIdCan/(websocket)/__virtual.ts @@ -0,0 +1,3 @@ +import { resolveRoutesFrom } from '../../../../../websocket/@x/workspace'; + +export default resolveRoutesFrom(import.meta.dirname); diff --git a/packages/client/src/shared/api/collection.internal.tsx b/packages/client/src/shared/api/collection.internal.tsx index 62e60d034..03d896b80 100644 --- a/packages/client/src/shared/api/collection.internal.tsx +++ b/packages/client/src/shared/api/collection.internal.tsx @@ -108,7 +108,11 @@ const createApiCollection = (schema: TSchem Match.value, Match.when( { $typeName: schema.sync.insert.typeName }, - (_: Message) => void write({ type: 'insert', value: createAlike(schema.item, _) as Item }), + (_: Message) => + void write({ + type: collection.has(getKey(_ as Item)) ? 'update' : 'insert', + value: createAlike(schema.item, _) as Item, + }), ), Match.when( { $typeName: schema.sync.upsert.typeName }, diff --git a/packages/client/src/shared/routes.tsx b/packages/client/src/shared/routes.tsx index b7c3990f0..73bc88fe3 100644 --- a/packages/client/src/shared/routes.tsx +++ b/packages/client/src/shared/routes.tsx @@ -34,6 +34,10 @@ export const routes = { '/(dashboard)/(workspace)/workspace/$workspaceIdCan/(http)/http/$httpIdCan/delta/$deltaHttpIdCan', ), }, + websocket: { + route: getRouteApi('/(dashboard)/(workspace)/workspace/$workspaceIdCan/(websocket)/websocket/$websocketIdCan'), + index: getRouteApi('/(dashboard)/(workspace)/workspace/$workspaceIdCan/(websocket)/websocket/$websocketIdCan/'), + }, }, }, }; diff --git a/packages/db/pkg/sqlc/gen/db.go b/packages/db/pkg/sqlc/gen/db.go index d2a8aeb06..604277fa3 100644 --- a/packages/db/pkg/sqlc/gen/db.go +++ b/packages/db/pkg/sqlc/gen/db.go @@ -141,6 +141,9 @@ func Prepare(ctx context.Context, db DBTX) (*Queries, error) { if q.cleanupOrphanedFlowNodeJsStmt, err = db.PrepareContext(ctx, cleanupOrphanedFlowNodeJs); err != nil { return nil, fmt.Errorf("error preparing query CleanupOrphanedFlowNodeJs: %w", err) } + if q.cleanupOrphanedFlowNodeWaitStmt, err = db.PrepareContext(ctx, cleanupOrphanedFlowNodeWait); err != nil { + return nil, fmt.Errorf("error preparing query CleanupOrphanedFlowNodeWait: %w", err) + } if q.cleanupOrphanedNodeExecutionsStmt, err = db.PrepareContext(ctx, cleanupOrphanedNodeExecutions); err != nil { return nil, fmt.Errorf("error preparing query CleanupOrphanedNodeExecutions: %w", err) } @@ -198,9 +201,18 @@ func Prepare(ctx context.Context, db DBTX) (*Queries, error) { if q.createFlowNodeMemoryStmt, err = db.PrepareContext(ctx, createFlowNodeMemory); err != nil { return nil, fmt.Errorf("error preparing query CreateFlowNodeMemory: %w", err) } + if q.createFlowNodeWaitStmt, err = db.PrepareContext(ctx, createFlowNodeWait); err != nil { + return nil, fmt.Errorf("error preparing query CreateFlowNodeWait: %w", err) + } if q.createFlowNodeWithStateStmt, err = db.PrepareContext(ctx, createFlowNodeWithState); err != nil { return nil, fmt.Errorf("error preparing query CreateFlowNodeWithState: %w", err) } + if q.createFlowNodeWsConnectionStmt, err = db.PrepareContext(ctx, createFlowNodeWsConnection); err != nil { + return nil, fmt.Errorf("error preparing query CreateFlowNodeWsConnection: %w", err) + } + if q.createFlowNodeWsSendStmt, err = db.PrepareContext(ctx, createFlowNodeWsSend); err != nil { + return nil, fmt.Errorf("error preparing query CreateFlowNodeWsSend: %w", err) + } if q.createFlowNodesBulkStmt, err = db.PrepareContext(ctx, createFlowNodesBulk); err != nil { return nil, fmt.Errorf("error preparing query CreateFlowNodesBulk: %w", err) } @@ -306,6 +318,12 @@ func Prepare(ctx context.Context, db DBTX) (*Queries, error) { if q.createVariableBulkStmt, err = db.PrepareContext(ctx, createVariableBulk); err != nil { return nil, fmt.Errorf("error preparing query CreateVariableBulk: %w", err) } + if q.createWebSocketStmt, err = db.PrepareContext(ctx, createWebSocket); err != nil { + return nil, fmt.Errorf("error preparing query CreateWebSocket: %w", err) + } + if q.createWebSocketHeaderStmt, err = db.PrepareContext(ctx, createWebSocketHeader); err != nil { + return nil, fmt.Errorf("error preparing query CreateWebSocketHeader: %w", err) + } if q.createWorkspaceStmt, err = db.PrepareContext(ctx, createWorkspace); err != nil { return nil, fmt.Errorf("error preparing query CreateWorkspace: %w", err) } @@ -366,6 +384,15 @@ func Prepare(ctx context.Context, db DBTX) (*Queries, error) { if q.deleteFlowNodeMemoryStmt, err = db.PrepareContext(ctx, deleteFlowNodeMemory); err != nil { return nil, fmt.Errorf("error preparing query DeleteFlowNodeMemory: %w", err) } + if q.deleteFlowNodeWaitStmt, err = db.PrepareContext(ctx, deleteFlowNodeWait); err != nil { + return nil, fmt.Errorf("error preparing query DeleteFlowNodeWait: %w", err) + } + if q.deleteFlowNodeWsConnectionStmt, err = db.PrepareContext(ctx, deleteFlowNodeWsConnection); err != nil { + return nil, fmt.Errorf("error preparing query DeleteFlowNodeWsConnection: %w", err) + } + if q.deleteFlowNodeWsSendStmt, err = db.PrepareContext(ctx, deleteFlowNodeWsSend); err != nil { + return nil, fmt.Errorf("error preparing query DeleteFlowNodeWsSend: %w", err) + } if q.deleteFlowTagStmt, err = db.PrepareContext(ctx, deleteFlowTag); err != nil { return nil, fmt.Errorf("error preparing query DeleteFlowTag: %w", err) } @@ -435,6 +462,15 @@ func Prepare(ctx context.Context, db DBTX) (*Queries, error) { if q.deleteVariableStmt, err = db.PrepareContext(ctx, deleteVariable); err != nil { return nil, fmt.Errorf("error preparing query DeleteVariable: %w", err) } + if q.deleteWebSocketStmt, err = db.PrepareContext(ctx, deleteWebSocket); err != nil { + return nil, fmt.Errorf("error preparing query DeleteWebSocket: %w", err) + } + if q.deleteWebSocketHeaderStmt, err = db.PrepareContext(ctx, deleteWebSocketHeader); err != nil { + return nil, fmt.Errorf("error preparing query DeleteWebSocketHeader: %w", err) + } + if q.deleteWebSocketHeadersByWebSocketIDStmt, err = db.PrepareContext(ctx, deleteWebSocketHeadersByWebSocketID); err != nil { + return nil, fmt.Errorf("error preparing query DeleteWebSocketHeadersByWebSocketID: %w", err) + } if q.deleteWorkspaceStmt, err = db.PrepareContext(ctx, deleteWorkspace); err != nil { return nil, fmt.Errorf("error preparing query DeleteWorkspace: %w", err) } @@ -561,6 +597,15 @@ func Prepare(ctx context.Context, db DBTX) (*Queries, error) { if q.getFlowNodeMemoryStmt, err = db.PrepareContext(ctx, getFlowNodeMemory); err != nil { return nil, fmt.Errorf("error preparing query GetFlowNodeMemory: %w", err) } + if q.getFlowNodeWaitStmt, err = db.PrepareContext(ctx, getFlowNodeWait); err != nil { + return nil, fmt.Errorf("error preparing query GetFlowNodeWait: %w", err) + } + if q.getFlowNodeWsConnectionStmt, err = db.PrepareContext(ctx, getFlowNodeWsConnection); err != nil { + return nil, fmt.Errorf("error preparing query GetFlowNodeWsConnection: %w", err) + } + if q.getFlowNodeWsSendStmt, err = db.PrepareContext(ctx, getFlowNodeWsSend); err != nil { + return nil, fmt.Errorf("error preparing query GetFlowNodeWsSend: %w", err) + } if q.getFlowNodesByFlowIDStmt, err = db.PrepareContext(ctx, getFlowNodesByFlowID); err != nil { return nil, fmt.Errorf("error preparing query GetFlowNodesByFlowID: %w", err) } @@ -870,6 +915,21 @@ func Prepare(ctx context.Context, db DBTX) (*Queries, error) { if q.getVariablesByEnvironmentIDOrderedStmt, err = db.PrepareContext(ctx, getVariablesByEnvironmentIDOrdered); err != nil { return nil, fmt.Errorf("error preparing query GetVariablesByEnvironmentIDOrdered: %w", err) } + if q.getWebSocketStmt, err = db.PrepareContext(ctx, getWebSocket); err != nil { + return nil, fmt.Errorf("error preparing query GetWebSocket: %w", err) + } + if q.getWebSocketHeaderByIDStmt, err = db.PrepareContext(ctx, getWebSocketHeaderByID); err != nil { + return nil, fmt.Errorf("error preparing query GetWebSocketHeaderByID: %w", err) + } + if q.getWebSocketHeadersStmt, err = db.PrepareContext(ctx, getWebSocketHeaders); err != nil { + return nil, fmt.Errorf("error preparing query GetWebSocketHeaders: %w", err) + } + if q.getWebSocketWorkspaceIDStmt, err = db.PrepareContext(ctx, getWebSocketWorkspaceID); err != nil { + return nil, fmt.Errorf("error preparing query GetWebSocketWorkspaceID: %w", err) + } + if q.getWebSocketsByWorkspaceIDStmt, err = db.PrepareContext(ctx, getWebSocketsByWorkspaceID); err != nil { + return nil, fmt.Errorf("error preparing query GetWebSocketsByWorkspaceID: %w", err) + } if q.getWorkspaceStmt, err = db.PrepareContext(ctx, getWorkspace); err != nil { return nil, fmt.Errorf("error preparing query GetWorkspace: %w", err) } @@ -975,6 +1035,15 @@ func Prepare(ctx context.Context, db DBTX) (*Queries, error) { if q.updateFlowNodeStateStmt, err = db.PrepareContext(ctx, updateFlowNodeState); err != nil { return nil, fmt.Errorf("error preparing query UpdateFlowNodeState: %w", err) } + if q.updateFlowNodeWaitStmt, err = db.PrepareContext(ctx, updateFlowNodeWait); err != nil { + return nil, fmt.Errorf("error preparing query UpdateFlowNodeWait: %w", err) + } + if q.updateFlowNodeWsConnectionStmt, err = db.PrepareContext(ctx, updateFlowNodeWsConnection); err != nil { + return nil, fmt.Errorf("error preparing query UpdateFlowNodeWsConnection: %w", err) + } + if q.updateFlowNodeWsSendStmt, err = db.PrepareContext(ctx, updateFlowNodeWsSend); err != nil { + return nil, fmt.Errorf("error preparing query UpdateFlowNodeWsSend: %w", err) + } if q.updateFlowVariableStmt, err = db.PrepareContext(ctx, updateFlowVariable); err != nil { return nil, fmt.Errorf("error preparing query UpdateFlowVariable: %w", err) } @@ -1071,6 +1140,12 @@ func Prepare(ctx context.Context, db DBTX) (*Queries, error) { if q.updateVariableStmt, err = db.PrepareContext(ctx, updateVariable); err != nil { return nil, fmt.Errorf("error preparing query UpdateVariable: %w", err) } + if q.updateWebSocketStmt, err = db.PrepareContext(ctx, updateWebSocket); err != nil { + return nil, fmt.Errorf("error preparing query UpdateWebSocket: %w", err) + } + if q.updateWebSocketHeaderStmt, err = db.PrepareContext(ctx, updateWebSocketHeader); err != nil { + return nil, fmt.Errorf("error preparing query UpdateWebSocketHeader: %w", err) + } if q.updateWorkspaceStmt, err = db.PrepareContext(ctx, updateWorkspace); err != nil { return nil, fmt.Errorf("error preparing query UpdateWorkspace: %w", err) } @@ -1286,6 +1361,11 @@ func (q *Queries) Close() error { err = fmt.Errorf("error closing cleanupOrphanedFlowNodeJsStmt: %w", cerr) } } + if q.cleanupOrphanedFlowNodeWaitStmt != nil { + if cerr := q.cleanupOrphanedFlowNodeWaitStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing cleanupOrphanedFlowNodeWaitStmt: %w", cerr) + } + } if q.cleanupOrphanedNodeExecutionsStmt != nil { if cerr := q.cleanupOrphanedNodeExecutionsStmt.Close(); cerr != nil { err = fmt.Errorf("error closing cleanupOrphanedNodeExecutionsStmt: %w", cerr) @@ -1381,11 +1461,26 @@ func (q *Queries) Close() error { err = fmt.Errorf("error closing createFlowNodeMemoryStmt: %w", cerr) } } + if q.createFlowNodeWaitStmt != nil { + if cerr := q.createFlowNodeWaitStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing createFlowNodeWaitStmt: %w", cerr) + } + } if q.createFlowNodeWithStateStmt != nil { if cerr := q.createFlowNodeWithStateStmt.Close(); cerr != nil { err = fmt.Errorf("error closing createFlowNodeWithStateStmt: %w", cerr) } } + if q.createFlowNodeWsConnectionStmt != nil { + if cerr := q.createFlowNodeWsConnectionStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing createFlowNodeWsConnectionStmt: %w", cerr) + } + } + if q.createFlowNodeWsSendStmt != nil { + if cerr := q.createFlowNodeWsSendStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing createFlowNodeWsSendStmt: %w", cerr) + } + } if q.createFlowNodesBulkStmt != nil { if cerr := q.createFlowNodesBulkStmt.Close(); cerr != nil { err = fmt.Errorf("error closing createFlowNodesBulkStmt: %w", cerr) @@ -1561,6 +1656,16 @@ func (q *Queries) Close() error { err = fmt.Errorf("error closing createVariableBulkStmt: %w", cerr) } } + if q.createWebSocketStmt != nil { + if cerr := q.createWebSocketStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing createWebSocketStmt: %w", cerr) + } + } + if q.createWebSocketHeaderStmt != nil { + if cerr := q.createWebSocketHeaderStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing createWebSocketHeaderStmt: %w", cerr) + } + } if q.createWorkspaceStmt != nil { if cerr := q.createWorkspaceStmt.Close(); cerr != nil { err = fmt.Errorf("error closing createWorkspaceStmt: %w", cerr) @@ -1661,6 +1766,21 @@ func (q *Queries) Close() error { err = fmt.Errorf("error closing deleteFlowNodeMemoryStmt: %w", cerr) } } + if q.deleteFlowNodeWaitStmt != nil { + if cerr := q.deleteFlowNodeWaitStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing deleteFlowNodeWaitStmt: %w", cerr) + } + } + if q.deleteFlowNodeWsConnectionStmt != nil { + if cerr := q.deleteFlowNodeWsConnectionStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing deleteFlowNodeWsConnectionStmt: %w", cerr) + } + } + if q.deleteFlowNodeWsSendStmt != nil { + if cerr := q.deleteFlowNodeWsSendStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing deleteFlowNodeWsSendStmt: %w", cerr) + } + } if q.deleteFlowTagStmt != nil { if cerr := q.deleteFlowTagStmt.Close(); cerr != nil { err = fmt.Errorf("error closing deleteFlowTagStmt: %w", cerr) @@ -1776,6 +1896,21 @@ func (q *Queries) Close() error { err = fmt.Errorf("error closing deleteVariableStmt: %w", cerr) } } + if q.deleteWebSocketStmt != nil { + if cerr := q.deleteWebSocketStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing deleteWebSocketStmt: %w", cerr) + } + } + if q.deleteWebSocketHeaderStmt != nil { + if cerr := q.deleteWebSocketHeaderStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing deleteWebSocketHeaderStmt: %w", cerr) + } + } + if q.deleteWebSocketHeadersByWebSocketIDStmt != nil { + if cerr := q.deleteWebSocketHeadersByWebSocketIDStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing deleteWebSocketHeadersByWebSocketIDStmt: %w", cerr) + } + } if q.deleteWorkspaceStmt != nil { if cerr := q.deleteWorkspaceStmt.Close(); cerr != nil { err = fmt.Errorf("error closing deleteWorkspaceStmt: %w", cerr) @@ -1986,6 +2121,21 @@ func (q *Queries) Close() error { err = fmt.Errorf("error closing getFlowNodeMemoryStmt: %w", cerr) } } + if q.getFlowNodeWaitStmt != nil { + if cerr := q.getFlowNodeWaitStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing getFlowNodeWaitStmt: %w", cerr) + } + } + if q.getFlowNodeWsConnectionStmt != nil { + if cerr := q.getFlowNodeWsConnectionStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing getFlowNodeWsConnectionStmt: %w", cerr) + } + } + if q.getFlowNodeWsSendStmt != nil { + if cerr := q.getFlowNodeWsSendStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing getFlowNodeWsSendStmt: %w", cerr) + } + } if q.getFlowNodesByFlowIDStmt != nil { if cerr := q.getFlowNodesByFlowIDStmt.Close(); cerr != nil { err = fmt.Errorf("error closing getFlowNodesByFlowIDStmt: %w", cerr) @@ -2501,6 +2651,31 @@ func (q *Queries) Close() error { err = fmt.Errorf("error closing getVariablesByEnvironmentIDOrderedStmt: %w", cerr) } } + if q.getWebSocketStmt != nil { + if cerr := q.getWebSocketStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing getWebSocketStmt: %w", cerr) + } + } + if q.getWebSocketHeaderByIDStmt != nil { + if cerr := q.getWebSocketHeaderByIDStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing getWebSocketHeaderByIDStmt: %w", cerr) + } + } + if q.getWebSocketHeadersStmt != nil { + if cerr := q.getWebSocketHeadersStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing getWebSocketHeadersStmt: %w", cerr) + } + } + if q.getWebSocketWorkspaceIDStmt != nil { + if cerr := q.getWebSocketWorkspaceIDStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing getWebSocketWorkspaceIDStmt: %w", cerr) + } + } + if q.getWebSocketsByWorkspaceIDStmt != nil { + if cerr := q.getWebSocketsByWorkspaceIDStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing getWebSocketsByWorkspaceIDStmt: %w", cerr) + } + } if q.getWorkspaceStmt != nil { if cerr := q.getWorkspaceStmt.Close(); cerr != nil { err = fmt.Errorf("error closing getWorkspaceStmt: %w", cerr) @@ -2676,6 +2851,21 @@ func (q *Queries) Close() error { err = fmt.Errorf("error closing updateFlowNodeStateStmt: %w", cerr) } } + if q.updateFlowNodeWaitStmt != nil { + if cerr := q.updateFlowNodeWaitStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing updateFlowNodeWaitStmt: %w", cerr) + } + } + if q.updateFlowNodeWsConnectionStmt != nil { + if cerr := q.updateFlowNodeWsConnectionStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing updateFlowNodeWsConnectionStmt: %w", cerr) + } + } + if q.updateFlowNodeWsSendStmt != nil { + if cerr := q.updateFlowNodeWsSendStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing updateFlowNodeWsSendStmt: %w", cerr) + } + } if q.updateFlowVariableStmt != nil { if cerr := q.updateFlowVariableStmt.Close(); cerr != nil { err = fmt.Errorf("error closing updateFlowVariableStmt: %w", cerr) @@ -2836,6 +3026,16 @@ func (q *Queries) Close() error { err = fmt.Errorf("error closing updateVariableStmt: %w", cerr) } } + if q.updateWebSocketStmt != nil { + if cerr := q.updateWebSocketStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing updateWebSocketStmt: %w", cerr) + } + } + if q.updateWebSocketHeaderStmt != nil { + if cerr := q.updateWebSocketHeaderStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing updateWebSocketHeaderStmt: %w", cerr) + } + } if q.updateWorkspaceStmt != nil { if cerr := q.updateWorkspaceStmt.Close(); cerr != nil { err = fmt.Errorf("error closing updateWorkspaceStmt: %w", cerr) @@ -2939,6 +3139,7 @@ type Queries struct { cleanupOrphanedFlowNodeGraphQLStmt *sql.Stmt cleanupOrphanedFlowNodeHttpStmt *sql.Stmt cleanupOrphanedFlowNodeJsStmt *sql.Stmt + cleanupOrphanedFlowNodeWaitStmt *sql.Stmt cleanupOrphanedNodeExecutionsStmt *sql.Stmt createCredentialStmt *sql.Stmt createCredentialAnthropicStmt *sql.Stmt @@ -2958,7 +3159,10 @@ type Queries struct { createFlowNodeHTTPStmt *sql.Stmt createFlowNodeJsStmt *sql.Stmt createFlowNodeMemoryStmt *sql.Stmt + createFlowNodeWaitStmt *sql.Stmt createFlowNodeWithStateStmt *sql.Stmt + createFlowNodeWsConnectionStmt *sql.Stmt + createFlowNodeWsSendStmt *sql.Stmt createFlowNodesBulkStmt *sql.Stmt createFlowTagStmt *sql.Stmt createFlowVariableStmt *sql.Stmt @@ -2994,6 +3198,8 @@ type Queries struct { createUserStmt *sql.Stmt createVariableStmt *sql.Stmt createVariableBulkStmt *sql.Stmt + createWebSocketStmt *sql.Stmt + createWebSocketHeaderStmt *sql.Stmt createWorkspaceStmt *sql.Stmt createWorkspaceUserStmt *sql.Stmt deleteCredentialStmt *sql.Stmt @@ -3014,6 +3220,9 @@ type Queries struct { deleteFlowNodeHTTPStmt *sql.Stmt deleteFlowNodeJsStmt *sql.Stmt deleteFlowNodeMemoryStmt *sql.Stmt + deleteFlowNodeWaitStmt *sql.Stmt + deleteFlowNodeWsConnectionStmt *sql.Stmt + deleteFlowNodeWsSendStmt *sql.Stmt deleteFlowTagStmt *sql.Stmt deleteFlowVariableStmt *sql.Stmt deleteGraphQLStmt *sql.Stmt @@ -3037,6 +3246,9 @@ type Queries struct { deleteTagStmt *sql.Stmt deleteUserStmt *sql.Stmt deleteVariableStmt *sql.Stmt + deleteWebSocketStmt *sql.Stmt + deleteWebSocketHeaderStmt *sql.Stmt + deleteWebSocketHeadersByWebSocketIDStmt *sql.Stmt deleteWorkspaceStmt *sql.Stmt deleteWorkspaceUserStmt *sql.Stmt findFileByPathHashStmt *sql.Stmt @@ -3079,6 +3291,9 @@ type Queries struct { getFlowNodeHTTPStmt *sql.Stmt getFlowNodeJsStmt *sql.Stmt getFlowNodeMemoryStmt *sql.Stmt + getFlowNodeWaitStmt *sql.Stmt + getFlowNodeWsConnectionStmt *sql.Stmt + getFlowNodeWsSendStmt *sql.Stmt getFlowNodesByFlowIDStmt *sql.Stmt getFlowNodesByFlowIDsStmt *sql.Stmt getFlowTagStmt *sql.Stmt @@ -3182,6 +3397,11 @@ type Queries struct { getVariableStmt *sql.Stmt getVariablesByEnvironmentIDStmt *sql.Stmt getVariablesByEnvironmentIDOrderedStmt *sql.Stmt + getWebSocketStmt *sql.Stmt + getWebSocketHeaderByIDStmt *sql.Stmt + getWebSocketHeadersStmt *sql.Stmt + getWebSocketWorkspaceIDStmt *sql.Stmt + getWebSocketsByWorkspaceIDStmt *sql.Stmt getWorkspaceStmt *sql.Stmt getWorkspaceByUserIDStmt *sql.Stmt getWorkspaceByUserIDandWorkspaceIDStmt *sql.Stmt @@ -3217,6 +3437,9 @@ type Queries struct { updateFlowNodeJsStmt *sql.Stmt updateFlowNodeMemoryStmt *sql.Stmt updateFlowNodeStateStmt *sql.Stmt + updateFlowNodeWaitStmt *sql.Stmt + updateFlowNodeWsConnectionStmt *sql.Stmt + updateFlowNodeWsSendStmt *sql.Stmt updateFlowVariableStmt *sql.Stmt updateFlowVariableOrderStmt *sql.Stmt updateGraphQLStmt *sql.Stmt @@ -3249,6 +3472,8 @@ type Queries struct { updateTagStmt *sql.Stmt updateUserStmt *sql.Stmt updateVariableStmt *sql.Stmt + updateWebSocketStmt *sql.Stmt + updateWebSocketHeaderStmt *sql.Stmt updateWorkspaceStmt *sql.Stmt updateWorkspaceUpdatedTimeStmt *sql.Stmt updateWorkspaceUserStmt *sql.Stmt @@ -3299,6 +3524,7 @@ func (q *Queries) WithTx(tx *sql.Tx) *Queries { cleanupOrphanedFlowNodeGraphQLStmt: q.cleanupOrphanedFlowNodeGraphQLStmt, cleanupOrphanedFlowNodeHttpStmt: q.cleanupOrphanedFlowNodeHttpStmt, cleanupOrphanedFlowNodeJsStmt: q.cleanupOrphanedFlowNodeJsStmt, + cleanupOrphanedFlowNodeWaitStmt: q.cleanupOrphanedFlowNodeWaitStmt, cleanupOrphanedNodeExecutionsStmt: q.cleanupOrphanedNodeExecutionsStmt, createCredentialStmt: q.createCredentialStmt, createCredentialAnthropicStmt: q.createCredentialAnthropicStmt, @@ -3318,7 +3544,10 @@ func (q *Queries) WithTx(tx *sql.Tx) *Queries { createFlowNodeHTTPStmt: q.createFlowNodeHTTPStmt, createFlowNodeJsStmt: q.createFlowNodeJsStmt, createFlowNodeMemoryStmt: q.createFlowNodeMemoryStmt, + createFlowNodeWaitStmt: q.createFlowNodeWaitStmt, createFlowNodeWithStateStmt: q.createFlowNodeWithStateStmt, + createFlowNodeWsConnectionStmt: q.createFlowNodeWsConnectionStmt, + createFlowNodeWsSendStmt: q.createFlowNodeWsSendStmt, createFlowNodesBulkStmt: q.createFlowNodesBulkStmt, createFlowTagStmt: q.createFlowTagStmt, createFlowVariableStmt: q.createFlowVariableStmt, @@ -3354,6 +3583,8 @@ func (q *Queries) WithTx(tx *sql.Tx) *Queries { createUserStmt: q.createUserStmt, createVariableStmt: q.createVariableStmt, createVariableBulkStmt: q.createVariableBulkStmt, + createWebSocketStmt: q.createWebSocketStmt, + createWebSocketHeaderStmt: q.createWebSocketHeaderStmt, createWorkspaceStmt: q.createWorkspaceStmt, createWorkspaceUserStmt: q.createWorkspaceUserStmt, deleteCredentialStmt: q.deleteCredentialStmt, @@ -3374,6 +3605,9 @@ func (q *Queries) WithTx(tx *sql.Tx) *Queries { deleteFlowNodeHTTPStmt: q.deleteFlowNodeHTTPStmt, deleteFlowNodeJsStmt: q.deleteFlowNodeJsStmt, deleteFlowNodeMemoryStmt: q.deleteFlowNodeMemoryStmt, + deleteFlowNodeWaitStmt: q.deleteFlowNodeWaitStmt, + deleteFlowNodeWsConnectionStmt: q.deleteFlowNodeWsConnectionStmt, + deleteFlowNodeWsSendStmt: q.deleteFlowNodeWsSendStmt, deleteFlowTagStmt: q.deleteFlowTagStmt, deleteFlowVariableStmt: q.deleteFlowVariableStmt, deleteGraphQLStmt: q.deleteGraphQLStmt, @@ -3397,6 +3631,9 @@ func (q *Queries) WithTx(tx *sql.Tx) *Queries { deleteTagStmt: q.deleteTagStmt, deleteUserStmt: q.deleteUserStmt, deleteVariableStmt: q.deleteVariableStmt, + deleteWebSocketStmt: q.deleteWebSocketStmt, + deleteWebSocketHeaderStmt: q.deleteWebSocketHeaderStmt, + deleteWebSocketHeadersByWebSocketIDStmt: q.deleteWebSocketHeadersByWebSocketIDStmt, deleteWorkspaceStmt: q.deleteWorkspaceStmt, deleteWorkspaceUserStmt: q.deleteWorkspaceUserStmt, findFileByPathHashStmt: q.findFileByPathHashStmt, @@ -3439,6 +3676,9 @@ func (q *Queries) WithTx(tx *sql.Tx) *Queries { getFlowNodeHTTPStmt: q.getFlowNodeHTTPStmt, getFlowNodeJsStmt: q.getFlowNodeJsStmt, getFlowNodeMemoryStmt: q.getFlowNodeMemoryStmt, + getFlowNodeWaitStmt: q.getFlowNodeWaitStmt, + getFlowNodeWsConnectionStmt: q.getFlowNodeWsConnectionStmt, + getFlowNodeWsSendStmt: q.getFlowNodeWsSendStmt, getFlowNodesByFlowIDStmt: q.getFlowNodesByFlowIDStmt, getFlowNodesByFlowIDsStmt: q.getFlowNodesByFlowIDsStmt, getFlowTagStmt: q.getFlowTagStmt, @@ -3542,6 +3782,11 @@ func (q *Queries) WithTx(tx *sql.Tx) *Queries { getVariableStmt: q.getVariableStmt, getVariablesByEnvironmentIDStmt: q.getVariablesByEnvironmentIDStmt, getVariablesByEnvironmentIDOrderedStmt: q.getVariablesByEnvironmentIDOrderedStmt, + getWebSocketStmt: q.getWebSocketStmt, + getWebSocketHeaderByIDStmt: q.getWebSocketHeaderByIDStmt, + getWebSocketHeadersStmt: q.getWebSocketHeadersStmt, + getWebSocketWorkspaceIDStmt: q.getWebSocketWorkspaceIDStmt, + getWebSocketsByWorkspaceIDStmt: q.getWebSocketsByWorkspaceIDStmt, getWorkspaceStmt: q.getWorkspaceStmt, getWorkspaceByUserIDStmt: q.getWorkspaceByUserIDStmt, getWorkspaceByUserIDandWorkspaceIDStmt: q.getWorkspaceByUserIDandWorkspaceIDStmt, @@ -3577,6 +3822,9 @@ func (q *Queries) WithTx(tx *sql.Tx) *Queries { updateFlowNodeJsStmt: q.updateFlowNodeJsStmt, updateFlowNodeMemoryStmt: q.updateFlowNodeMemoryStmt, updateFlowNodeStateStmt: q.updateFlowNodeStateStmt, + updateFlowNodeWaitStmt: q.updateFlowNodeWaitStmt, + updateFlowNodeWsConnectionStmt: q.updateFlowNodeWsConnectionStmt, + updateFlowNodeWsSendStmt: q.updateFlowNodeWsSendStmt, updateFlowVariableStmt: q.updateFlowVariableStmt, updateFlowVariableOrderStmt: q.updateFlowVariableOrderStmt, updateGraphQLStmt: q.updateGraphQLStmt, @@ -3609,6 +3857,8 @@ func (q *Queries) WithTx(tx *sql.Tx) *Queries { updateTagStmt: q.updateTagStmt, updateUserStmt: q.updateUserStmt, updateVariableStmt: q.updateVariableStmt, + updateWebSocketStmt: q.updateWebSocketStmt, + updateWebSocketHeaderStmt: q.updateWebSocketHeaderStmt, updateWorkspaceStmt: q.updateWorkspaceStmt, updateWorkspaceUpdatedTimeStmt: q.updateWorkspaceUpdatedTimeStmt, updateWorkspaceUserStmt: q.updateWorkspaceUserStmt, diff --git a/packages/db/pkg/sqlc/gen/flow.sql.go b/packages/db/pkg/sqlc/gen/flow.sql.go index 8398c387c..5b262ffdb 100644 --- a/packages/db/pkg/sqlc/gen/flow.sql.go +++ b/packages/db/pkg/sqlc/gen/flow.sql.go @@ -79,6 +79,15 @@ func (q *Queries) CleanupOrphanedFlowNodeJs(ctx context.Context) error { return err } +const cleanupOrphanedFlowNodeWait = `-- name: CleanupOrphanedFlowNodeWait :exec +DELETE FROM flow_node_wait WHERE flow_node_id NOT IN (SELECT id FROM flow_node) +` + +func (q *Queries) CleanupOrphanedFlowNodeWait(ctx context.Context) error { + _, err := q.exec(ctx, q.cleanupOrphanedFlowNodeWaitStmt, cleanupOrphanedFlowNodeWait) + return err +} + const cleanupOrphanedNodeExecutions = `-- name: CleanupOrphanedNodeExecutions :exec DELETE FROM node_execution WHERE node_id NOT IN (SELECT id FROM flow_node) ` @@ -294,6 +303,23 @@ func (q *Queries) CreateFlowNodeJs(ctx context.Context, arg CreateFlowNodeJsPara return err } +const createFlowNodeWait = `-- name: CreateFlowNodeWait :exec +INSERT INTO + flow_node_wait (flow_node_id, duration_ms) +VALUES + (?, ?) +` + +type CreateFlowNodeWaitParams struct { + FlowNodeID idwrap.IDWrap + DurationMs int64 +} + +func (q *Queries) CreateFlowNodeWait(ctx context.Context, arg CreateFlowNodeWaitParams) error { + _, err := q.exec(ctx, q.createFlowNodeWaitStmt, createFlowNodeWait, arg.FlowNodeID, arg.DurationMs) + return err +} + const createFlowNodeWithState = `-- name: CreateFlowNodeWithState :exec INSERT INTO flow_node (id, flow_id, name, node_kind, position_x, position_y, state) @@ -1070,6 +1096,17 @@ func (q *Queries) DeleteFlowNodeJs(ctx context.Context, flowNodeID idwrap.IDWrap return err } +const deleteFlowNodeWait = `-- name: DeleteFlowNodeWait :exec +DELETE FROM flow_node_wait +WHERE + flow_node_id = ? +` + +func (q *Queries) DeleteFlowNodeWait(ctx context.Context, flowNodeID idwrap.IDWrap) error { + _, err := q.exec(ctx, q.deleteFlowNodeWaitStmt, deleteFlowNodeWait, flowNodeID) + return err +} + const deleteFlowTag = `-- name: DeleteFlowTag :exec DELETE FROM flow_tag WHERE @@ -1592,6 +1629,23 @@ func (q *Queries) GetFlowNodeJs(ctx context.Context, flowNodeID idwrap.IDWrap) ( return i, err } +const getFlowNodeWait = `-- name: GetFlowNodeWait :one +SELECT + flow_node_id, + duration_ms +FROM + flow_node_wait +WHERE + flow_node_id = ? +` + +func (q *Queries) GetFlowNodeWait(ctx context.Context, flowNodeID idwrap.IDWrap) (FlowNodeWait, error) { + row := q.queryRow(ctx, q.getFlowNodeWaitStmt, getFlowNodeWait, flowNodeID) + var i FlowNodeWait + err := row.Scan(&i.FlowNodeID, &i.DurationMs) + return i, err +} + const getFlowNodesByFlowID = `-- name: GetFlowNodesByFlowID :many SELECT id, @@ -2711,6 +2765,24 @@ func (q *Queries) UpdateFlowNodeState(ctx context.Context, arg UpdateFlowNodeSta return err } +const updateFlowNodeWait = `-- name: UpdateFlowNodeWait :exec +UPDATE flow_node_wait +SET + duration_ms = ? +WHERE + flow_node_id = ? +` + +type UpdateFlowNodeWaitParams struct { + DurationMs int64 + FlowNodeID idwrap.IDWrap +} + +func (q *Queries) UpdateFlowNodeWait(ctx context.Context, arg UpdateFlowNodeWaitParams) error { + _, err := q.exec(ctx, q.updateFlowNodeWaitStmt, updateFlowNodeWait, arg.DurationMs, arg.FlowNodeID) + return err +} + const updateFlowVariable = `-- name: UpdateFlowVariable :exec UPDATE flow_variable SET diff --git a/packages/db/pkg/sqlc/gen/models.go b/packages/db/pkg/sqlc/gen/models.go index 0ce8a7244..0f01990c4 100644 --- a/packages/db/pkg/sqlc/gen/models.go +++ b/packages/db/pkg/sqlc/gen/models.go @@ -201,6 +201,22 @@ type FlowNodeMemory struct { WindowSize int32 } +type FlowNodeWait struct { + FlowNodeID idwrap.IDWrap + DurationMs int64 +} + +type FlowNodeWsConnection struct { + FlowNodeID idwrap.IDWrap + WebsocketID *idwrap.IDWrap +} + +type FlowNodeWsSend struct { + FlowNodeID idwrap.IDWrap + WsConnectionNodeName string + Message string +} + type FlowTag struct { ID idwrap.IDWrap FlowID idwrap.IDWrap @@ -529,6 +545,30 @@ type Variable struct { DisplayOrder float64 } +type Websocket struct { + ID idwrap.IDWrap + WorkspaceID idwrap.IDWrap + FolderID *idwrap.IDWrap + Name string + Url string + Description string + LastRunAt interface{} + CreatedAt int64 + UpdatedAt int64 +} + +type WebsocketHeader struct { + ID idwrap.IDWrap + WebsocketID idwrap.IDWrap + HeaderKey string + HeaderValue string + Description string + Enabled bool + DisplayOrder float64 + CreatedAt int64 + UpdatedAt int64 +} + type Workspace struct { ID idwrap.IDWrap Name string diff --git a/packages/db/pkg/sqlc/gen/websocket.sql.go b/packages/db/pkg/sqlc/gen/websocket.sql.go new file mode 100644 index 000000000..2eebf9c71 --- /dev/null +++ b/packages/db/pkg/sqlc/gen/websocket.sql.go @@ -0,0 +1,443 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 +// source: websocket.sql + +package gen + +import ( + "context" + + idwrap "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" +) + +const createFlowNodeWsConnection = `-- name: CreateFlowNodeWsConnection :exec +INSERT INTO flow_node_ws_connection (flow_node_id, websocket_id) VALUES (?, ?) +` + +type CreateFlowNodeWsConnectionParams struct { + FlowNodeID idwrap.IDWrap + WebsocketID *idwrap.IDWrap +} + +func (q *Queries) CreateFlowNodeWsConnection(ctx context.Context, arg CreateFlowNodeWsConnectionParams) error { + _, err := q.exec(ctx, q.createFlowNodeWsConnectionStmt, createFlowNodeWsConnection, arg.FlowNodeID, arg.WebsocketID) + return err +} + +const createFlowNodeWsSend = `-- name: CreateFlowNodeWsSend :exec +INSERT INTO flow_node_ws_send (flow_node_id, ws_connection_node_name, message) VALUES (?, ?, ?) +` + +type CreateFlowNodeWsSendParams struct { + FlowNodeID idwrap.IDWrap + WsConnectionNodeName string + Message string +} + +func (q *Queries) CreateFlowNodeWsSend(ctx context.Context, arg CreateFlowNodeWsSendParams) error { + _, err := q.exec(ctx, q.createFlowNodeWsSendStmt, createFlowNodeWsSend, arg.FlowNodeID, arg.WsConnectionNodeName, arg.Message) + return err +} + +const createWebSocket = `-- name: CreateWebSocket :exec +INSERT INTO websocket ( + id, workspace_id, folder_id, name, url, + description, last_run_at, created_at, updated_at +) +VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) +` + +type CreateWebSocketParams struct { + ID idwrap.IDWrap + WorkspaceID idwrap.IDWrap + FolderID *idwrap.IDWrap + Name string + Url string + Description string + LastRunAt interface{} + CreatedAt int64 + UpdatedAt int64 +} + +func (q *Queries) CreateWebSocket(ctx context.Context, arg CreateWebSocketParams) error { + _, err := q.exec(ctx, q.createWebSocketStmt, createWebSocket, + arg.ID, + arg.WorkspaceID, + arg.FolderID, + arg.Name, + arg.Url, + arg.Description, + arg.LastRunAt, + arg.CreatedAt, + arg.UpdatedAt, + ) + return err +} + +const createWebSocketHeader = `-- name: CreateWebSocketHeader :exec +INSERT INTO websocket_header ( + id, websocket_id, header_key, header_value, description, + enabled, display_order, created_at, updated_at +) +VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) +` + +type CreateWebSocketHeaderParams struct { + ID idwrap.IDWrap + WebsocketID idwrap.IDWrap + HeaderKey string + HeaderValue string + Description string + Enabled bool + DisplayOrder float64 + CreatedAt int64 + UpdatedAt int64 +} + +func (q *Queries) CreateWebSocketHeader(ctx context.Context, arg CreateWebSocketHeaderParams) error { + _, err := q.exec(ctx, q.createWebSocketHeaderStmt, createWebSocketHeader, + arg.ID, + arg.WebsocketID, + arg.HeaderKey, + arg.HeaderValue, + arg.Description, + arg.Enabled, + arg.DisplayOrder, + arg.CreatedAt, + arg.UpdatedAt, + ) + return err +} + +const deleteFlowNodeWsConnection = `-- name: DeleteFlowNodeWsConnection :exec +DELETE FROM flow_node_ws_connection WHERE flow_node_id = ? +` + +func (q *Queries) DeleteFlowNodeWsConnection(ctx context.Context, flowNodeID idwrap.IDWrap) error { + _, err := q.exec(ctx, q.deleteFlowNodeWsConnectionStmt, deleteFlowNodeWsConnection, flowNodeID) + return err +} + +const deleteFlowNodeWsSend = `-- name: DeleteFlowNodeWsSend :exec +DELETE FROM flow_node_ws_send WHERE flow_node_id = ? +` + +func (q *Queries) DeleteFlowNodeWsSend(ctx context.Context, flowNodeID idwrap.IDWrap) error { + _, err := q.exec(ctx, q.deleteFlowNodeWsSendStmt, deleteFlowNodeWsSend, flowNodeID) + return err +} + +const deleteWebSocket = `-- name: DeleteWebSocket :exec +DELETE FROM websocket +WHERE id = ? +` + +func (q *Queries) DeleteWebSocket(ctx context.Context, id idwrap.IDWrap) error { + _, err := q.exec(ctx, q.deleteWebSocketStmt, deleteWebSocket, id) + return err +} + +const deleteWebSocketHeader = `-- name: DeleteWebSocketHeader :exec +DELETE FROM websocket_header +WHERE id = ? +` + +func (q *Queries) DeleteWebSocketHeader(ctx context.Context, id idwrap.IDWrap) error { + _, err := q.exec(ctx, q.deleteWebSocketHeaderStmt, deleteWebSocketHeader, id) + return err +} + +const deleteWebSocketHeadersByWebSocketID = `-- name: DeleteWebSocketHeadersByWebSocketID :exec +DELETE FROM websocket_header +WHERE websocket_id = ? +` + +func (q *Queries) DeleteWebSocketHeadersByWebSocketID(ctx context.Context, websocketID idwrap.IDWrap) error { + _, err := q.exec(ctx, q.deleteWebSocketHeadersByWebSocketIDStmt, deleteWebSocketHeadersByWebSocketID, websocketID) + return err +} + +const getFlowNodeWsConnection = `-- name: GetFlowNodeWsConnection :one + +SELECT + flow_node_id, + websocket_id +FROM flow_node_ws_connection +WHERE flow_node_id = ? +LIMIT 1 +` + +// Flow Node WebSocket Queries +func (q *Queries) GetFlowNodeWsConnection(ctx context.Context, flowNodeID idwrap.IDWrap) (FlowNodeWsConnection, error) { + row := q.queryRow(ctx, q.getFlowNodeWsConnectionStmt, getFlowNodeWsConnection, flowNodeID) + var i FlowNodeWsConnection + err := row.Scan(&i.FlowNodeID, &i.WebsocketID) + return i, err +} + +const getFlowNodeWsSend = `-- name: GetFlowNodeWsSend :one +SELECT + flow_node_id, + ws_connection_node_name, + message +FROM flow_node_ws_send +WHERE flow_node_id = ? +LIMIT 1 +` + +func (q *Queries) GetFlowNodeWsSend(ctx context.Context, flowNodeID idwrap.IDWrap) (FlowNodeWsSend, error) { + row := q.queryRow(ctx, q.getFlowNodeWsSendStmt, getFlowNodeWsSend, flowNodeID) + var i FlowNodeWsSend + err := row.Scan(&i.FlowNodeID, &i.WsConnectionNodeName, &i.Message) + return i, err +} + +const getWebSocket = `-- name: GetWebSocket :one + +SELECT + id, workspace_id, folder_id, name, url, + description, last_run_at, created_at, updated_at +FROM websocket +WHERE id = ? LIMIT 1 +` + +// WebSocket Core Queries +func (q *Queries) GetWebSocket(ctx context.Context, id idwrap.IDWrap) (Websocket, error) { + row := q.queryRow(ctx, q.getWebSocketStmt, getWebSocket, id) + var i Websocket + err := row.Scan( + &i.ID, + &i.WorkspaceID, + &i.FolderID, + &i.Name, + &i.Url, + &i.Description, + &i.LastRunAt, + &i.CreatedAt, + &i.UpdatedAt, + ) + return i, err +} + +const getWebSocketHeaderByID = `-- name: GetWebSocketHeaderByID :one +SELECT + id, websocket_id, header_key, header_value, description, + enabled, display_order, created_at, updated_at +FROM websocket_header +WHERE id = ? LIMIT 1 +` + +func (q *Queries) GetWebSocketHeaderByID(ctx context.Context, id idwrap.IDWrap) (WebsocketHeader, error) { + row := q.queryRow(ctx, q.getWebSocketHeaderByIDStmt, getWebSocketHeaderByID, id) + var i WebsocketHeader + err := row.Scan( + &i.ID, + &i.WebsocketID, + &i.HeaderKey, + &i.HeaderValue, + &i.Description, + &i.Enabled, + &i.DisplayOrder, + &i.CreatedAt, + &i.UpdatedAt, + ) + return i, err +} + +const getWebSocketHeaders = `-- name: GetWebSocketHeaders :many + +SELECT + id, websocket_id, header_key, header_value, description, + enabled, display_order, created_at, updated_at +FROM websocket_header +WHERE websocket_id = ? +ORDER BY display_order +` + +// WebSocket Header Queries +func (q *Queries) GetWebSocketHeaders(ctx context.Context, websocketID idwrap.IDWrap) ([]WebsocketHeader, error) { + rows, err := q.query(ctx, q.getWebSocketHeadersStmt, getWebSocketHeaders, websocketID) + if err != nil { + return nil, err + } + defer rows.Close() + items := []WebsocketHeader{} + for rows.Next() { + var i WebsocketHeader + if err := rows.Scan( + &i.ID, + &i.WebsocketID, + &i.HeaderKey, + &i.HeaderValue, + &i.Description, + &i.Enabled, + &i.DisplayOrder, + &i.CreatedAt, + &i.UpdatedAt, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getWebSocketWorkspaceID = `-- name: GetWebSocketWorkspaceID :one +SELECT workspace_id +FROM websocket +WHERE id = ? +LIMIT 1 +` + +func (q *Queries) GetWebSocketWorkspaceID(ctx context.Context, id idwrap.IDWrap) (idwrap.IDWrap, error) { + row := q.queryRow(ctx, q.getWebSocketWorkspaceIDStmt, getWebSocketWorkspaceID, id) + var workspace_id idwrap.IDWrap + err := row.Scan(&workspace_id) + return workspace_id, err +} + +const getWebSocketsByWorkspaceID = `-- name: GetWebSocketsByWorkspaceID :many +SELECT + id, workspace_id, folder_id, name, url, + description, last_run_at, created_at, updated_at +FROM websocket +WHERE workspace_id = ? +ORDER BY updated_at DESC +` + +func (q *Queries) GetWebSocketsByWorkspaceID(ctx context.Context, workspaceID idwrap.IDWrap) ([]Websocket, error) { + rows, err := q.query(ctx, q.getWebSocketsByWorkspaceIDStmt, getWebSocketsByWorkspaceID, workspaceID) + if err != nil { + return nil, err + } + defer rows.Close() + items := []Websocket{} + for rows.Next() { + var i Websocket + if err := rows.Scan( + &i.ID, + &i.WorkspaceID, + &i.FolderID, + &i.Name, + &i.Url, + &i.Description, + &i.LastRunAt, + &i.CreatedAt, + &i.UpdatedAt, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const updateFlowNodeWsConnection = `-- name: UpdateFlowNodeWsConnection :exec +INSERT INTO flow_node_ws_connection (flow_node_id, websocket_id) VALUES (?, ?) +ON CONFLICT(flow_node_id) DO UPDATE SET + websocket_id = excluded.websocket_id +` + +type UpdateFlowNodeWsConnectionParams struct { + FlowNodeID idwrap.IDWrap + WebsocketID *idwrap.IDWrap +} + +func (q *Queries) UpdateFlowNodeWsConnection(ctx context.Context, arg UpdateFlowNodeWsConnectionParams) error { + _, err := q.exec(ctx, q.updateFlowNodeWsConnectionStmt, updateFlowNodeWsConnection, arg.FlowNodeID, arg.WebsocketID) + return err +} + +const updateFlowNodeWsSend = `-- name: UpdateFlowNodeWsSend :exec +INSERT INTO flow_node_ws_send (flow_node_id, ws_connection_node_name, message) VALUES (?, ?, ?) +ON CONFLICT(flow_node_id) DO UPDATE SET + ws_connection_node_name = excluded.ws_connection_node_name, + message = excluded.message +` + +type UpdateFlowNodeWsSendParams struct { + FlowNodeID idwrap.IDWrap + WsConnectionNodeName string + Message string +} + +func (q *Queries) UpdateFlowNodeWsSend(ctx context.Context, arg UpdateFlowNodeWsSendParams) error { + _, err := q.exec(ctx, q.updateFlowNodeWsSendStmt, updateFlowNodeWsSend, arg.FlowNodeID, arg.WsConnectionNodeName, arg.Message) + return err +} + +const updateWebSocket = `-- name: UpdateWebSocket :exec +UPDATE websocket +SET + name = ?, + url = ?, + description = ?, + last_run_at = COALESCE(?, last_run_at), + updated_at = unixepoch() +WHERE id = ? +` + +type UpdateWebSocketParams struct { + Name string + Url string + Description string + LastRunAt interface{} + ID idwrap.IDWrap +} + +func (q *Queries) UpdateWebSocket(ctx context.Context, arg UpdateWebSocketParams) error { + _, err := q.exec(ctx, q.updateWebSocketStmt, updateWebSocket, + arg.Name, + arg.Url, + arg.Description, + arg.LastRunAt, + arg.ID, + ) + return err +} + +const updateWebSocketHeader = `-- name: UpdateWebSocketHeader :exec +UPDATE websocket_header +SET + header_key = ?, + header_value = ?, + description = ?, + enabled = ?, + display_order = ?, + updated_at = unixepoch() +WHERE id = ? +` + +type UpdateWebSocketHeaderParams struct { + HeaderKey string + HeaderValue string + Description string + Enabled bool + DisplayOrder float64 + ID idwrap.IDWrap +} + +func (q *Queries) UpdateWebSocketHeader(ctx context.Context, arg UpdateWebSocketHeaderParams) error { + _, err := q.exec(ctx, q.updateWebSocketHeaderStmt, updateWebSocketHeader, + arg.HeaderKey, + arg.HeaderValue, + arg.Description, + arg.Enabled, + arg.DisplayOrder, + arg.ID, + ) + return err +} diff --git a/packages/db/pkg/sqlc/queries/flow.sql b/packages/db/pkg/sqlc/queries/flow.sql index 43a055cf4..db9763adf 100644 --- a/packages/db/pkg/sqlc/queries/flow.sql +++ b/packages/db/pkg/sqlc/queries/flow.sql @@ -522,6 +522,33 @@ DELETE FROM flow_node_js WHERE flow_node_id = ?; +-- name: GetFlowNodeWait :one +SELECT + flow_node_id, + duration_ms +FROM + flow_node_wait +WHERE + flow_node_id = ?; + +-- name: CreateFlowNodeWait :exec +INSERT INTO + flow_node_wait (flow_node_id, duration_ms) +VALUES + (?, ?); + +-- name: UpdateFlowNodeWait :exec +UPDATE flow_node_wait +SET + duration_ms = ? +WHERE + flow_node_id = ?; + +-- name: DeleteFlowNodeWait :exec +DELETE FROM flow_node_wait +WHERE + flow_node_id = ?; + -- name: GetMigration :one SELECT id, @@ -741,6 +768,9 @@ DELETE FROM flow_node_condition WHERE flow_node_id NOT IN (SELECT id FROM flow_n -- name: CleanupOrphanedFlowNodeJs :exec DELETE FROM flow_node_js WHERE flow_node_id NOT IN (SELECT id FROM flow_node); +-- name: CleanupOrphanedFlowNodeWait :exec +DELETE FROM flow_node_wait WHERE flow_node_id NOT IN (SELECT id FROM flow_node); + -- name: CleanupOrphanedFlowEdges :exec DELETE FROM flow_edge WHERE source_id NOT IN (SELECT id FROM flow_node) OR target_id NOT IN (SELECT id FROM flow_node); diff --git a/packages/db/pkg/sqlc/queries/websocket.sql b/packages/db/pkg/sqlc/queries/websocket.sql new file mode 100644 index 000000000..dd7a70f00 --- /dev/null +++ b/packages/db/pkg/sqlc/queries/websocket.sql @@ -0,0 +1,134 @@ +-- +-- WebSocket Core Queries +-- + +-- name: GetWebSocket :one +SELECT + id, workspace_id, folder_id, name, url, + description, last_run_at, created_at, updated_at +FROM websocket +WHERE id = ? LIMIT 1; + +-- name: GetWebSocketsByWorkspaceID :many +SELECT + id, workspace_id, folder_id, name, url, + description, last_run_at, created_at, updated_at +FROM websocket +WHERE workspace_id = ? +ORDER BY updated_at DESC; + +-- name: GetWebSocketWorkspaceID :one +SELECT workspace_id +FROM websocket +WHERE id = ? +LIMIT 1; + +-- name: CreateWebSocket :exec +INSERT INTO websocket ( + id, workspace_id, folder_id, name, url, + description, last_run_at, created_at, updated_at +) +VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?); + +-- name: UpdateWebSocket :exec +UPDATE websocket +SET + name = ?, + url = ?, + description = ?, + last_run_at = COALESCE(?, last_run_at), + updated_at = unixepoch() +WHERE id = ?; + +-- name: DeleteWebSocket :exec +DELETE FROM websocket +WHERE id = ?; + +-- +-- WebSocket Header Queries +-- + +-- name: GetWebSocketHeaders :many +SELECT + id, websocket_id, header_key, header_value, description, + enabled, display_order, created_at, updated_at +FROM websocket_header +WHERE websocket_id = ? +ORDER BY display_order; + +-- name: GetWebSocketHeaderByID :one +SELECT + id, websocket_id, header_key, header_value, description, + enabled, display_order, created_at, updated_at +FROM websocket_header +WHERE id = ? LIMIT 1; + +-- name: CreateWebSocketHeader :exec +INSERT INTO websocket_header ( + id, websocket_id, header_key, header_value, description, + enabled, display_order, created_at, updated_at +) +VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?); + +-- name: UpdateWebSocketHeader :exec +UPDATE websocket_header +SET + header_key = ?, + header_value = ?, + description = ?, + enabled = ?, + display_order = ?, + updated_at = unixepoch() +WHERE id = ?; + +-- name: DeleteWebSocketHeader :exec +DELETE FROM websocket_header +WHERE id = ?; + +-- name: DeleteWebSocketHeadersByWebSocketID :exec +DELETE FROM websocket_header +WHERE websocket_id = ?; + +-- +-- Flow Node WebSocket Queries +-- + +-- name: GetFlowNodeWsConnection :one +SELECT + flow_node_id, + websocket_id +FROM flow_node_ws_connection +WHERE flow_node_id = ? +LIMIT 1; + +-- name: CreateFlowNodeWsConnection :exec +INSERT INTO flow_node_ws_connection (flow_node_id, websocket_id) VALUES (?, ?); + +-- name: UpdateFlowNodeWsConnection :exec +INSERT INTO flow_node_ws_connection (flow_node_id, websocket_id) VALUES (?, ?) +ON CONFLICT(flow_node_id) DO UPDATE SET + websocket_id = excluded.websocket_id; + +-- name: DeleteFlowNodeWsConnection :exec +DELETE FROM flow_node_ws_connection WHERE flow_node_id = ?; + +-- name: GetFlowNodeWsSend :one +SELECT + flow_node_id, + ws_connection_node_name, + message +FROM flow_node_ws_send +WHERE flow_node_id = ? +LIMIT 1; + +-- name: CreateFlowNodeWsSend :exec +INSERT INTO flow_node_ws_send (flow_node_id, ws_connection_node_name, message) VALUES (?, ?, ?); + +-- name: UpdateFlowNodeWsSend :exec +INSERT INTO flow_node_ws_send (flow_node_id, ws_connection_node_name, message) VALUES (?, ?, ?) +ON CONFLICT(flow_node_id) DO UPDATE SET + ws_connection_node_name = excluded.ws_connection_node_name, + message = excluded.message; + +-- name: DeleteFlowNodeWsSend :exec +DELETE FROM flow_node_ws_send WHERE flow_node_id = ?; diff --git a/packages/db/pkg/sqlc/schema/05_flow.sql b/packages/db/pkg/sqlc/schema/05_flow.sql index 6d7729c6c..c80a925c4 100644 --- a/packages/db/pkg/sqlc/schema/05_flow.sql +++ b/packages/db/pkg/sqlc/schema/05_flow.sql @@ -103,6 +103,11 @@ CREATE TABLE flow_node_js ( code_compress_type INT8 NOT NULL ); +CREATE TABLE flow_node_wait ( + flow_node_id BLOB NOT NULL PRIMARY KEY, + duration_ms BIGINT NOT NULL +); + CREATE TABLE flow_variable ( id BLOB NOT NULL PRIMARY KEY, flow_id BLOB NOT NULL, diff --git a/packages/db/pkg/sqlc/schema/10_websocket.sql b/packages/db/pkg/sqlc/schema/10_websocket.sql new file mode 100644 index 000000000..d8be5935d --- /dev/null +++ b/packages/db/pkg/sqlc/schema/10_websocket.sql @@ -0,0 +1,57 @@ +/* + * + * WEBSOCKET SYSTEM + * WebSocket connection support for flows and standalone testing + * + */ + +-- Core WebSocket connection definition +CREATE TABLE websocket ( + id BLOB NOT NULL PRIMARY KEY, + workspace_id BLOB NOT NULL, + folder_id BLOB, + name TEXT NOT NULL, + url TEXT NOT NULL, + description TEXT NOT NULL DEFAULT '', + last_run_at BIGINT NULL, + created_at BIGINT NOT NULL DEFAULT (unixepoch()), + updated_at BIGINT NOT NULL DEFAULT (unixepoch()), + + FOREIGN KEY (workspace_id) REFERENCES workspaces (id) ON DELETE CASCADE, + FOREIGN KEY (folder_id) REFERENCES files (id) ON DELETE SET NULL +); + +CREATE INDEX websocket_workspace_idx ON websocket (workspace_id); +CREATE INDEX websocket_folder_idx ON websocket (folder_id) WHERE folder_id IS NOT NULL; + +-- WebSocket connection headers (sent during handshake) +CREATE TABLE websocket_header ( + id BLOB NOT NULL PRIMARY KEY, + websocket_id BLOB NOT NULL, + header_key TEXT NOT NULL, + header_value TEXT NOT NULL, + description TEXT NOT NULL DEFAULT '', + enabled BOOLEAN NOT NULL DEFAULT TRUE, + display_order REAL NOT NULL DEFAULT 0, + created_at BIGINT NOT NULL DEFAULT (unixepoch()), + updated_at BIGINT NOT NULL DEFAULT (unixepoch()), + + FOREIGN KEY (websocket_id) REFERENCES websocket (id) ON DELETE CASCADE +); + +CREATE INDEX websocket_header_ws_idx ON websocket_header (websocket_id); +CREATE INDEX websocket_header_order_idx ON websocket_header (websocket_id, display_order); + +-- Flow node: WebSocket Connection (entry/listener node) +CREATE TABLE flow_node_ws_connection ( + flow_node_id BLOB NOT NULL PRIMARY KEY, + websocket_id BLOB, + FOREIGN KEY (websocket_id) REFERENCES websocket (id) ON DELETE SET NULL +); + +-- Flow node: WebSocket Send (action node) +CREATE TABLE flow_node_ws_send ( + flow_node_id BLOB NOT NULL PRIMARY KEY, + ws_connection_node_name TEXT NOT NULL DEFAULT '', + message TEXT NOT NULL DEFAULT '' +); diff --git a/packages/db/pkg/sqlc/sqlc.yaml b/packages/db/pkg/sqlc/sqlc.yaml index 2402ae3ae..b8a7e5067 100644 --- a/packages/db/pkg/sqlc/sqlc.yaml +++ b/packages/db/pkg/sqlc/sqlc.yaml @@ -932,3 +932,56 @@ sql: import: 'github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap' package: 'idwrap' type: 'IDWrap' + ## WebSocket system + ### websocket table + - column: 'websocket.id' + go_type: + import: 'github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap' + package: 'idwrap' + type: 'IDWrap' + - column: 'websocket.workspace_id' + go_type: + import: 'github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap' + package: 'idwrap' + type: 'IDWrap' + - column: 'websocket.folder_id' + go_type: + import: 'github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap' + package: 'idwrap' + type: 'IDWrap' + pointer: true + ### websocket_header table + - column: 'websocket_header.id' + go_type: + import: 'github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap' + package: 'idwrap' + type: 'IDWrap' + - column: 'websocket_header.websocket_id' + go_type: + import: 'github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap' + package: 'idwrap' + type: 'IDWrap' + ### flow_node_ws_connection table + - column: 'flow_node_ws_connection.flow_node_id' + go_type: + import: 'github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap' + package: 'idwrap' + type: 'IDWrap' + - column: 'flow_node_ws_connection.websocket_id' + go_type: + import: 'github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap' + package: 'idwrap' + type: 'IDWrap' + pointer: true + ### flow_node_ws_send table + - column: 'flow_node_ws_send.flow_node_id' + go_type: + import: 'github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap' + package: 'idwrap' + type: 'IDWrap' + ### flow_node_wait table + - column: 'flow_node_wait.flow_node_id' + go_type: + import: 'github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap' + package: 'idwrap' + type: 'IDWrap' diff --git a/packages/server/cmd/serverrun/serverrun.go b/packages/server/cmd/serverrun/serverrun.go index ae80bae5f..4e6d5fa85 100644 --- a/packages/server/cmd/serverrun/serverrun.go +++ b/packages/server/cmd/serverrun/serverrun.go @@ -34,6 +34,7 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/internal/api/rimportv2" "github.com/the-dev-tools/dev-tools/packages/server/internal/api/rlog" "github.com/the-dev-tools/dev-tools/packages/server/internal/api/rreference" + "github.com/the-dev-tools/dev-tools/packages/server/internal/api/rwebsocket" "github.com/the-dev-tools/dev-tools/packages/server/internal/api/rworkspace" "github.com/the-dev-tools/dev-tools/packages/server/internal/migrations" "github.com/the-dev-tools/dev-tools/packages/server/pkg/credvault" @@ -52,6 +53,7 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sgraphql" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/shttp" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/suser" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/swebsocket" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sworkspace" "github.com/the-dev-tools/dev-tools/packages/server/pkg/streamregistry" envapiv1 "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/api/environment/v1" @@ -193,6 +195,13 @@ func Run() error { flowNodeAiProviderService := sflow.NewNodeAiProviderService(queries) flowNodeMemoryService := sflow.NewNodeMemoryService(queries) flowNodeGraphQLService := sflow.NewNodeGraphQLService(queries) + flowNodeWsConnectionService := sflow.NewNodeWsConnectionService(queries) + flowNodeWsSendService := sflow.NewNodeWsSendService(queries) + flowNodeWaitService := sflow.NewNodeWaitService(queries) + + // WebSocket + websocketService := swebsocket.New(queries, logger) + websocketHeaderService := swebsocket.NewWebSocketHeaderService(queries) // GraphQL graphqlService := sgraphql.New(queries, logger) @@ -466,8 +475,13 @@ func Run() error { NodeAI: &flowNodeAIService, NodeAiProvider: &flowNodeAiProviderService, NodeMemory: &flowNodeMemoryService, - NodeGraphQL: &flowNodeGraphQLService, - NodeExecution: &nodeExecutionService, + NodeGraphQL: &flowNodeGraphQLService, + NodeWsConnection: &flowNodeWsConnectionService, + NodeWsSend: &flowNodeWsSendService, + NodeWait: &flowNodeWaitService, + WebSocket: &websocketService, + WebSocketHeader: &websocketHeaderService, + NodeExecution: &nodeExecutionService, FlowVariable: &flowVariableService, Env: &environmentService, Var: &variableService, @@ -497,6 +511,7 @@ func Run() error { Memory: streamers.Memory, NodeGraphQL: streamers.NodeGraphQL, GraphQL: streamers.GraphQL, + WebSocket: streamers.WebSocket, Execution: streamers.Execution, HttpResponse: streamers.HttpResponse, HttpResponseHeader: streamers.HttpResponseHeader, @@ -519,14 +534,19 @@ func Run() error { // ExportV2 Service exportV2Srv := rexportv2.NewExportV2RPC(rexportv2.ExportV2Deps{ - DB: currentDB, - Queries: queries, - Workspace: workspaceService, - User: userService, - Http: &httpService, - Flow: &flowService, - File: fileService, - Logger: logger, + DB: currentDB, + Queries: queries, + Workspace: workspaceService, + User: userService, + Http: &httpService, + Flow: &flowService, + File: fileService, + GraphQL: &graphqlService, + GraphQLHeader: &graphqlHeaderService, + GraphQLAssert: &graphqlAssertService, + WebSocket: &websocketService, + WebSocketHeader: &websocketHeaderService, + Logger: logger, }) newServiceManager.addService(rexportv2.CreateExportV2Service(*exportV2Srv, optionsAll)) @@ -618,6 +638,18 @@ func Run() error { }) newServiceManager.addService(rreference.CreateService(refServiceRPC, optionsAll)) + // WebSocket Service + wsSrv := rwebsocket.New(rwebsocket.Deps{ + DB: currentDB, + WS: websocketService, + WSH: websocketHeaderService, + US: userService, + Workspace: workspaceService, + WSStream: streamers.WebSocket, + WSHStream: streamers.WebSocketHeader, + }) + newServiceManager.addService(rwebsocket.CreateService(wsSrv, optionsAll)) + // Start services go func() { err := api.ListenServices(newServiceManager.getServices(), port) @@ -774,6 +806,8 @@ type streamers struct { CredentialOpenAi eventstream.SyncStreamer[rcredential.CredentialOpenAiTopic, rcredential.CredentialOpenAiEvent] CredentialGemini eventstream.SyncStreamer[rcredential.CredentialGeminiTopic, rcredential.CredentialGeminiEvent] CredentialAnthropic eventstream.SyncStreamer[rcredential.CredentialAnthropicTopic, rcredential.CredentialAnthropicEvent] + WebSocket eventstream.SyncStreamer[rwebsocket.WebSocketTopic, rwebsocket.WebSocketEvent] + WebSocketHeader eventstream.SyncStreamer[rwebsocket.WebSocketHeaderTopic, rwebsocket.WebSocketHeaderEvent] } func newStreamers() *streamers { @@ -819,6 +853,8 @@ func newStreamers() *streamers { CredentialOpenAi: memory.NewInMemorySyncStreamer[rcredential.CredentialOpenAiTopic, rcredential.CredentialOpenAiEvent](), CredentialGemini: memory.NewInMemorySyncStreamer[rcredential.CredentialGeminiTopic, rcredential.CredentialGeminiEvent](), CredentialAnthropic: memory.NewInMemorySyncStreamer[rcredential.CredentialAnthropicTopic, rcredential.CredentialAnthropicEvent](), + WebSocket: memory.NewInMemorySyncStreamer[rwebsocket.WebSocketTopic, rwebsocket.WebSocketEvent](), + WebSocketHeader: memory.NewInMemorySyncStreamer[rwebsocket.WebSocketHeaderTopic, rwebsocket.WebSocketHeaderEvent](), } } @@ -864,6 +900,8 @@ func (s *streamers) shutdown() { s.CredentialOpenAi.Shutdown() s.CredentialGemini.Shutdown() s.CredentialAnthropic.Shutdown() + s.WebSocket.Shutdown() + s.WebSocketHeader.Shutdown() } // registerCascadeHandlers registers all handlers needed for cascade deletion events. diff --git a/packages/server/go.mod b/packages/server/go.mod index 5ab3b3353..b1760b14f 100644 --- a/packages/server/go.mod +++ b/packages/server/go.mod @@ -6,6 +6,7 @@ require ( connectrpc.com/connect v1.19.1 github.com/Microsoft/go-winio v0.6.2 github.com/andybalholm/brotli v1.2.0 + github.com/coder/websocket v1.8.14 github.com/expr-lang/expr v1.17.7 github.com/goccy/go-json v0.10.5 github.com/golang-jwt/jwt/v5 v5.3.0 @@ -21,9 +22,11 @@ require ( github.com/tmc/langchaingo v0.1.14 golang.org/x/crypto v0.46.0 golang.org/x/net v0.48.0 + golang.org/x/sync v0.19.0 golang.org/x/text v0.32.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 + modernc.org/sqlite v1.43.0 ) require ( @@ -65,7 +68,6 @@ require ( go.uber.org/zap v1.27.1 // indirect golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sync v0.19.0 // indirect golang.org/x/sys v0.40.0 // indirect golang.org/x/time v0.12.0 // indirect google.golang.org/api v0.246.0 // indirect @@ -77,7 +79,6 @@ require ( modernc.org/libc v1.67.4 // indirect modernc.org/mathutil v1.7.1 // indirect modernc.org/memory v1.11.0 // indirect - modernc.org/sqlite v1.43.0 // indirect ) replace ( diff --git a/packages/server/go.sum b/packages/server/go.sum index c42857ce8..b451ff1d3 100644 --- a/packages/server/go.sum +++ b/packages/server/go.sum @@ -26,6 +26,8 @@ github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ= github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/coder/websocket v1.8.14 h1:9L0p0iKiNOibykf283eHkKUHHrpG7f65OE3BhhO7v9g= +github.com/coder/websocket v1.8.14/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= diff --git a/packages/server/internal/api/rexportv2/export.go b/packages/server/internal/api/rexportv2/export.go index 3221b247c..a65275137 100644 --- a/packages/server/internal/api/rexportv2/export.go +++ b/packages/server/internal/api/rexportv2/export.go @@ -3,6 +3,7 @@ package rexportv2 import ( "context" + "encoding/json" "fmt" "log/slog" "strings" @@ -10,11 +11,17 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/internal/api/middleware/mwauth" "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" "github.com/the-dev-tools/dev-tools/packages/server/pkg/ioworkspace" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mfile" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mgraphql" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sfile" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sflow" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sgraphql" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/shttp" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/suser" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/swebsocket" "github.com/the-dev-tools/dev-tools/packages/server/pkg/translate/yamlflowsimplev2" + + "gopkg.in/yaml.v3" ) // Interfaces @@ -37,20 +44,40 @@ type Validator interface { // SimpleExporter implements the Exporter interface using modern services type SimpleExporter struct { - httpService *shttp.HTTPService - flowService *sflow.FlowService - fileService *sfile.FileService - ioWorkspaceService *ioworkspace.IOWorkspaceService - storage Storage + httpService *shttp.HTTPService + flowService *sflow.FlowService + fileService *sfile.FileService + ioWorkspaceService *ioworkspace.IOWorkspaceService + graphqlService *sgraphql.GraphQLService + graphqlHeaderService *sgraphql.GraphQLHeaderService + graphqlAssertService *sgraphql.GraphQLAssertService + websocketService *swebsocket.WebSocketService + websocketHeaderService *swebsocket.WebSocketHeaderService + storage Storage } // NewExporter creates a new SimpleExporter -func NewExporter(httpService *shttp.HTTPService, flowService *sflow.FlowService, fileService *sfile.FileService, ioWorkspaceService *ioworkspace.IOWorkspaceService) *SimpleExporter { +func NewExporter( + httpService *shttp.HTTPService, + flowService *sflow.FlowService, + fileService *sfile.FileService, + ioWorkspaceService *ioworkspace.IOWorkspaceService, + graphqlService *sgraphql.GraphQLService, + graphqlHeaderService *sgraphql.GraphQLHeaderService, + graphqlAssertService *sgraphql.GraphQLAssertService, + websocketService *swebsocket.WebSocketService, + websocketHeaderService *swebsocket.WebSocketHeaderService, +) *SimpleExporter { return &SimpleExporter{ - httpService: httpService, - flowService: flowService, - fileService: fileService, - ioWorkspaceService: ioWorkspaceService, + httpService: httpService, + flowService: flowService, + fileService: fileService, + ioWorkspaceService: ioWorkspaceService, + graphqlService: graphqlService, + graphqlHeaderService: graphqlHeaderService, + graphqlAssertService: graphqlAssertService, + websocketService: websocketService, + websocketHeaderService: websocketHeaderService, } } @@ -171,6 +198,227 @@ func (e *SimpleExporter) ExportToCurl(ctx context.Context, data *WorkspaceExport return strings.Join(commands, "\n\n"), nil } +// ExportGraphQLToCurl exports GraphQL requests as cURL commands (POST with JSON body) +func (e *SimpleExporter) ExportGraphQLToCurl(ctx context.Context, graphqlIDs []idwrap.IDWrap) (string, error) { + if len(graphqlIDs) == 0 { + return "", nil + } + + var commands []string + for _, gqlID := range graphqlIDs { + gql, err := e.graphqlService.Get(ctx, gqlID) + if err != nil { + continue + } + + headers, err := e.graphqlHeaderService.GetByGraphQLID(ctx, gqlID) + if err != nil { + headers = nil + } + + var cmd strings.Builder + cmd.WriteString(fmt.Sprintf("curl -X POST '%s'", gql.Url)) + cmd.WriteString(" -H \"Content-Type: application/json\"") + + for _, h := range headers { + if h.Enabled { + cmd.WriteString(fmt.Sprintf(" -H \"%s: %s\"", h.Key, h.Value)) + } + } + + // Build JSON body with query and variables + body := buildGraphQLJSONBody(gql.Query, gql.Variables) + cmd.WriteString(fmt.Sprintf(" --data-raw '%s'", strings.ReplaceAll(body, "'", "'\"'\"'"))) + cmd.WriteString(fmt.Sprintf(" # %s", gql.Name)) + commands = append(commands, cmd.String()) + } + + if len(commands) == 0 { + return "", nil + } + return strings.Join(commands, "\n\n"), nil +} + +// buildGraphQLJSONBody builds a JSON string with query and optional variables +func buildGraphQLJSONBody(query, variables string) string { + // Escape the query string for JSON + queryJSON, _ := json.Marshal(query) + + if variables == "" || variables == "{}" { + return fmt.Sprintf(`{"query":%s}`, string(queryJSON)) + } + + // Variables is already a JSON string, use it directly + return fmt.Sprintf(`{"query":%s,"variables":%s}`, string(queryJSON), variables) +} + +// ExportGraphQLToYAML exports GraphQL requests as a focused YAML +func (e *SimpleExporter) ExportGraphQLToYAML(ctx context.Context, graphqlIDs []idwrap.IDWrap) ([]byte, error) { + var gqlDefs []yamlflowsimplev2.YamlGraphQLDefV2 + + for _, gqlID := range graphqlIDs { + gql, err := e.graphqlService.Get(ctx, gqlID) + if err != nil { + continue + } + + headers, err := e.graphqlHeaderService.GetByGraphQLID(ctx, gqlID) + if err != nil { + headers = nil + } + + asserts, err := e.graphqlAssertService.GetByGraphQLID(ctx, gqlID) + if err != nil { + asserts = nil + } + + gqlDef := yamlflowsimplev2.YamlGraphQLDefV2{ + Name: gql.Name, + URL: gql.Url, + Query: gql.Query, + Variables: gql.Variables, + Headers: buildGraphQLHeaderMapOrSliceExport(headers), + Assertions: buildGraphQLAssertionsExport(asserts), + } + gqlDefs = append(gqlDefs, gqlDef) + } + + yamlFormat := yamlflowsimplev2.YamlFlowFormatV2{ + WorkspaceName: "export", + GraphQLRequests: gqlDefs, + } + + return yaml.Marshal(yamlFormat) +} + +// ExportWebSocketToYAML exports WebSocket items as a focused YAML +func (e *SimpleExporter) ExportWebSocketToYAML(ctx context.Context, websocketIDs []idwrap.IDWrap) ([]byte, error) { + // Build a minimal YAML with websocket info + type wsYAMLItem struct { + Name string `yaml:"name"` + URL string `yaml:"url"` + Headers map[string]string `yaml:"headers,omitempty"` + } + + type wsYAMLFormat struct { + WorkspaceName string `yaml:"workspace_name"` + WebSockets []wsYAMLItem `yaml:"websockets"` + } + + var items []wsYAMLItem + for _, wsID := range websocketIDs { + ws, err := e.websocketService.Get(ctx, wsID) + if err != nil { + continue + } + + headers, err := e.websocketHeaderService.GetByWebSocketID(ctx, wsID) + if err != nil { + headers = nil + } + + headerMap := make(map[string]string) + for _, h := range headers { + if h.Enabled { + headerMap[h.Key] = h.Value + } + } + + item := wsYAMLItem{ + Name: ws.Name, + URL: ws.Url, + } + if len(headerMap) > 0 { + item.Headers = headerMap + } + items = append(items, item) + } + + wsFormat := wsYAMLFormat{ + WorkspaceName: "export", + WebSockets: items, + } + + return yaml.Marshal(wsFormat) +} + +// tryPerItemYAMLExport checks if fileIDs refer to GraphQL or WebSocket items +// and exports them as focused YAML. Returns (data, name, handled). +func (e *SimpleExporter) tryPerItemYAMLExport(ctx context.Context, fileIDs []idwrap.IDWrap) ([]byte, string, bool) { + if e.fileService == nil { + return nil, "", false + } + + // Check the first fileID's content type + file, err := e.fileService.GetFile(ctx, fileIDs[0]) + if err != nil { + return nil, "", false + } + + switch file.ContentType { + case mfile.ContentTypeGraphQL: + data, err := e.ExportGraphQLToYAML(ctx, fileIDs) + if err != nil { + return nil, "", false + } + return data, "graphql_export.yaml", true + + case mfile.ContentTypeWebSocket: + data, err := e.ExportWebSocketToYAML(ctx, fileIDs) + if err != nil { + return nil, "", false + } + return data, "websocket_export.yaml", true + + case mfile.ContentTypeHTTP, mfile.ContentTypeHTTPDelta: + // Use FilterByHTTPIDs for per-item HTTP export + exportOpts := ioworkspace.ExportOptions{ + WorkspaceID: file.WorkspaceID, + IncludeHTTP: true, + FilterByHTTPIDs: fileIDs, + } + bundle, err := e.ioWorkspaceService.Export(ctx, exportOpts) + if err != nil { + return nil, "", false + } + yamlData, err := yamlflowsimplev2.MarshalSimplifiedYAML(bundle) + if err != nil { + return nil, "", false + } + return yamlData, "http_export.yaml", true + + default: + return nil, "", false + } +} + +func buildGraphQLHeaderMapOrSliceExport(headers []mgraphql.GraphQLHeader) yamlflowsimplev2.HeaderMapOrSlice { + if len(headers) == 0 { + return nil + } + var result []yamlflowsimplev2.YamlNameValuePairV2 + for _, h := range headers { + result = append(result, yamlflowsimplev2.YamlNameValuePairV2{ + Name: h.Key, + Value: h.Value, + Enabled: h.Enabled, + Description: h.Description, + }) + } + return yamlflowsimplev2.HeaderMapOrSlice(result) +} + +func buildGraphQLAssertionsExport(asserts []mgraphql.GraphQLAssert) yamlflowsimplev2.AssertionsOrSlice { + if len(asserts) == 0 { + return nil + } + var result []yamlflowsimplev2.YamlAssertionV2 + for _, a := range asserts { + result = append(result, yamlflowsimplev2.YamlAssertionV2{Expression: a.Value, Enabled: a.Enabled}) + } + return yamlflowsimplev2.AssertionsOrSlice(result) +} + // Validator Implementation // SimpleValidator implements basic validation @@ -336,6 +584,17 @@ func (s *Service) Export(ctx context.Context, req *ExportRequest) (*ExportRespon switch req.Format { case ExportFormat_YAML: + // Try per-item YAML export for GraphQL and WebSocket items + if simpleExporter, ok := s.exporter.(*SimpleExporter); ok && len(req.FileIDs) > 0 { + itemData, itemName, handled := simpleExporter.tryPerItemYAMLExport(ctx, req.FileIDs) + if handled { + return &ExportResponse{ + Name: itemName, + Data: itemData, + }, nil + } + } + data, err = s.exporter.ExportToYAML(ctx, exportData, req.Simplified, req.FileIDs) if err != nil { return nil, fmt.Errorf("YAML export failed: %w", err) diff --git a/packages/server/internal/api/rexportv2/exporter_test.go b/packages/server/internal/api/rexportv2/exporter_test.go index 28578fd77..1230eefff 100644 --- a/packages/server/internal/api/rexportv2/exporter_test.go +++ b/packages/server/internal/api/rexportv2/exporter_test.go @@ -15,7 +15,9 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/senv" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sfile" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sflow" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sgraphql" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/shttp" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/swebsocket" "github.com/the-dev-tools/dev-tools/packages/server/pkg/testutil" ) @@ -36,7 +38,12 @@ func TestNewExporter(t *testing.T) { // Create IOWorkspaceService ioWorkspaceService := ioworkspace.New(base.Queries, logger) - exporter := NewExporter(&httpService, &flowService, fileService, ioWorkspaceService) + graphqlService := sgraphql.New(base.Queries, logger) + graphqlHeaderService := sgraphql.NewGraphQLHeaderService(base.Queries) + graphqlAssertService := sgraphql.NewGraphQLAssertService(base.Queries) + websocketService := swebsocket.New(base.Queries, logger) + websocketHeaderService := swebsocket.NewWebSocketHeaderService(base.Queries) + exporter := NewExporter(&httpService, &flowService, fileService, ioWorkspaceService, &graphqlService, &graphqlHeaderService, &graphqlAssertService, &websocketService, &websocketHeaderService) storage := NewStorage(&workspaceService, &httpService, &flowService, fileService) exporter.SetStorage(storage) @@ -123,7 +130,12 @@ func TestDefaultExporter_ExportToYAML_WithEnvironments(t *testing.T) { workspaceService := services.WorkspaceService ioWorkspaceService := ioworkspace.New(base.Queries, logger) - exporter := NewExporter(&httpService, &flowService, fileService, ioWorkspaceService) + graphqlService := sgraphql.New(base.Queries, logger) + graphqlHeaderService := sgraphql.NewGraphQLHeaderService(base.Queries) + graphqlAssertService := sgraphql.NewGraphQLAssertService(base.Queries) + websocketService := swebsocket.New(base.Queries, logger) + websocketHeaderService := swebsocket.NewWebSocketHeaderService(base.Queries) + exporter := NewExporter(&httpService, &flowService, fileService, ioWorkspaceService, &graphqlService, &graphqlHeaderService, &graphqlAssertService, &websocketService, &websocketHeaderService) storage := NewStorage(&workspaceService, &httpService, &flowService, fileService) exporter.SetStorage(storage) @@ -524,7 +536,12 @@ func setupExporterWithoutData(t *testing.T, ctx context.Context) *SimpleExporter // Create IOWorkspaceService ioWorkspaceService := ioworkspace.New(base.Queries, logger) - exporter := NewExporter(&httpService, &flowService, fileService, ioWorkspaceService) + graphqlService := sgraphql.New(base.Queries, logger) + graphqlHeaderService := sgraphql.NewGraphQLHeaderService(base.Queries) + graphqlAssertService := sgraphql.NewGraphQLAssertService(base.Queries) + websocketService := swebsocket.New(base.Queries, logger) + websocketHeaderService := swebsocket.NewWebSocketHeaderService(base.Queries) + exporter := NewExporter(&httpService, &flowService, fileService, ioWorkspaceService, &graphqlService, &graphqlHeaderService, &graphqlAssertService, &websocketService, &websocketHeaderService) storage := NewStorage(&workspaceService, &httpService, &flowService, fileService) exporter.SetStorage(storage) @@ -549,7 +566,12 @@ func setupExporterWithTestData(t *testing.T, ctx context.Context) (*SimpleExport // Create IOWorkspaceService ioWorkspaceService := ioworkspace.New(base.Queries, logger) - exporter := NewExporter(&httpService, &flowService, fileService, ioWorkspaceService) + graphqlService := sgraphql.New(base.Queries, logger) + graphqlHeaderService := sgraphql.NewGraphQLHeaderService(base.Queries) + graphqlAssertService := sgraphql.NewGraphQLAssertService(base.Queries) + websocketService := swebsocket.New(base.Queries, logger) + websocketHeaderService := swebsocket.NewWebSocketHeaderService(base.Queries) + exporter := NewExporter(&httpService, &flowService, fileService, ioWorkspaceService, &graphqlService, &graphqlHeaderService, &graphqlAssertService, &websocketService, &websocketHeaderService) storage := NewStorage(&workspaceService, &httpService, &flowService, fileService) exporter.SetStorage(storage) diff --git a/packages/server/internal/api/rexportv2/rexportv2.go b/packages/server/internal/api/rexportv2/rexportv2.go index f8633de31..1d21c103a 100644 --- a/packages/server/internal/api/rexportv2/rexportv2.go +++ b/packages/server/internal/api/rexportv2/rexportv2.go @@ -14,8 +14,10 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/pkg/ioworkspace" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sfile" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sflow" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sgraphql" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/shttp" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/suser" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/swebsocket" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sworkspace" exportv1 "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/api/export/v1" "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/api/export/v1/exportv1connect" @@ -158,14 +160,19 @@ type ExportV2RPC struct { } type ExportV2Deps struct { - DB *sql.DB - Queries *gen.Queries - Workspace sworkspace.WorkspaceService - User suser.UserService - Http *shttp.HTTPService - Flow *sflow.FlowService - File *sfile.FileService - Logger *slog.Logger + DB *sql.DB + Queries *gen.Queries + Workspace sworkspace.WorkspaceService + User suser.UserService + Http *shttp.HTTPService + Flow *sflow.FlowService + File *sfile.FileService + GraphQL *sgraphql.GraphQLService + GraphQLHeader *sgraphql.GraphQLHeaderService + GraphQLAssert *sgraphql.GraphQLAssertService + WebSocket *swebsocket.WebSocketService + WebSocketHeader *swebsocket.WebSocketHeaderService + Logger *slog.Logger } func (d *ExportV2Deps) Validate() error { @@ -203,7 +210,9 @@ func NewExportV2RPC(deps ExportV2Deps) *ExportV2RPC { storage := NewStorage(&deps.Workspace, deps.Http, deps.Flow, deps.File) // Create simple exporter with IOWorkspaceService - exporter := NewExporter(deps.Http, deps.Flow, deps.File, ioWorkspaceService) + exporter := NewExporter(deps.Http, deps.Flow, deps.File, ioWorkspaceService, + deps.GraphQL, deps.GraphQLHeader, deps.GraphQLAssert, + deps.WebSocket, deps.WebSocketHeader) // Create simple validator validator := NewValidator(&deps.User) @@ -291,6 +300,49 @@ func (h *ExportV2RPC) ExportCurl(ctx context.Context, req *connect.Request[expor return connect.NewResponse(protoResp), nil } +// ExportCurlGraphQL implements the ExportCurlGraphQL RPC method +func (h *ExportV2RPC) ExportCurlGraphQL(ctx context.Context, req *connect.Request[exportv1.ExportCurlGraphQLRequest]) (*connect.Response[exportv1.ExportCurlGraphQLResponse], error) { + h.logger.Info("Received ExportCurlGraphQL request", + "workspace_id", req.Msg.WorkspaceId, + "graphql_ids_count", len(req.Msg.GraphqlIds)) + + // Parse workspace ID + workspaceID, err := idwrap.NewFromBytes(req.Msg.WorkspaceId) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, NewValidationError("workspaceId", err.Error())) + } + + // Validate workspace access + if err := h.service.validator.ValidateWorkspaceAccess(ctx, workspaceID); err != nil { + return nil, handleServiceError(err) + } + + // Parse GraphQL IDs + graphqlIDs := make([]idwrap.IDWrap, 0, len(req.Msg.GraphqlIds)) + for _, idBytes := range req.Msg.GraphqlIds { + gqlID, err := idwrap.NewFromBytes(idBytes) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, NewValidationError("graphqlIds", err.Error())) + } + graphqlIDs = append(graphqlIDs, gqlID) + } + + // Get the exporter + simpleExporter, ok := h.service.exporter.(*SimpleExporter) + if !ok { + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("exporter does not support GraphQL cURL export")) + } + + curlData, err := simpleExporter.ExportGraphQLToCurl(ctx, graphqlIDs) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + return connect.NewResponse(&exportv1.ExportCurlGraphQLResponse{ + Data: curlData, + }), nil +} + // Private conversion functions // convertToExportRequest converts protobuf request to internal request model diff --git a/packages/server/internal/api/rfile/rfile.go b/packages/server/internal/api/rfile/rfile.go index d25c87e2e..6ffb22ad5 100644 --- a/packages/server/internal/api/rfile/rfile.go +++ b/packages/server/internal/api/rfile/rfile.go @@ -142,6 +142,8 @@ func toAPIFileKind(kind mfile.ContentType) apiv1.FileKind { return apiv1.FileKind_FILE_KIND_CREDENTIAL case mfile.ContentTypeGraphQL: return apiv1.FileKind_FILE_KIND_GRAPH_Q_L + case mfile.ContentTypeWebSocket: + return apiv1.FileKind_FILE_KIND_WEB_SOCKET default: return apiv1.FileKind_FILE_KIND_UNSPECIFIED } @@ -162,6 +164,8 @@ func fromAPIFileKind(kind apiv1.FileKind) mfile.ContentType { return mfile.ContentTypeCredential case apiv1.FileKind_FILE_KIND_GRAPH_Q_L: return mfile.ContentTypeGraphQL + case apiv1.FileKind_FILE_KIND_WEB_SOCKET: + return mfile.ContentTypeWebSocket default: return mfile.ContentTypeUnknown } diff --git a/packages/server/internal/api/rflowv2/logging_test.go b/packages/server/internal/api/rflowv2/logging_test.go index 61e7520be..be32c3e7f 100644 --- a/packages/server/internal/api/rflowv2/logging_test.go +++ b/packages/server/internal/api/rflowv2/logging_test.go @@ -18,6 +18,7 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/pkg/dbtime" "github.com/the-dev-tools/dev-tools/packages/server/pkg/eventstream/memory" "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/flowbuilder" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/flowexec" "github.com/the-dev-tools/dev-tools/packages/server/pkg/http/resolver" "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" @@ -81,6 +82,11 @@ func TestFlowRun_Logging(t *testing.T) { nil, // NodeAiProviderService nil, // NodeMemoryService nil, // NodeGraphQLService + nil, // NodeWsConnectionService + nil, // NodeWsSendService + nil, // NodeWaitService + nil, // WebSocketService + nil, // WebSocketHeaderService nil, // GraphQLService nil, // GraphQLHeaderService &wsService, @@ -110,7 +116,7 @@ func TestFlowRun_Logging(t *testing.T) { fvs: &flowVarService, logger: logger, logStream: logStreamer, - builder: builder, + sessionFactory: &flowexec.LocalSessionFactory{Builder: builder}, runningFlows: make(map[string]context.CancelFunc), } diff --git a/packages/server/internal/api/rflowv2/node_config_sync_test.go b/packages/server/internal/api/rflowv2/node_config_sync_test.go index d5de51d17..d7e175a76 100644 --- a/packages/server/internal/api/rflowv2/node_config_sync_test.go +++ b/packages/server/internal/api/rflowv2/node_config_sync_test.go @@ -283,7 +283,7 @@ func TestNodeHttpSync_PublishesEventsOnCRUD(t *testing.T) { events := collectNodeEvents(registry.nodeEvents, 1, 100*time.Millisecond) require.Len(t, events, 1) - assert.Equal(t, nodeEventUpdate, events[0].Type) + assert.Equal(t, nodeEventInsert, events[0].Type) }) t.Run("Update publishes event", func(t *testing.T) { @@ -307,7 +307,7 @@ func TestNodeHttpSync_PublishesEventsOnCRUD(t *testing.T) { events := collectNodeEvents(registry.nodeEvents, 1, 100*time.Millisecond) require.Len(t, events, 1) - assert.Equal(t, nodeEventUpdate, events[0].Type) + assert.Equal(t, nodeEventDelete, events[0].Type) }) } diff --git a/packages/server/internal/api/rflowv2/rflowv2.go b/packages/server/internal/api/rflowv2/rflowv2.go index 6cd086888..7a750f257 100644 --- a/packages/server/internal/api/rflowv2/rflowv2.go +++ b/packages/server/internal/api/rflowv2/rflowv2.go @@ -15,7 +15,9 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/internal/api/rgraphql" "github.com/the-dev-tools/dev-tools/packages/server/internal/api/rhttp" "github.com/the-dev-tools/dev-tools/packages/server/internal/api/rlog" + "github.com/the-dev-tools/dev-tools/packages/server/internal/api/rwebsocket" "github.com/the-dev-tools/dev-tools/packages/server/pkg/eventstream" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/flowexec" "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/flowbuilder" gqlresolver "github.com/the-dev-tools/dev-tools/packages/server/pkg/graphql/resolver" "github.com/the-dev-tools/dev-tools/packages/server/pkg/http/resolver" @@ -28,6 +30,7 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sflow" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sgraphql" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/shttp" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/swebsocket" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sworkspace" flowv1 "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/api/flow/v1" "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/api/flow/v1/flowv1connect" @@ -190,6 +193,18 @@ type nodeGraphQLWithFlow struct { baseNode *mflow.Node } +type nodeWsConnectionWithFlow struct { + nodeWsConnection mflow.NodeWsConnection + flowID idwrap.IDWrap + baseNode *mflow.Node +} + +type nodeWsSendWithFlow struct { + nodeWsSend mflow.NodeWsSend + flowID idwrap.IDWrap + baseNode *mflow.Node +} + // Shared event type strings for all entity types. // Using mutation.Operation.String() values for consistency. const ( @@ -278,8 +293,13 @@ type FlowServiceV2Services struct { NodeAI *sflow.NodeAIService NodeAiProvider *sflow.NodeAiProviderService NodeMemory *sflow.NodeMemoryService - NodeGraphQL *sflow.NodeGraphQLService - NodeExecution *sflow.NodeExecutionService + NodeGraphQL *sflow.NodeGraphQLService + NodeWsConnection *sflow.NodeWsConnectionService + NodeWsSend *sflow.NodeWsSendService + NodeWait *sflow.NodeWaitService + WebSocket *swebsocket.WebSocketService + WebSocketHeader *swebsocket.WebSocketHeaderService + NodeExecution *sflow.NodeExecutionService FlowVariable *sflow.FlowVariableService Env *senv.EnvironmentService Var *senv.VariableService @@ -370,6 +390,7 @@ type FlowServiceV2Streamers struct { Memory eventstream.SyncStreamer[MemoryTopic, MemoryEvent] NodeGraphQL eventstream.SyncStreamer[NodeGraphQLTopic, NodeGraphQLEvent] GraphQL eventstream.SyncStreamer[rgraphql.GraphQLTopic, rgraphql.GraphQLEvent] + WebSocket eventstream.SyncStreamer[rwebsocket.WebSocketTopic, rwebsocket.WebSocketEvent] Execution eventstream.SyncStreamer[ExecutionTopic, ExecutionEvent] Http eventstream.SyncStreamer[rhttp.HttpTopic, rhttp.HttpEvent] HttpResponse eventstream.SyncStreamer[rhttp.HttpResponseTopic, rhttp.HttpResponseEvent] @@ -438,8 +459,13 @@ type FlowServiceV2RPC struct { naps *sflow.NodeAiProviderService nmems *sflow.NodeMemoryService ngqs *sflow.NodeGraphQLService - gqls *sgraphql.GraphQLService - gqlhs *sgraphql.GraphQLHeaderService + nwcs *sflow.NodeWsConnectionService + nwss *sflow.NodeWsSendService + nwaits *sflow.NodeWaitService + wsService *swebsocket.WebSocketService + wsHeaderService *swebsocket.WebSocketHeaderService + gqls *sgraphql.GraphQLService + gqlhs *sgraphql.GraphQLHeaderService nes *sflow.NodeExecutionService fvs *sflow.FlowVariableService envs *senv.EnvironmentService @@ -466,6 +492,7 @@ type FlowServiceV2RPC struct { memoryStream eventstream.SyncStreamer[MemoryTopic, MemoryEvent] nodeGraphQLStream eventstream.SyncStreamer[NodeGraphQLTopic, NodeGraphQLEvent] graphqlStream eventstream.SyncStreamer[rgraphql.GraphQLTopic, rgraphql.GraphQLEvent] + wsStream eventstream.SyncStreamer[rwebsocket.WebSocketTopic, rwebsocket.WebSocketEvent] executionStream eventstream.SyncStreamer[ExecutionTopic, ExecutionEvent] httpStream eventstream.SyncStreamer[rhttp.HttpTopic, rhttp.HttpEvent] httpResponseStream eventstream.SyncStreamer[rhttp.HttpResponseTopic, rhttp.HttpResponseEvent] @@ -478,11 +505,11 @@ type FlowServiceV2RPC struct { fileService *sfile.FileService fileStream eventstream.SyncStreamer[rfile.FileTopic, rfile.FileEvent] - // JS executor client for running JS nodes (connects to worker-js) - jsClient node_js_executorv1connect.NodeJsExecutorServiceClient + // Session factory for creating execution sessions (local or distributed) + sessionFactory flowexec.SessionFactory - // Shared builder for flow execution - builder *flowbuilder.Builder + // Snapshot registry for flow version snapshots + snapshotRegistry *flowexec.SnapshotRegistry // Running flows map for cancellation runningFlowsMu sync.Mutex @@ -501,11 +528,42 @@ func New(deps FlowServiceV2Deps) *FlowServiceV2RPC { deps.Services.Node, deps.Services.NodeRequest, deps.Services.NodeFor, deps.Services.NodeForEach, deps.Services.NodeIf, deps.Services.NodeJs, deps.Services.NodeAI, deps.Services.NodeAiProvider, deps.Services.NodeMemory, deps.Services.NodeGraphQL, + deps.Services.NodeWsConnection, deps.Services.NodeWsSend, deps.Services.NodeWait, + deps.Services.WebSocket, deps.Services.WebSocketHeader, deps.Services.GraphQL, deps.Services.GraphQLHeader, deps.Services.Workspace, deps.Services.Var, deps.Services.FlowVariable, deps.Resolver, deps.GraphQLResolver, deps.Logger, llmFactory, ) + // Build snapshot registry for flow version snapshots + registry := flowexec.NewSnapshotRegistry() + registry.Register(&flowexec.RequestSnapshot{Service: deps.Services.NodeRequest}) + registry.Register(&flowexec.ForSnapshot{Service: deps.Services.NodeFor}) + registry.Register(&flowexec.ForEachSnapshot{Service: deps.Services.NodeForEach}) + registry.Register(&flowexec.ConditionSnapshot{Service: deps.Services.NodeIf}) + registry.Register(&flowexec.JSSnapshot{Service: deps.Services.NodeJs}) + if deps.Services.NodeAI != nil { + registry.Register(&flowexec.AISnapshot{Service: deps.Services.NodeAI}) + } + if deps.Services.NodeAiProvider != nil { + registry.Register(&flowexec.AIProviderSnapshot{Service: deps.Services.NodeAiProvider}) + } + if deps.Services.NodeMemory != nil { + registry.Register(&flowexec.MemorySnapshot{Service: deps.Services.NodeMemory}) + } + if deps.Services.NodeGraphQL != nil { + registry.Register(&flowexec.GraphQLSnapshot{Service: deps.Services.NodeGraphQL}) + } + if deps.Services.NodeWsConnection != nil { + registry.Register(&flowexec.WsConnectionSnapshot{Service: deps.Services.NodeWsConnection}) + } + if deps.Services.NodeWsSend != nil { + registry.Register(&flowexec.WsSendSnapshot{Service: deps.Services.NodeWsSend}) + } + if deps.Services.NodeWait != nil { + registry.Register(&flowexec.WaitSnapshot{Service: deps.Services.NodeWait}) + } + return &FlowServiceV2RPC{ DB: deps.DB, wsReader: deps.Readers.Workspace, @@ -527,6 +585,11 @@ func New(deps FlowServiceV2Deps) *FlowServiceV2RPC { naps: deps.Services.NodeAiProvider, nmems: deps.Services.NodeMemory, ngqs: deps.Services.NodeGraphQL, + nwcs: deps.Services.NodeWsConnection, + nwss: deps.Services.NodeWsSend, + nwaits: deps.Services.NodeWait, + wsService: deps.Services.WebSocket, + wsHeaderService: deps.Services.WebSocketHeader, gqls: deps.Services.GraphQL, gqlhs: deps.Services.GraphQLHeader, nes: deps.Services.NodeExecution, @@ -554,6 +617,7 @@ func New(deps FlowServiceV2Deps) *FlowServiceV2RPC { memoryStream: deps.Streamers.Memory, nodeGraphQLStream: deps.Streamers.NodeGraphQL, graphqlStream: deps.Streamers.GraphQL, + wsStream: deps.Streamers.WebSocket, executionStream: deps.Streamers.Execution, httpStream: deps.Streamers.Http, httpResponseStream: deps.Streamers.HttpResponse, @@ -565,8 +629,11 @@ func New(deps FlowServiceV2Deps) *FlowServiceV2RPC { logStream: deps.Streamers.Log, fileService: deps.Services.File, fileStream: deps.Streamers.File, - jsClient: deps.JsClient, - builder: builder, + sessionFactory: &flowexec.LocalSessionFactory{ + Builder: builder, + JsClient: deps.JsClient, + }, + snapshotRegistry: registry, runningFlows: make(map[string]context.CancelFunc), } } @@ -640,6 +707,12 @@ func (p *rflowPublisher) PublishAll(events []mutation.Event) { p.publishNodeMemory(evt) case mutation.EntityFlowNodeGraphQL: p.publishNodeGraphQL(evt) + case mutation.EntityFlowNodeWsConnection: + p.publishNodeWsConnection(evt) + case mutation.EntityFlowNodeWsSend: + p.publishNodeWsSend(evt) + case mutation.EntityFlowNodeWait: + p.publishNodeWait(evt) case mutation.EntityFlowEdge: p.publishEdge(evt) case mutation.EntityFlowVariable: @@ -819,15 +892,24 @@ func (p *rflowPublisher) publishNodeHttp(evt mutation.Event) { var node *flowv1.Node var flowID idwrap.IDWrap + var eventType string - // 1. Publish update to base node stream + // 1. Publish to base node stream switch evt.Op { - case mutation.OpInsert, mutation.OpUpdate: + case mutation.OpInsert: + eventType = nodeEventInsert + if data, ok := evt.Payload.(nodeHttpWithFlow); ok && data.baseNode != nil { + node = serializeNode(*data.baseNode) + flowID = data.flowID + } + case mutation.OpUpdate: + eventType = nodeEventUpdate if data, ok := evt.Payload.(nodeHttpWithFlow); ok && data.baseNode != nil { node = serializeNode(*data.baseNode) flowID = data.flowID } case mutation.OpDelete: + eventType = nodeEventDelete node = &flowv1.Node{ NodeId: evt.ID.Bytes(), FlowId: evt.ParentID.Bytes(), @@ -837,7 +919,7 @@ func (p *rflowPublisher) publishNodeHttp(evt mutation.Event) { if node != nil { p.nodeStream.Publish(NodeTopic{FlowID: flowID}, NodeEvent{ - Type: nodeEventUpdate, + Type: eventType, FlowID: flowID, Node: node, }) @@ -1080,14 +1162,63 @@ func (p *rflowPublisher) publishNodeGraphQL(evt mutation.Event) { var node *flowv1.Node var flowID idwrap.IDWrap + var eventType string switch evt.Op { - case mutation.OpInsert, mutation.OpUpdate: + case mutation.OpInsert: + eventType = nodeEventInsert if data, ok := evt.Payload.(nodeGraphQLWithFlow); ok && data.baseNode != nil { node = serializeNode(*data.baseNode) flowID = data.flowID } + case mutation.OpUpdate: + eventType = nodeEventUpdate + if data, ok := evt.Payload.(nodeGraphQLWithFlow); ok && data.baseNode != nil { + node = serializeNode(*data.baseNode) + flowID = data.flowID + } + case mutation.OpDelete: + eventType = nodeEventDelete + node = &flowv1.Node{ + NodeId: evt.ID.Bytes(), + FlowId: evt.ParentID.Bytes(), + } + flowID = evt.ParentID + } + + if node != nil { + p.nodeStream.Publish(NodeTopic{FlowID: flowID}, NodeEvent{ + Type: eventType, + FlowID: flowID, + Node: node, + }) + } +} + +func (p *rflowPublisher) publishNodeWsConnection(evt mutation.Event) { + if p.nodeStream == nil { + return + } + + var node *flowv1.Node + var flowID idwrap.IDWrap + var eventType string + + switch evt.Op { + case mutation.OpInsert: + eventType = nodeEventInsert + if data, ok := evt.Payload.(nodeWsConnectionWithFlow); ok && data.baseNode != nil { + node = serializeNode(*data.baseNode) + flowID = data.flowID + } + case mutation.OpUpdate: + eventType = nodeEventUpdate + if data, ok := evt.Payload.(nodeWsConnectionWithFlow); ok && data.baseNode != nil { + node = serializeNode(*data.baseNode) + flowID = data.flowID + } case mutation.OpDelete: + eventType = nodeEventDelete node = &flowv1.Node{ NodeId: evt.ID.Bytes(), FlowId: evt.ParentID.Bytes(), @@ -1097,7 +1228,87 @@ func (p *rflowPublisher) publishNodeGraphQL(evt mutation.Event) { if node != nil { p.nodeStream.Publish(NodeTopic{FlowID: flowID}, NodeEvent{ - Type: nodeEventUpdate, + Type: eventType, + FlowID: flowID, + Node: node, + }) + } +} + +func (p *rflowPublisher) publishNodeWsSend(evt mutation.Event) { + if p.nodeStream == nil { + return + } + + var node *flowv1.Node + var flowID idwrap.IDWrap + var eventType string + + switch evt.Op { + case mutation.OpInsert: + eventType = nodeEventInsert + if data, ok := evt.Payload.(nodeWsSendWithFlow); ok && data.baseNode != nil { + node = serializeNode(*data.baseNode) + flowID = data.flowID + } + case mutation.OpUpdate: + eventType = nodeEventUpdate + if data, ok := evt.Payload.(nodeWsSendWithFlow); ok && data.baseNode != nil { + node = serializeNode(*data.baseNode) + flowID = data.flowID + } + case mutation.OpDelete: + eventType = nodeEventDelete + node = &flowv1.Node{ + NodeId: evt.ID.Bytes(), + FlowId: evt.ParentID.Bytes(), + } + flowID = evt.ParentID + } + + if node != nil { + p.nodeStream.Publish(NodeTopic{FlowID: flowID}, NodeEvent{ + Type: eventType, + FlowID: flowID, + Node: node, + }) + } +} + +func (p *rflowPublisher) publishNodeWait(evt mutation.Event) { + if p.nodeStream == nil { + return + } + + var node *flowv1.Node + var flowID idwrap.IDWrap + var eventType string + + switch evt.Op { + case mutation.OpInsert: + eventType = nodeEventInsert + if data, ok := evt.Payload.(nodeWaitWithFlow); ok && data.baseNode != nil { + node = serializeNode(*data.baseNode) + flowID = data.flowID + } + case mutation.OpUpdate: + eventType = nodeEventUpdate + if data, ok := evt.Payload.(nodeWaitWithFlow); ok && data.baseNode != nil { + node = serializeNode(*data.baseNode) + flowID = data.flowID + } + case mutation.OpDelete: + eventType = nodeEventDelete + node = &flowv1.Node{ + NodeId: evt.ID.Bytes(), + FlowId: evt.ParentID.Bytes(), + } + flowID = evt.ParentID + } + + if node != nil { + p.nodeStream.Publish(NodeTopic{FlowID: flowID}, NodeEvent{ + Type: eventType, FlowID: flowID, Node: node, }) diff --git a/packages/server/internal/api/rflowv2/rflowv2_copy_paste.go b/packages/server/internal/api/rflowv2/rflowv2_copy_paste.go index e822e1372..504246be7 100644 --- a/packages/server/internal/api/rflowv2/rflowv2_copy_paste.go +++ b/packages/server/internal/api/rflowv2/rflowv2_copy_paste.go @@ -13,6 +13,7 @@ import ( devtoolsdb "github.com/the-dev-tools/dev-tools/packages/db" "github.com/the-dev-tools/dev-tools/packages/server/internal/api/rgraphql" "github.com/the-dev-tools/dev-tools/packages/server/internal/api/rhttp" + "github.com/the-dev-tools/dev-tools/packages/server/internal/api/rwebsocket" "github.com/the-dev-tools/dev-tools/packages/server/internal/converter" "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" "github.com/the-dev-tools/dev-tools/packages/server/pkg/ioworkspace" @@ -20,11 +21,13 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mgraphql" "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mhttp" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mwebsocket" "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mworkspace" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sflow" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/shttp" "github.com/the-dev-tools/dev-tools/packages/server/pkg/translate/yamlflowsimplev2" flowv1 "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/api/flow/v1" + wsapiv1 "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/api/web_socket/v1" ) // FlowNodesCopy serializes selected nodes to YAML for clipboard copy. @@ -98,6 +101,8 @@ func (s *FlowServiceV2RPC) FlowNodesCopy( // Fetch type-specific data switch n.NodeKind { + case mflow.NODE_KIND_MANUAL_START: + // No type-specific data for ManualStart case mflow.NODE_KIND_REQUEST: if d, err := s.nrs.GetNodeRequest(ctx, n.ID); err == nil && d != nil { bundle.FlowRequestNodes = append(bundle.FlowRequestNodes, *d) @@ -168,6 +173,27 @@ func (s *FlowServiceV2RPC) FlowNodesCopy( } } } + case mflow.NODE_KIND_WS_CONNECTION: + if s.nwcs != nil { + if d, err := s.nwcs.GetNodeWsConnection(ctx, n.ID); err == nil { + bundle.FlowWsConnectionNodes = append(bundle.FlowWsConnectionNodes, *d) + if d.WebSocketID != nil { + s.populateWebSocketBundle(ctx, *d.WebSocketID, bundle) + } + } + } + case mflow.NODE_KIND_WS_SEND: + if s.nwss != nil { + if d, err := s.nwss.GetNodeWsSend(ctx, n.ID); err == nil { + bundle.FlowWsSendNodes = append(bundle.FlowWsSendNodes, *d) + } + } + case mflow.NODE_KIND_WAIT: + if s.nwaits != nil { + if d, err := s.nwaits.GetNodeWait(ctx, n.ID); err == nil && d != nil { + bundle.FlowWaitNodes = append(bundle.FlowWaitNodes, *d) + } + } } } @@ -223,6 +249,20 @@ func (s *FlowServiceV2RPC) populateGraphQLBundle(ctx context.Context, graphqlID } } +// populateWebSocketBundle fetches the WebSocket entity and its headers and adds them to the bundle. +func (s *FlowServiceV2RPC) populateWebSocketBundle(ctx context.Context, wsID idwrap.IDWrap, bundle *ioworkspace.WorkspaceBundle) { + if s.wsService != nil { + if ws, err := s.wsService.Get(ctx, wsID); err == nil { + bundle.WebSockets = append(bundle.WebSockets, *ws) + } + } + if s.wsHeaderService != nil { + if headers, err := s.wsHeaderService.GetByWebSocketID(ctx, wsID); err == nil { + bundle.WebSocketHeaders = append(bundle.WebSocketHeaders, headers...) + } + } +} + // FlowNodesPaste parses YAML from clipboard and creates nodes in the target flow. func (s *FlowServiceV2RPC) FlowNodesPaste( ctx context.Context, @@ -390,6 +430,21 @@ func (s *FlowServiceV2RPC) FlowNodesPaste( parsed.FlowGraphQLNodes[i].FlowNodeID = newID } } + for i := range parsed.FlowWsConnectionNodes { + if newID, ok := nodeIDMapping[parsed.FlowWsConnectionNodes[i].FlowNodeID]; ok { + parsed.FlowWsConnectionNodes[i].FlowNodeID = newID + } + } + for i := range parsed.FlowWsSendNodes { + if newID, ok := nodeIDMapping[parsed.FlowWsSendNodes[i].FlowNodeID]; ok { + parsed.FlowWsSendNodes[i].FlowNodeID = newID + } + } + for i := range parsed.FlowWaitNodes { + if newID, ok := nodeIDMapping[parsed.FlowWaitNodes[i].FlowNodeID]; ok { + parsed.FlowWaitNodes[i].FlowNodeID = newID + } + } // Remap variable references in expression fields when node names changed if len(nameMapping) > 0 { @@ -440,6 +495,18 @@ func (s *FlowServiceV2RPC) FlowNodesPaste( for i := range parsed.GraphQLHeaders { parsed.GraphQLHeaders[i].Value = remapVarRefs(parsed.GraphQLHeaders[i].Value, nameMapping) } + for i := range parsed.FlowWsSendNodes { + parsed.FlowWsSendNodes[i].Message = remapVarRefs(parsed.FlowWsSendNodes[i].Message, nameMapping) + if newName, ok := nameMapping[parsed.FlowWsSendNodes[i].WsConnectionNodeName]; ok { + parsed.FlowWsSendNodes[i].WsConnectionNodeName = newName + } + } + for i := range parsed.WebSockets { + parsed.WebSockets[i].Url = remapVarRefs(parsed.WebSockets[i].Url, nameMapping) + } + for i := range parsed.WebSocketHeaders { + parsed.WebSocketHeaders[i].Value = remapVarRefs(parsed.WebSocketHeaders[i].Value, nameMapping) + } } // Remap edges @@ -617,6 +684,34 @@ func (s *FlowServiceV2RPC) FlowNodesPaste( } } + // Handle WebSocket entities — create copies + wsIDMapping := make(map[idwrap.IDWrap]idwrap.IDWrap) + for i := range parsed.WebSockets { + ws := &parsed.WebSockets[i] + oldID := ws.ID + newID := idwrap.NewNow() + wsIDMapping[oldID] = newID + ws.ID = newID + ws.WorkspaceID = targetFlow.WorkspaceID + } + for i := range parsed.FlowWsConnectionNodes { + wcn := &parsed.FlowWsConnectionNodes[i] + if wcn.WebSocketID != nil { + if newID, ok := wsIDMapping[*wcn.WebSocketID]; ok { + wcn.WebSocketID = &newID + } + } + } + var wsHeadersToCreate []mwebsocket.WebSocketHeader + for i := range parsed.WebSocketHeaders { + h := &parsed.WebSocketHeaders[i] + if newID, ok := wsIDMapping[h.WebSocketID]; ok { + h.WebSocketID = newID + h.ID = idwrap.NewNow() + wsHeadersToCreate = append(wsHeadersToCreate, *h) + } + } + // Begin transaction for creating all entities tx, err := s.DB.BeginTx(ctx, nil) if err != nil { @@ -767,6 +862,46 @@ func (s *FlowServiceV2RPC) FlowNodesPaste( } } } + if s.wsService != nil { + for i := range parsed.WebSockets { + wsTx := s.wsService.TX(tx) + if err := wsTx.Create(ctx, &parsed.WebSockets[i]); err != nil { + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to create websocket: %w", err)) + } + } + } + if s.wsHeaderService != nil { + for _, h := range wsHeadersToCreate { + wshTx := s.wsHeaderService.TX(tx) + if err := wshTx.Create(ctx, h); err != nil { + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to create ws header: %w", err)) + } + } + } + if s.nwcs != nil { + for _, wsn := range parsed.FlowWsConnectionNodes { + nwcsWriter := sflow.NewNodeWsConnectionWriter(tx) + if err := nwcsWriter.CreateNodeWsConnection(ctx, wsn); err != nil { + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to create ws connection node: %w", err)) + } + } + } + if s.nwss != nil { + for _, wsn := range parsed.FlowWsSendNodes { + nwssWriter := sflow.NewNodeWsSendWriter(tx) + if err := nwssWriter.CreateNodeWsSend(ctx, wsn); err != nil { + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to create ws send node: %w", err)) + } + } + } + if s.nwaits != nil { + for _, wn := range parsed.FlowWaitNodes { + nwaitsWriter := sflow.NewNodeWaitWriter(tx) + if err := nwaitsWriter.CreateNodeWait(ctx, wn); err != nil { + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to create wait node: %w", err)) + } + } + } // Create edges for _, e := range validEdges { @@ -815,6 +950,19 @@ func (s *FlowServiceV2RPC) FlowNodesPaste( } } + // Publish WebSocket events for newly created entities + for i := range parsed.WebSockets { + ws := parsed.WebSockets[i] + s.wsStream.Publish(rwebsocket.WebSocketTopic{WorkspaceID: targetFlow.WorkspaceID}, rwebsocket.WebSocketEvent{ + Type: eventTypeInsert, + WebSocket: &wsapiv1.WebSocket{ + WebsocketId: ws.ID.Bytes(), + Name: ws.Name, + Url: ws.Url, + }, + }) + } + return connect.NewResponse(&flowv1.FlowNodesPasteResponse{ NodeIds: createdNodeIDs, }), nil diff --git a/packages/server/internal/api/rflowv2/rflowv2_exec.go b/packages/server/internal/api/rflowv2/rflowv2_exec.go index 0d9cd119c..0fe2fc68e 100644 --- a/packages/server/internal/api/rflowv2/rflowv2_exec.go +++ b/packages/server/internal/api/rflowv2/rflowv2_exec.go @@ -7,27 +7,17 @@ import ( "encoding/json" "errors" "fmt" - "math" - "sync" - "time" "connectrpc.com/connect" emptypb "google.golang.org/protobuf/types/known/emptypb" devtoolsdb "github.com/the-dev-tools/dev-tools/packages/db" - "github.com/the-dev-tools/dev-tools/packages/server/internal/api/rlog" - "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node/ngraphql" - "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node/nrequest" - "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/runner" - "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/runner/flowlocalrunner" - "github.com/the-dev-tools/dev-tools/packages/server/pkg/httpclient" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/flowexec" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/flowresult" "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" - "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mcondition" "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" - "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mgraphql" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sflow" flowv1 "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/api/flow/v1" - logv1 "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/api/log/v1" ) func (s *FlowServiceV2RPC) FlowRun(ctx context.Context, req *connect.Request[flowv1.FlowRunRequest]) (*connect.Response[emptypb.Empty], error) { @@ -134,7 +124,7 @@ func (s *FlowServiceV2RPC) FlowRun(ctx context.Context, req *connect.Request[flo cancel() }() - duration, execErr := s.executeFlow(bgCtx, flow, nodes, edges, flowVars, version.ID, nodeIDMapping) + duration, execErr := s.executeFlow(bgCtx, flow, nodes, edges, flowVars, nodeIDMapping) // Copy final node/edge states from parent to version (best-effort). // Use Background() because bgCtx may be cancelled on FlowStop. @@ -171,161 +161,55 @@ func (s *FlowServiceV2RPC) executeFlow( nodes []mflow.Node, edges []mflow.Edge, flowVars []mflow.FlowVariable, - versionFlowID idwrap.IDWrap, nodeIDMapping map[string]idwrap.IDWrap, ) (int32, error) { - // Build base variables by merging: GlobalEnv -> ActiveEnv -> FlowVars - // Later values override earlier ones - baseVars, err := s.builder.BuildVariables(ctx, flow.WorkspaceID, flowVars) - if err != nil { - return 0, fmt.Errorf("failed to build execution variables: %w", err) + // Filter orphaned edges (source or target node missing) + validEdges := filterValidEdges(nodes, edges) + + // Create result processor + proc := flowresult.NewServerResultProcessor(flowresult.ServerResultProcessorOpts{ + FlowID: flow.ID, + WorkspaceID: flow.WorkspaceID, + Nodes: nodes, + Edges: validEdges, + NodeIDMapping: nodeIDMapping, + HTTPResponseService: s.httpResponseService, + GraphQLResponseService: s.graphqlResponseService, + NodeExecutionService: s.nes, + NodeService: s.ns, + EdgeService: s.es, + Publisher: s.newExecEventPublisher(), + Logger: s.logger, + }) + + // Create and prepare execution session + session := s.sessionFactory.Create(proc) + + if err := session.Prepare(ctx, flowexec.ExecutionParams{ + Flow: flow, + Nodes: nodes, + Edges: validEdges, + FlowVars: flowVars, + }); err != nil { + return 0, err } - requestRespChan := make(chan nrequest.NodeRequestSideResp, len(nodes)*2+1) - // Track when HTTP responses are published so node execution events can wait - // This ensures frontend receives HttpResponse before NodeExecution with ResponseID - responsePublished := make(map[string]chan struct{}) - var responsePublishedMu sync.Mutex - var respDrain sync.WaitGroup - respDrain.Add(1) - go func() { - defer respDrain.Done() - for resp := range requestRespChan { - responseID := resp.Resp.HTTPResponse.ID.String() - - // Register the channel before processing so nodeStateChan can find it - responsePublishedMu.Lock() - publishedChan := make(chan struct{}) - responsePublished[responseID] = publishedChan - responsePublishedMu.Unlock() - - // Save HTTP Response - if err := s.httpResponseService.Create(ctx, resp.Resp.HTTPResponse); err != nil { - s.logger.Error("failed to save http response", "error", err) - } else { - s.publishHttpResponseEvent("insert", resp.Resp.HTTPResponse, flow.WorkspaceID) - } - - // Save Headers - for _, h := range resp.Resp.ResponseHeaders { - if err := s.httpResponseService.CreateHeader(ctx, h); err != nil { - s.logger.Error("failed to save http response header", "error", err) - } else { - s.publishHttpResponseHeaderEvent("insert", h, flow.WorkspaceID) - } - } - - // Save Asserts - for _, a := range resp.Resp.ResponseAsserts { - if err := s.httpResponseService.CreateAssert(ctx, a); err != nil { - s.logger.Error("failed to save http response assert", "error", err) - } else { - s.publishHttpResponseAssertEvent("insert", a, flow.WorkspaceID) - } - } + // Reset node/edge states before execution (batch-publishes UI events) + s.resetNodeStates(ctx, flow.ID, nodes) + s.resetEdgeStates(ctx, flow.ID, edges) - // Signal that response is published - nodeStateChan can now publish execution - close(publishedChan) - - if resp.Done != nil { - close(resp.Done) - } - } - }() - defer func() { - close(requestRespChan) - respDrain.Wait() - }() - - gqlRespChan := make(chan ngraphql.NodeGraphQLSideResp, len(nodes)*2+1) - gqlResponsePublished := make(map[string]chan struct{}) - var gqlResponsePublishedMu sync.Mutex - var gqlRespDrain sync.WaitGroup - gqlRespDrain.Add(1) - go func() { - defer gqlRespDrain.Done() - for resp := range gqlRespChan { - responseID := resp.Response.ID.String() - - gqlResponsePublishedMu.Lock() - publishedChan := make(chan struct{}) - gqlResponsePublished[responseID] = publishedChan - gqlResponsePublishedMu.Unlock() - - // Save all entities first, THEN publish events in batch - // This ensures atomicity and ordering - the client can query for - // child entities (headers/assertions) immediately after receiving - // the response event, preventing race conditions in real-time updates - - // Save GraphQL Response - responseSuccess := false - if err := s.graphqlResponseService.Create(ctx, resp.Response); err != nil { - s.logger.Error("failed to save graphql response", "error", err) - } else { - responseSuccess = true - } - - // Save Response Headers - var successHeaders []mgraphql.GraphQLResponseHeader - for _, h := range resp.RespHeaders { - if err := s.graphqlResponseService.CreateHeader(ctx, h); err != nil { - s.logger.Error("failed to save graphql response header", "error", err) - } else { - successHeaders = append(successHeaders, h) - } - } - - // Save Asserts - var successAsserts []mgraphql.GraphQLResponseAssert - for _, a := range resp.RespAsserts { - if err := s.graphqlResponseService.CreateAssert(ctx, a); err != nil { - s.logger.Error("failed to save graphql response assert", "error", err) - } else { - successAsserts = append(successAsserts, a) - } - } - - // Publish all events atomically AFTER all saves complete - // This guarantees the client receives events in the correct order: - // 1. Response (parent) - // 2. Headers (children) - // 3. Assertions (children) - if responseSuccess { - // Publish response first - s.publishGraphQLResponseEvent("insert", resp.Response, flow.WorkspaceID) - - // Then headers - for _, h := range successHeaders { - s.publishGraphQLResponseHeaderEvent("insert", h, flow.WorkspaceID) - } - - // Then assertions - for _, a := range successAsserts { - s.publishGraphQLResponseAssertEvent("insert", a, flow.WorkspaceID) - } - } - - close(publishedChan) - - if resp.Done != nil { - close(resp.Done) - } - } - }() - defer func() { - close(gqlRespChan) - gqlRespDrain.Wait() - }() - - sharedHTTPClient := httpclient.New() + // Execute flow and wait for result processing + result, err := session.Run(ctx) + return result.Duration, err +} - // Filter out orphaned edges (source or target node missing) to prevent - // runner panics when edges reference deleted nodes. +// filterValidEdges removes edges whose source or target node is missing. +func filterValidEdges(nodes []mflow.Node, edges []mflow.Edge) []mflow.Edge { nodeIDSet := make(map[idwrap.IDWrap]struct{}, len(nodes)) for _, n := range nodes { nodeIDSet[n.ID] = struct{}{} } - validEdges := edges[:0:0] + validEdges := make([]mflow.Edge, 0, len(edges)) for _, e := range edges { if _, srcOK := nodeIDSet[e.SourceID]; !srcOK { continue @@ -335,34 +219,11 @@ func (s *FlowServiceV2RPC) executeFlow( } validEdges = append(validEdges, e) } + return validEdges +} - edgeMap := mflow.NewEdgesMap(validEdges) - // Build edgesBySource map for O(1) edge lookup by source node ID - edgesBySource := make(map[idwrap.IDWrap][]mflow.Edge, len(validEdges)) - for _, edge := range validEdges { - edgesBySource[edge.SourceID] = append(edgesBySource[edge.SourceID], edge) - } - - const defaultNodeTimeout = 60 // seconds - timeoutDuration := time.Duration(defaultNodeTimeout) * time.Second - - flowNodeMap, startNodeID, err := s.builder.BuildNodes( - ctx, - flow, - nodes, - timeoutDuration, - sharedHTTPClient, - requestRespChan, - gqlRespChan, - s.jsClient, - ) - if err != nil { - return 0, err - } - - flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewMonotonic(), flow.ID, startNodeID, flowNodeMap, edgeMap, 0, nil) - - // Reset all node states to UNSPECIFIED before flow execution +// resetNodeStates sets all node states to UNSPECIFIED and batch-publishes events. +func (s *FlowServiceV2RPC) resetNodeStates(ctx context.Context, flowID idwrap.IDWrap, nodes []mflow.Node) { nodeResetEvents := make([]NodeEvent, 0, len(nodes)) for _, node := range nodes { if err := s.ns.UpdateNodeState(ctx, node.ID, mflow.NODE_STATE_UNSPECIFIED); err != nil { @@ -372,17 +233,18 @@ func (s *FlowServiceV2RPC) executeFlow( resetNode.State = mflow.NODE_STATE_UNSPECIFIED nodeResetEvents = append(nodeResetEvents, NodeEvent{ Type: nodeEventUpdate, - FlowID: flow.ID, + FlowID: flowID, Node: serializeNode(resetNode), }) } } - // Bulk publish node reset events for real-time sync if len(nodeResetEvents) > 0 && s.nodeStream != nil { - s.nodeStream.Publish(NodeTopic{FlowID: flow.ID}, nodeResetEvents...) + s.nodeStream.Publish(NodeTopic{FlowID: flowID}, nodeResetEvents...) } +} - // Reset all edge states to UNSPECIFIED before flow execution +// resetEdgeStates sets all edge states to UNSPECIFIED and batch-publishes events. +func (s *FlowServiceV2RPC) resetEdgeStates(ctx context.Context, flowID idwrap.IDWrap, edges []mflow.Edge) { edgeResetEvents := make([]EdgeEvent, 0, len(edges)) for _, edge := range edges { if err := s.es.UpdateEdgeState(ctx, edge.ID, mflow.NODE_STATE_UNSPECIFIED); err != nil { @@ -392,349 +254,14 @@ func (s *FlowServiceV2RPC) executeFlow( resetEdge.State = mflow.NODE_STATE_UNSPECIFIED edgeResetEvents = append(edgeResetEvents, EdgeEvent{ Type: edgeEventUpdate, - FlowID: flow.ID, + FlowID: flowID, Edge: serializeEdge(resetEdge), }) } } - // Bulk publish edge reset events for real-time sync if len(edgeResetEvents) > 0 && s.edgeStream != nil { - s.edgeStream.Publish(EdgeTopic{FlowID: flow.ID}, edgeResetEvents...) + s.edgeStream.Publish(EdgeTopic{FlowID: flowID}, edgeResetEvents...) } - - // Build nodeKindMap for O(1) lookup of node kinds - // Used to skip NodeExecution creation for loop coordinator wrapper statuses - nodeKindMap := make(map[idwrap.IDWrap]mflow.NodeKind, len(nodes)) - for _, node := range nodes { - nodeKindMap[node.ID] = node.NodeKind - } - - nodeStateChan := make(chan runner.FlowNodeStatus, len(nodes)*2+1) - var stateDrain sync.WaitGroup - stateDrain.Add(1) - - // Create inverse mapping to map versioned IDs back to original IDs for live sync - inverseNodeIDMapping := make(map[string]idwrap.IDWrap, len(nodeIDMapping)) - for k, v := range nodeIDMapping { - inverseNodeIDMapping[v.String()] = idwrap.NewTextMust(k) - } - - go func() { - defer stateDrain.Done() - - // Cache execution IDs to ensure stability across multiple events for the same execution - // Key: NodeID + Iteration info - executionCache := make(map[string]idwrap.IDWrap) - - for status := range nodeStateChan { - // Find the original node ID if this is a versioned ID - originalNodeID := status.NodeID - if origID, ok := inverseNodeIDMapping[status.NodeID.String()]; ok { - originalNodeID = origID - } - - // Check if this is a loop coordinator (For/ForEach) wrapper status - // Skip NodeExecution creation for these, but still update node visual state - nodeKind := nodeKindMap[status.NodeID] - isLoopNode := nodeKind == mflow.NODE_KIND_FOR || nodeKind == mflow.NODE_KIND_FOR_EACH - skipExecution := isLoopNode && !status.IterationEvent - - // Persist execution state (skip for loop node wrapper statuses) - if !skipExecution { - execID := status.ExecutionID - isNewExecution := false - - if isZeroID(execID) { - // Construct cache key based on node and iteration context - cacheKey := status.NodeID.String() - if status.IterationContext != nil { - // Use iteration path and index for uniqueness in loops - cacheKey = fmt.Sprintf("%s:%v:%d", cacheKey, status.IterationContext.IterationPath, status.IterationContext.ExecutionIndex) - } else if status.IterationIndex >= 0 { - cacheKey = fmt.Sprintf("%s:%d", cacheKey, status.IterationIndex) - } - - if cachedID, ok := executionCache[cacheKey]; ok { - execID = cachedID - } else { - execID = idwrap.NewMonotonic() - executionCache[cacheKey] = execID - isNewExecution = true - } - } - - // Include timestamp in execution name for easy identification - executionName := fmt.Sprintf("%s - %s", status.Name, time.Now().Format("2006-01-02 15:04")) - - // Debug: Log AuxiliaryID value being set - if status.AuxiliaryID != nil { - s.logger.Debug("Creating execution with AuxiliaryID", - "exec_id", execID.String(), - "node_id", status.NodeID.String(), - "node_name", status.Name, - "state", status.State, - "auxiliary_id", status.AuxiliaryID.String(), - ) - } else { - s.logger.Debug("Creating execution without AuxiliaryID", - "exec_id", execID.String(), - "node_id", status.NodeID.String(), - "node_name", status.Name, - "state", status.State, - ) - } - - model := mflow.NodeExecution{ - ID: execID, - NodeID: status.NodeID, - Name: executionName, - State: status.State, - } - - // Set the appropriate response ID based on node kind - nodeKindForAux := nodeKindMap[status.NodeID] - if status.AuxiliaryID != nil { - if nodeKindForAux == mflow.NODE_KIND_GRAPHQL { - model.GraphQLResponseID = status.AuxiliaryID - } else { - model.ResponseID = status.AuxiliaryID - } - } - - if status.Error != nil { - errStr := status.Error.Error() - model.Error = &errStr - } - - if status.InputData != nil { - if b, err := json.Marshal(status.InputData); err == nil { - _ = model.SetInputJSON(b) - } - } - if status.OutputData != nil { - if b, err := json.Marshal(status.OutputData); err == nil { - _ = model.SetOutputJSON(b) - } - } - - // Set CompletedAt for terminal states - if status.State == mflow.NODE_STATE_SUCCESS || - status.State == mflow.NODE_STATE_FAILURE || - status.State == mflow.NODE_STATE_CANCELED { - now := time.Now().Unix() - model.CompletedAt = &now - } - - eventType := executionEventInsert - // Only use UPDATE if it's NOT a new execution AND the state is terminal. - // If it's a new execution (first time seeing this node run), we MUST send INSERT, - // even if the state is already SUCCESS/FAILURE (instant execution). - if !isNewExecution && (status.State == mflow.NODE_STATE_SUCCESS || - status.State == mflow.NODE_STATE_FAILURE || - status.State == mflow.NODE_STATE_CANCELED) { - eventType = executionEventUpdate - } - - if err := s.nes.UpsertNodeExecution(ctx, model); err != nil { - s.logger.Error("failed to persist node execution", "error", err) - } - - // If this execution has a ResponseID, wait for the response to be published first - // This ensures frontend receives HttpResponse/GraphQLResponse before NodeExecution - if status.AuxiliaryID != nil { - respIDStr := status.AuxiliaryID.String() - - // Check HTTP response published map - responsePublishedMu.Lock() - publishedChan, ok := responsePublished[respIDStr] - responsePublishedMu.Unlock() - if ok { - select { - case <-publishedChan: - case <-ctx.Done(): - } - responsePublishedMu.Lock() - delete(responsePublished, respIDStr) - responsePublishedMu.Unlock() - } - - // Check GraphQL response published map - gqlResponsePublishedMu.Lock() - gqlPublishedChan, gqlOK := gqlResponsePublished[respIDStr] - gqlResponsePublishedMu.Unlock() - if gqlOK { - select { - case <-gqlPublishedChan: - case <-ctx.Done(): - } - gqlResponsePublishedMu.Lock() - delete(gqlResponsePublished, respIDStr) - gqlResponsePublishedMu.Unlock() - } - } - - // Publish execution event - s.publishExecutionEvent(eventType, model, flow.ID) - } - - // Update node state in database (always use versioned ID for state persistence) - if err := s.ns.UpdateNodeState(ctx, status.NodeID, status.State); err != nil { - s.logger.Error("failed to update node state", "node_id", status.NodeID.String(), "error", err) - } - - // Update edge states based on node execution state - if status.State == mflow.NODE_STATE_SUCCESS || status.State == mflow.NODE_STATE_FAILURE { - // Find edges that start from this node using O(1) map lookup - edgesFromNode := edgesBySource[status.NodeID] - edgeState := mflow.NODE_STATE_SUCCESS - if status.State == mflow.NODE_STATE_FAILURE { - edgeState = mflow.NODE_STATE_FAILURE - } - for _, edge := range edgesFromNode { - if err := s.es.UpdateEdgeState(ctx, edge.ID, edgeState); err != nil { - s.logger.Error("failed to update edge state", "edge_id", edge.ID.String(), "error", err) - } else { - // Publish edge state update event for real-time sync - updatedEdge := edge - updatedEdge.State = edgeState - s.publishEdgeEvent(edgeEventUpdate, updatedEdge) - } - } - } - - // Note: Version node executions are no longer created here. - // Executions are moved from parent nodes to version nodes at the start of the next run. - - if s.nodeStream != nil { - var info string - if status.Error != nil { - info = status.Error.Error() - } else { - iterIndex := -1 - if status.IterationEvent { - iterIndex = status.IterationIndex - } else if status.IterationContext != nil { - iterIndex = status.IterationContext.ExecutionIndex - } - - if iterIndex >= 0 { - info = fmt.Sprintf("Iter: %d", iterIndex+1) - } - } - - // Map versioned node ID back to original node ID for live sync on current view - nodePB := &flowv1.Node{ - NodeId: originalNodeID.Bytes(), - FlowId: flow.ID.Bytes(), - State: flowv1.FlowItemState(status.State), - } - if info != "" { - nodePB.Info = &info - } - - s.nodeStream.Publish(NodeTopic{FlowID: flow.ID}, NodeEvent{ - Type: nodeEventUpdate, - FlowID: flow.ID, - Node: nodePB, - }) - } - - if s.logStream != nil && status.State != mflow.NODE_STATE_RUNNING { - idStr := status.NodeID.String() - stateStr := mflow.StringNodeState(status.State) - nodeName := status.Name - if nodeName == "" { - nodeName = idStr - } - msg := fmt.Sprintf("Node %s: %s", nodeName, stateStr) - - var logLevel logv1.LogLevel - switch status.State { - case mflow.NODE_STATE_FAILURE: - logLevel = logv1.LogLevel_LOG_LEVEL_ERROR - case mflow.NODE_STATE_CANCELED: - logLevel = logv1.LogLevel_LOG_LEVEL_WARNING - default: - logLevel = logv1.LogLevel_LOG_LEVEL_UNSPECIFIED - } - - // Create structured value with full node details - logData := map[string]any{ - "node_id": status.NodeID.String(), - "node_name": status.Name, - "state": stateStr, - "flow_id": flow.ID.String(), - "duration_ms": status.RunDuration.Milliseconds(), - } - - // Convert output/input to JSON-safe format via marshal/unmarshal - // This ensures types like []byte are properly converted - // Limit size to avoid very large log entries that could slow down the frontend - const maxLogDataSize = 64 * 1024 // 64KB limit - if status.OutputData != nil { - if jsonBytes, err := json.Marshal(status.OutputData); err == nil { - if len(jsonBytes) <= maxLogDataSize { - var jsonSafe any - if json.Unmarshal(jsonBytes, &jsonSafe) == nil { - logData["output"] = jsonSafe - } - } else { - logData["output"] = "(output too large to display)" - } - } - } - if status.InputData != nil { - if jsonBytes, err := json.Marshal(status.InputData); err == nil { - if len(jsonBytes) <= maxLogDataSize { - var jsonSafe any - if json.Unmarshal(jsonBytes, &jsonSafe) == nil { - logData["input"] = jsonSafe - } - } else { - logData["input"] = "(input too large to display)" - } - } - } - if status.Error != nil { - logData["error"] = status.Error.Error() - } - if status.IterationContext != nil { - logData["iteration_index"] = status.IterationContext.ExecutionIndex - logData["iteration_path"] = status.IterationContext.IterationPath - } - - val, err := rlog.NewLogValue(logData) - if err != nil { - s.logger.Error("failed to create log value", "error", err) - } - - s.logStream.Publish(rlog.LogTopic{}, rlog.LogEvent{ - Type: rlog.EventTypeInsert, - Log: &logv1.Log{ - LogId: idwrap.NewMonotonic().Bytes(), - Name: msg, - Level: logLevel, - Value: val, - }, - }) - } - } - }() - - startTime := time.Now() - runErr := flowRunner.RunWithEvents(ctx, runner.FlowEventChannels{ - NodeStates: nodeStateChan, - }, baseVars) - - duration := time.Since(startTime).Milliseconds() - if duration > math.MaxInt32 { - duration = math.MaxInt32 - } - //nolint:gosec // duration clamped to MaxInt32 - durationInt := int32(duration) - - stateDrain.Wait() - return durationInt, runErr } func (s *FlowServiceV2RPC) FlowStop(ctx context.Context, req *connect.Request[flowv1.FlowStopRequest]) (*connect.Response[emptypb.Empty], error) { @@ -794,100 +321,7 @@ func (s *FlowServiceV2RPC) createFlowVersionSnapshot( ) (mflow.Flow, map[string]idwrap.IDWrap, error) { // === PREPARATION PHASE (BEFORE TRANSACTION) === // Read all sub-node configurations before starting the transaction to minimize transaction duration. - // This follows SQLite best practices of keeping transactions short and doing reads outside when possible. - - type nodeConfig struct { - sourceNode mflow.Node - requestData *mflow.NodeRequest - forData *mflow.NodeFor - forEachData *mflow.NodeForEach - conditionData *mflow.NodeIf - jsData *mflow.NodeJS - aiData *mflow.NodeAI - aiProviderData *mflow.NodeAiProvider - memoryData *mflow.NodeMemory - graphqlData *mflow.NodeGraphQL - } - - nodeConfigs := make([]nodeConfig, 0, len(sourceNodes)) - - for _, sourceNode := range sourceNodes { - config := nodeConfig{sourceNode: sourceNode} - - switch sourceNode.NodeKind { - case mflow.NODE_KIND_REQUEST: - requestData, err := s.nrs.GetNodeRequest(ctx, sourceNode.ID) - if err == nil && requestData != nil { - config.requestData = requestData - } - - case mflow.NODE_KIND_FOR: - forData, err := s.nfs.GetNodeFor(ctx, sourceNode.ID) - if err != nil { - s.logger.Warn("failed to get for node config, using defaults", "node_id", sourceNode.ID.String(), "error", err) - } else if forData != nil { - config.forData = forData - } - - case mflow.NODE_KIND_FOR_EACH: - forEachData, err := s.nfes.GetNodeForEach(ctx, sourceNode.ID) - if err != nil { - s.logger.Warn("failed to get foreach node config, using defaults", "node_id", sourceNode.ID.String(), "error", err) - } else if forEachData != nil { - config.forEachData = forEachData - } - - case mflow.NODE_KIND_CONDITION: - conditionData, err := s.nifs.GetNodeIf(ctx, sourceNode.ID) - if err != nil { - s.logger.Warn("failed to get condition node config, using defaults", "node_id", sourceNode.ID.String(), "error", err) - } else if conditionData != nil { - config.conditionData = conditionData - } - - case mflow.NODE_KIND_JS: - jsData, err := s.njss.GetNodeJS(ctx, sourceNode.ID) - if err != nil { - s.logger.Warn("failed to get js node config, using defaults", "node_id", sourceNode.ID.String(), "error", err) - } else if jsData != nil { - config.jsData = jsData - } - - case mflow.NODE_KIND_AI: - aiData, err := s.nais.GetNodeAI(ctx, sourceNode.ID) - if err != nil { - s.logger.Warn("failed to get ai node config, using defaults", "node_id", sourceNode.ID.String(), "error", err) - } else if aiData != nil { - config.aiData = aiData - } - - case mflow.NODE_KIND_AI_PROVIDER: - aiProviderData, err := s.naps.GetNodeAiProvider(ctx, sourceNode.ID) - if err != nil { - s.logger.Warn("failed to get ai provider node config, using defaults", "node_id", sourceNode.ID.String(), "error", err) - } else if aiProviderData != nil { - config.aiProviderData = aiProviderData - } - - case mflow.NODE_KIND_AI_MEMORY: - memoryData, err := s.nmems.GetNodeMemory(ctx, sourceNode.ID) - if err != nil { - s.logger.Warn("failed to get memory node config, using defaults", "node_id", sourceNode.ID.String(), "error", err) - } else if memoryData != nil { - config.memoryData = memoryData - } - - case mflow.NODE_KIND_GRAPHQL: - graphqlData, err := s.ngqs.GetNodeGraphQL(ctx, sourceNode.ID) - if err != nil { - s.logger.Warn("failed to get graphql node config, using defaults", "node_id", sourceNode.ID.String(), "error", err) - } else if graphqlData != nil { - config.graphqlData = graphqlData - } - } - - nodeConfigs = append(nodeConfigs, config) - } + nodeConfigs := s.snapshotRegistry.ReadAll(ctx, sourceNodes, s.logger) // === BEGIN TRANSACTION === tx, err := s.DB.BeginTx(ctx, nil) @@ -896,34 +330,8 @@ func (s *FlowServiceV2RPC) createFlowVersionSnapshot( } defer devtoolsdb.TxnRollback(tx) - // Get TX-bound service writers flowWriter := s.fs.TX(tx) nodeWriter := s.ns.TX(tx) - nrsWriter := s.nrs.TX(tx) - nfsWriter := s.nfs.TX(tx) - nfesWriter := s.nfes.TX(tx) - nifsWriter := s.nifs.TX(tx) - njssWriter := s.njss.TX(tx) - var naisWriter *sflow.NodeAIService - if s.nais != nil { - txService := s.nais.TX(tx) - naisWriter = &txService - } - var napsWriter *sflow.NodeAiProviderService - if s.naps != nil { - txService := s.naps.TX(tx) - napsWriter = &txService - } - var nmemsWriter *sflow.NodeMemoryService - if s.nmems != nil { - txService := s.nmems.TX(tx) - nmemsWriter = &txService - } - var ngqsWriter *sflow.NodeGraphQLService - if s.ngqs != nil { - txService := s.ngqs.TX(tx) - ngqsWriter = &txService - } edgeWriter := s.es.TX(tx) varWriter := s.fvs.TX(tx) @@ -940,18 +348,12 @@ func (s *FlowServiceV2RPC) createFlowVersionSnapshot( // Events collections for bulk publishing (after commit) nodeEvents := make([]NodeEvent, 0, len(sourceNodes)) - jsEvents := make([]JsEvent, 0) - forEvents := make([]ForEvent, 0) - // Duplicate all nodes and their sub-node data - for _, config := range nodeConfigs { - sourceNode := config.sourceNode + // Duplicate all nodes + for _, sourceNode := range sourceNodes { newNodeID := idwrap.NewMonotonic() nodeIDMapping[sourceNode.ID.String()] = newNodeID - // Create the base node with UNSPECIFIED state. The parent node's state is from - // the previous run and would be misleading — this version's execution hasn't - // happened yet, so its nodes should start clean. newNode := mflow.Node{ ID: newNodeID, FlowID: versionFlowID, @@ -962,195 +364,47 @@ func (s *FlowServiceV2RPC) createFlowVersionSnapshot( State: mflow.NODE_STATE_UNSPECIFIED, } - // Use CreateNodeWithState to set the initial state in the snapshot if err := nodeWriter.CreateNodeWithState(ctx, newNode); err != nil { return mflow.Flow{}, nil, fmt.Errorf("create node %s: %w", sourceNode.Name, err) } - // Duplicate node-type specific data - switch sourceNode.NodeKind { - case mflow.NODE_KIND_REQUEST: - if config.requestData != nil { - // Copy the request node config (referencing same HTTP, not duplicating) - newRequestData := mflow.NodeRequest{ - FlowNodeID: newNodeID, - HttpID: config.requestData.HttpID, - DeltaHttpID: config.requestData.DeltaHttpID, - HasRequestConfig: config.requestData.HasRequestConfig, - } - if err := nrsWriter.CreateNodeRequest(ctx, newRequestData); err != nil { - return mflow.Flow{}, nil, fmt.Errorf("create request node: %w", err) - } - // Request node events are handled through nodeStream subscription - } - - case mflow.NODE_KIND_FOR: - // Always create For node config with defaults - newForData := mflow.NodeFor{ - FlowNodeID: newNodeID, - IterCount: 1, // default - Condition: mcondition.Condition{}, // default empty - ErrorHandling: mflow.ErrorHandling_ERROR_HANDLING_BREAK, // default - } - if config.forData != nil { - // Override with actual values, but keep default of 1 if IterCount is 0 - if config.forData.IterCount > 0 { - newForData.IterCount = config.forData.IterCount - } - newForData.Condition = config.forData.Condition - newForData.ErrorHandling = config.forData.ErrorHandling - } - if err := nfsWriter.CreateNodeFor(ctx, newForData); err != nil { - return mflow.Flow{}, nil, fmt.Errorf("create for node: %w", err) - } - forEvents = append(forEvents, ForEvent{ - Type: forEventInsert, - FlowID: versionFlowID, - Node: serializeNodeFor(newForData), - }) + nodeEvents = append(nodeEvents, NodeEvent{ + Type: nodeEventInsert, + FlowID: versionFlowID, + Node: serializeNode(newNode), + }) + } - case mflow.NODE_KIND_FOR_EACH: - // Always create ForEach node config with defaults - newForEachData := mflow.NodeForEach{ - FlowNodeID: newNodeID, - IterExpression: "", // default empty - Condition: mcondition.Condition{}, // default empty - ErrorHandling: mflow.ErrorHandling_ERROR_HANDLING_BREAK, // default - } - if config.forEachData != nil { - // Override with actual values - newForEachData.IterExpression = config.forEachData.IterExpression - newForEachData.Condition = config.forEachData.Condition - newForEachData.ErrorHandling = config.forEachData.ErrorHandling - } - if err := nfesWriter.CreateNodeForEach(ctx, newForEachData); err != nil { - return mflow.Flow{}, nil, fmt.Errorf("create foreach node: %w", err) - } - // ForEach node events are handled through nodeStream subscription + // Write type-specific node configs via snapshot registry + configResults, err := s.snapshotRegistry.WriteAllTx(ctx, tx, sourceNodes, nodeIDMapping, nodeConfigs) + if err != nil { + return mflow.Flow{}, nil, err + } - case mflow.NODE_KIND_CONDITION: - // Always create Condition node config with defaults - newConditionData := mflow.NodeIf{ - FlowNodeID: newNodeID, - Condition: mcondition.Condition{}, // default empty - } - if config.conditionData != nil { - // Override with actual values - newConditionData.Condition = config.conditionData.Condition - } - if err := nifsWriter.CreateNodeIf(ctx, newConditionData); err != nil { - return mflow.Flow{}, nil, fmt.Errorf("create condition node: %w", err) + // Collect type-specific events for publishing + var jsEvents []JsEvent + var forEvents []ForEvent + for _, result := range configResults { + switch result.NodeKind { + case mflow.NODE_KIND_FOR: + if data, ok := result.Config.(mflow.NodeFor); ok { + forEvents = append(forEvents, ForEvent{ + Type: forEventInsert, + FlowID: versionFlowID, + Node: serializeNodeFor(data), + }) } - // Condition node events are handled through nodeStream subscription - case mflow.NODE_KIND_JS: - // Always create JS node config with defaults - newJsData := mflow.NodeJS{ - FlowNodeID: newNodeID, - Code: nil, // default empty - CodeCompressType: 0, // default none - } - if config.jsData != nil { - // Override with actual values - newJsData.Code = config.jsData.Code - newJsData.CodeCompressType = config.jsData.CodeCompressType - } - if err := njssWriter.CreateNodeJS(ctx, newJsData); err != nil { - return mflow.Flow{}, nil, fmt.Errorf("create js node: %w", err) - } - jsEvents = append(jsEvents, JsEvent{ - Type: jsEventInsert, - FlowID: versionFlowID, - Node: serializeNodeJs(newJsData), - }) - - case mflow.NODE_KIND_AI: - // Skip if AI service is not available - if naisWriter == nil { - s.logger.Warn("NodeAI service not available, skipping AI node config", "node_id", sourceNode.ID.String()) - } else { - // Create AI node config (model/credential now via connected Model node) - newAIData := mflow.NodeAI{ - FlowNodeID: newNodeID, - Prompt: "", - MaxIterations: 5, - } - if config.aiData != nil { - newAIData.Prompt = config.aiData.Prompt - newAIData.MaxIterations = config.aiData.MaxIterations - } - if err := naisWriter.CreateNodeAI(ctx, newAIData); err != nil { - return mflow.Flow{}, nil, fmt.Errorf("create ai node: %w", err) - } - // AI node events are handled through nodeStream subscription - } - - case mflow.NODE_KIND_AI_PROVIDER: - // Skip if AI Provider service is not available - if napsWriter == nil { - s.logger.Warn("NodeAiProvider service not available, skipping AI Provider node config", "node_id", sourceNode.ID.String()) - } else { - // Create AI Provider node config with defaults - newAiProviderData := mflow.NodeAiProvider{ - FlowNodeID: newNodeID, - CredentialID: nil, - Model: mflow.AiModelUnspecified, - Temperature: nil, - MaxTokens: nil, - } - if config.aiProviderData != nil { - newAiProviderData.CredentialID = config.aiProviderData.CredentialID - newAiProviderData.Model = config.aiProviderData.Model - newAiProviderData.Temperature = config.aiProviderData.Temperature - newAiProviderData.MaxTokens = config.aiProviderData.MaxTokens - } - if err := napsWriter.CreateNodeAiProvider(ctx, newAiProviderData); err != nil { - return mflow.Flow{}, nil, fmt.Errorf("create ai provider node: %w", err) - } - // AI Provider node events are handled through nodeStream subscription - } - - case mflow.NODE_KIND_AI_MEMORY: - // Skip if Memory service is not available - if nmemsWriter == nil { - s.logger.Warn("NodeMemory service not available, skipping Memory node config", "node_id", sourceNode.ID.String()) - } else { - // Create Memory node config with defaults - newMemoryData := mflow.NodeMemory{ - FlowNodeID: newNodeID, - MemoryType: mflow.AiMemoryTypeWindowBuffer, - WindowSize: 10, // Default window size - } - if config.memoryData != nil { - newMemoryData.MemoryType = config.memoryData.MemoryType - newMemoryData.WindowSize = config.memoryData.WindowSize - } - if err := nmemsWriter.CreateNodeMemory(ctx, newMemoryData); err != nil { - return mflow.Flow{}, nil, fmt.Errorf("create memory node: %w", err) - } - // Memory node events are handled through nodeStream subscription - } - - case mflow.NODE_KIND_GRAPHQL: - if ngqsWriter == nil { - s.logger.Warn("NodeGraphQL service not available, skipping GraphQL node config", "node_id", sourceNode.ID.String()) - } else if config.graphqlData != nil { - newGraphQLData := mflow.NodeGraphQL{ - FlowNodeID: newNodeID, - GraphQLID: config.graphqlData.GraphQLID, - } - if err := ngqsWriter.CreateNodeGraphQL(ctx, newGraphQLData); err != nil { - return mflow.Flow{}, nil, fmt.Errorf("create graphql node: %w", err) - } + if data, ok := result.Config.(mflow.NodeJS); ok { + jsEvents = append(jsEvents, JsEvent{ + Type: jsEventInsert, + FlowID: versionFlowID, + Node: serializeNodeJs(data), + }) } + default: + // Other node kinds don't need type-specific events } - - // Collect base node event - nodeEvents = append(nodeEvents, NodeEvent{ - Type: nodeEventInsert, - FlowID: versionFlowID, - Node: serializeNode(newNode), - }) } // Duplicate all edges with remapped node IDs diff --git a/packages/server/internal/api/rflowv2/rflowv2_exec_publisher.go b/packages/server/internal/api/rflowv2/rflowv2_exec_publisher.go new file mode 100644 index 000000000..262a7f9ca --- /dev/null +++ b/packages/server/internal/api/rflowv2/rflowv2_exec_publisher.go @@ -0,0 +1,241 @@ +package rflowv2 + +import ( + "encoding/json" + "fmt" + + "github.com/the-dev-tools/dev-tools/packages/server/internal/api/rgraphql" + "github.com/the-dev-tools/dev-tools/packages/server/internal/api/rhttp" + "github.com/the-dev-tools/dev-tools/packages/server/internal/api/rlog" + "github.com/the-dev-tools/dev-tools/packages/server/internal/converter" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/eventstream" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/runner" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mgraphql" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mhttp" + flowv1 "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/api/flow/v1" + logv1 "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/api/log/v1" +) + +// execEventPublisher implements flowresult.EventPublisher by delegating +// to the event stream fields on FlowServiceV2RPC. +type execEventPublisher struct { + executionStream eventstream.SyncStreamer[ExecutionTopic, ExecutionEvent] + nodeStream eventstream.SyncStreamer[NodeTopic, NodeEvent] + edgeStream eventstream.SyncStreamer[EdgeTopic, EdgeEvent] + httpResponseStream eventstream.SyncStreamer[rhttp.HttpResponseTopic, rhttp.HttpResponseEvent] + httpResponseHeaderStream eventstream.SyncStreamer[rhttp.HttpResponseHeaderTopic, rhttp.HttpResponseHeaderEvent] + httpResponseAssertStream eventstream.SyncStreamer[rhttp.HttpResponseAssertTopic, rhttp.HttpResponseAssertEvent] + gqlResponseStream eventstream.SyncStreamer[rgraphql.GraphQLResponseTopic, rgraphql.GraphQLResponseEvent] + gqlResponseHeaderStream eventstream.SyncStreamer[rgraphql.GraphQLResponseHeaderTopic, rgraphql.GraphQLResponseHeaderEvent] + gqlResponseAssertStream eventstream.SyncStreamer[rgraphql.GraphQLResponseAssertTopic, rgraphql.GraphQLResponseAssertEvent] + logStream eventstream.SyncStreamer[rlog.LogTopic, rlog.LogEvent] + logger func(msg string, args ...any) +} + +func (s *FlowServiceV2RPC) newExecEventPublisher() *execEventPublisher { + return &execEventPublisher{ + executionStream: s.executionStream, + nodeStream: s.nodeStream, + edgeStream: s.edgeStream, + httpResponseStream: s.httpResponseStream, + httpResponseHeaderStream: s.httpResponseHeaderStream, + httpResponseAssertStream: s.httpResponseAssertStream, + gqlResponseStream: s.graphqlResponseStream, + gqlResponseHeaderStream: s.graphqlResponseHeaderStream, + gqlResponseAssertStream: s.graphqlResponseAssertStream, + logStream: s.logStream, + logger: func(msg string, args ...any) { + s.logger.Error(msg, args...) + }, + } +} + +func (p *execEventPublisher) PublishHTTPResponse(response mhttp.HTTPResponse, workspaceID idwrap.IDWrap) { + if p.httpResponseStream == nil { + return + } + responsePB := converter.ToAPIHttpResponse(response) + p.httpResponseStream.Publish(rhttp.HttpResponseTopic{WorkspaceID: workspaceID}, rhttp.HttpResponseEvent{ + Type: eventTypeInsert, + HttpResponse: responsePB, + }) +} + +func (p *execEventPublisher) PublishHTTPResponseHeader(header mhttp.HTTPResponseHeader, workspaceID idwrap.IDWrap) { + if p.httpResponseHeaderStream == nil { + return + } + headerPB := converter.ToAPIHttpResponseHeader(header) + p.httpResponseHeaderStream.Publish(rhttp.HttpResponseHeaderTopic{WorkspaceID: workspaceID}, rhttp.HttpResponseHeaderEvent{ + Type: eventTypeInsert, + HttpResponseHeader: headerPB, + }) +} + +func (p *execEventPublisher) PublishHTTPResponseAssert(assert mhttp.HTTPResponseAssert, workspaceID idwrap.IDWrap) { + if p.httpResponseAssertStream == nil { + return + } + assertPB := converter.ToAPIHttpResponseAssert(assert) + p.httpResponseAssertStream.Publish(rhttp.HttpResponseAssertTopic{WorkspaceID: workspaceID}, rhttp.HttpResponseAssertEvent{ + Type: eventTypeInsert, + HttpResponseAssert: assertPB, + }) +} + +func (p *execEventPublisher) PublishGraphQLResponse(response mgraphql.GraphQLResponse, workspaceID idwrap.IDWrap) { + if p.gqlResponseStream == nil { + return + } + responsePB := rgraphql.ToAPIGraphQLResponse(response) + p.gqlResponseStream.Publish(rgraphql.GraphQLResponseTopic{WorkspaceID: workspaceID}, rgraphql.GraphQLResponseEvent{ + Type: eventTypeInsert, + GraphQLResponse: responsePB, + }) +} + +func (p *execEventPublisher) PublishGraphQLResponseHeader(header mgraphql.GraphQLResponseHeader, workspaceID idwrap.IDWrap) { + if p.gqlResponseHeaderStream == nil { + return + } + headerPB := rgraphql.ToAPIGraphQLResponseHeader(header) + p.gqlResponseHeaderStream.Publish(rgraphql.GraphQLResponseHeaderTopic{WorkspaceID: workspaceID}, rgraphql.GraphQLResponseHeaderEvent{ + Type: eventTypeInsert, + GraphQLResponseHeader: headerPB, + }) +} + +func (p *execEventPublisher) PublishGraphQLResponseAssert(assert mgraphql.GraphQLResponseAssert, workspaceID idwrap.IDWrap) { + if p.gqlResponseAssertStream == nil { + return + } + assertPB := rgraphql.ToAPIGraphQLResponseAssert(assert) + p.gqlResponseAssertStream.Publish(rgraphql.GraphQLResponseAssertTopic{WorkspaceID: workspaceID}, rgraphql.GraphQLResponseAssertEvent{ + Type: eventTypeInsert, + GraphQLResponseAssert: assertPB, + }) +} + +func (p *execEventPublisher) PublishExecution(eventType string, execution mflow.NodeExecution, flowID idwrap.IDWrap) { + if p.executionStream == nil { + return + } + executionPB := serializeNodeExecution(execution) + p.executionStream.Publish(ExecutionTopic{FlowID: flowID}, ExecutionEvent{ + Type: eventType, + FlowID: flowID, + Execution: executionPB, + }) +} + +func (p *execEventPublisher) PublishNodeState(flowID, originalNodeID idwrap.IDWrap, state mflow.NodeState, info string) { + if p.nodeStream == nil { + return + } + nodePB := &flowv1.Node{ + NodeId: originalNodeID.Bytes(), + FlowId: flowID.Bytes(), + State: flowv1.FlowItemState(state), + } + if info != "" { + nodePB.Info = &info + } + p.nodeStream.Publish(NodeTopic{FlowID: flowID}, NodeEvent{ + Type: nodeEventUpdate, + FlowID: flowID, + Node: nodePB, + }) +} + +func (p *execEventPublisher) PublishEdgeState(edge mflow.Edge) { + if p.edgeStream == nil { + return + } + p.edgeStream.Publish(EdgeTopic{FlowID: edge.FlowID}, EdgeEvent{ + Type: edgeEventUpdate, + FlowID: edge.FlowID, + Edge: serializeEdge(edge), + }) +} + +func (p *execEventPublisher) PublishLog(flowID idwrap.IDWrap, status runner.FlowNodeStatus) { + if p.logStream == nil { + return + } + + idStr := status.NodeID.String() + stateStr := mflow.StringNodeState(status.State) + nodeName := status.Name + if nodeName == "" { + nodeName = idStr + } + msg := fmt.Sprintf("Node %s: %s", nodeName, stateStr) + + var logLevel logv1.LogLevel + switch status.State { + case mflow.NODE_STATE_FAILURE: + logLevel = logv1.LogLevel_LOG_LEVEL_ERROR + case mflow.NODE_STATE_CANCELED: + logLevel = logv1.LogLevel_LOG_LEVEL_WARNING + default: + logLevel = logv1.LogLevel_LOG_LEVEL_UNSPECIFIED + } + + logData := map[string]any{ + "node_id": status.NodeID.String(), + "node_name": status.Name, + "state": stateStr, + "flow_id": flowID.String(), + "duration_ms": status.RunDuration.Milliseconds(), + } + + const maxLogDataSize = 64 * 1024 // 64KB limit + if status.OutputData != nil { + if jsonBytes, err := json.Marshal(status.OutputData); err == nil { + if len(jsonBytes) <= maxLogDataSize { + var jsonSafe any + if json.Unmarshal(jsonBytes, &jsonSafe) == nil { + logData["output"] = jsonSafe + } + } else { + logData["output"] = "(output too large to display)" + } + } + } + if status.InputData != nil { + if jsonBytes, err := json.Marshal(status.InputData); err == nil { + if len(jsonBytes) <= maxLogDataSize { + var jsonSafe any + if json.Unmarshal(jsonBytes, &jsonSafe) == nil { + logData["input"] = jsonSafe + } + } else { + logData["input"] = "(input too large to display)" + } + } + } + if status.Error != nil { + logData["error"] = status.Error.Error() + } + if status.IterationContext != nil { + logData["iteration_index"] = status.IterationContext.ExecutionIndex + logData["iteration_path"] = status.IterationContext.IterationPath + } + + val, err := rlog.NewLogValue(logData) + if err != nil { + p.logger("failed to create log value", "error", err) + } + + p.logStream.Publish(rlog.LogTopic{}, rlog.LogEvent{ + Type: rlog.EventTypeInsert, + Log: &logv1.Log{ + LogId: idwrap.NewMonotonic().Bytes(), + Name: msg, + Level: logLevel, + Value: val, + }, + }) +} diff --git a/packages/server/internal/api/rflowv2/rflowv2_exec_test.go b/packages/server/internal/api/rflowv2/rflowv2_exec_test.go index 9406ae293..2eb1e5a75 100644 --- a/packages/server/internal/api/rflowv2/rflowv2_exec_test.go +++ b/packages/server/internal/api/rflowv2/rflowv2_exec_test.go @@ -20,6 +20,7 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/internal/api/middleware/mwauth" "github.com/the-dev-tools/dev-tools/packages/server/pkg/dbtime" "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/flowbuilder" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/flowexec" "github.com/the-dev-tools/dev-tools/packages/server/pkg/http/resolver" "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" @@ -76,6 +77,11 @@ func setupTestService(t *testing.T) (*FlowServiceV2RPC, *gen.Queries, context.Co &aiProviderService, &memoryService, nil, // NodeGraphQLService + nil, // NodeWsConnectionService + nil, // NodeWsSendService + nil, // NodeWaitService + nil, // WebSocketService + nil, // WebSocketHeaderService nil, // GraphQLService nil, // GraphQLHeaderService &wsService, @@ -87,27 +93,38 @@ func setupTestService(t *testing.T) (*FlowServiceV2RPC, *gen.Queries, context.Co nil, // LLMProviderFactory ) + // Build snapshot registry for version snapshots + registry := flowexec.NewSnapshotRegistry() + registry.Register(&flowexec.RequestSnapshot{Service: &reqService}) + registry.Register(&flowexec.ForSnapshot{Service: &forService}) + registry.Register(&flowexec.ForEachSnapshot{Service: &forEachService}) + registry.Register(&flowexec.ConditionSnapshot{Service: ifService}) + registry.Register(&flowexec.JSSnapshot{Service: &jsService}) + registry.Register(&flowexec.AIProviderSnapshot{Service: &aiProviderService}) + registry.Register(&flowexec.MemorySnapshot{Service: &memoryService}) + svc := &FlowServiceV2RPC{ - DB: db, - wsReader: wsReader, - fsReader: fsReader, - nsReader: nsReader, - ws: &wsService, - fs: &flowService, - ns: &nodeService, - nes: &nodeExecService, - es: &edgeService, - fvs: &flowVarService, - nrs: &reqService, // Added missing services to struct - nfs: &forService, - nfes: &forEachService, - nifs: ifService, - njss: &jsService, - naps: &aiProviderService, - nmems: &memoryService, - logger: logger, - builder: builder, - runningFlows: make(map[string]context.CancelFunc), + DB: db, + wsReader: wsReader, + fsReader: fsReader, + nsReader: nsReader, + ws: &wsService, + fs: &flowService, + ns: &nodeService, + nes: &nodeExecService, + es: &edgeService, + fvs: &flowVarService, + nrs: &reqService, + nfs: &forService, + nfes: &forEachService, + nifs: ifService, + njss: &jsService, + naps: &aiProviderService, + nmems: &memoryService, + logger: logger, + sessionFactory: &flowexec.LocalSessionFactory{Builder: builder}, + snapshotRegistry: registry, + runningFlows: make(map[string]context.CancelFunc), } // Setup User & Workspace diff --git a/packages/server/internal/api/rflowv2/rflowv2_exec_transaction_test.go b/packages/server/internal/api/rflowv2/rflowv2_exec_transaction_test.go index f82a93202..5171998b4 100644 --- a/packages/server/internal/api/rflowv2/rflowv2_exec_transaction_test.go +++ b/packages/server/internal/api/rflowv2/rflowv2_exec_transaction_test.go @@ -16,6 +16,7 @@ import ( gen "github.com/the-dev-tools/dev-tools/packages/db/pkg/sqlc/gen" "github.com/the-dev-tools/dev-tools/packages/server/internal/api/middleware/mwauth" "github.com/the-dev-tools/dev-tools/packages/server/pkg/dbtime" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/flowexec" "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mcondition" "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" @@ -25,6 +26,16 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/pkg/testutil" ) +func newTestSnapshotRegistry(nrs *sflow.NodeRequestService, nfs *sflow.NodeForService, nfes *sflow.NodeForEachService, nifs *sflow.NodeIfService, njss *sflow.NodeJsService) *flowexec.SnapshotRegistry { + registry := flowexec.NewSnapshotRegistry() + registry.Register(&flowexec.RequestSnapshot{Service: nrs}) + registry.Register(&flowexec.ForSnapshot{Service: nfs}) + registry.Register(&flowexec.ForEachSnapshot{Service: nfes}) + registry.Register(&flowexec.ConditionSnapshot{Service: nifs}) + registry.Register(&flowexec.JSSnapshot{Service: njss}) + return registry +} + // TestFlowVersionSnapshot_TransactionAtomicity verifies that createFlowVersionSnapshot // uses a single transaction and either creates ALL entities or NONE. // This test ensures the critical data corruption bug is fixed where partial flow @@ -53,18 +64,19 @@ func TestFlowVersionSnapshot_TransactionAtomicity(t *testing.T) { logger := slog.New(slog.NewTextHandler(os.Stdout, nil)) svc := &FlowServiceV2RPC{ - DB: db, - ws: &wsService, - fs: &flowService, - ns: &nodeService, - es: &edgeService, - nrs: &nrsService, - nfs: &nfsService, - nfes: &nfesService, - nifs: nifsService, - njss: &njssService, - fvs: &varService, - logger: logger, + DB: db, + ws: &wsService, + fs: &flowService, + ns: &nodeService, + es: &edgeService, + nrs: &nrsService, + nfs: &nfsService, + nfes: &nfesService, + nifs: nifsService, + njss: &njssService, + fvs: &varService, + logger: logger, + snapshotRegistry: newTestSnapshotRegistry(&nrsService, &nfsService, &nfesService, nifsService, &njssService), } // Create test data @@ -284,6 +296,7 @@ func TestFlowVersionSnapshot_TransactionAtomicity(t *testing.T) { ifData, err := nifsService.GetNodeIf(ctx, node.ID) require.NoError(t, err) require.NotNil(t, ifData, "Condition config should exist") + default: } } @@ -329,18 +342,19 @@ func TestFlowVersionSnapshot_EmptyFlow(t *testing.T) { logger := slog.New(slog.NewTextHandler(os.Stdout, nil)) svc := &FlowServiceV2RPC{ - DB: db, - ws: &wsService, - fs: &flowService, - ns: &nodeService, - es: &edgeService, - nrs: &nrsService, - nfs: &nfsService, - nfes: &nfesService, - nifs: nifsService, - njss: &njssService, - fvs: &varService, - logger: logger, + DB: db, + ws: &wsService, + fs: &flowService, + ns: &nodeService, + es: &edgeService, + nrs: &nrsService, + nfs: &nfsService, + nfes: &nfesService, + nifs: nifsService, + njss: &njssService, + fvs: &varService, + logger: logger, + snapshotRegistry: newTestSnapshotRegistry(&nrsService, &nfsService, &nfesService, nifsService, &njssService), } userID := idwrap.NewNow() @@ -439,18 +453,19 @@ func TestFlowVersionSnapshot_Concurrency_Simple(t *testing.T) { logger := slog.New(slog.NewTextHandler(os.Stdout, nil)) svc := &FlowServiceV2RPC{ - DB: db, - ws: &wsService, - fs: &flowService, - ns: &nodeService, - es: &edgeService, - nrs: &nrsService, - nfs: &nfsService, - nfes: &nfesService, - nifs: nifsService, - njss: &njssService, - fvs: &varService, - logger: logger, + DB: db, + ws: &wsService, + fs: &flowService, + ns: &nodeService, + es: &edgeService, + nrs: &nrsService, + nfs: &nfsService, + nfes: &nfesService, + nifs: nifsService, + njss: &njssService, + fvs: &varService, + logger: logger, + snapshotRegistry: newTestSnapshotRegistry(&nrsService, &nfsService, &nfesService, nifsService, &njssService), } userID := idwrap.NewNow() @@ -548,18 +563,19 @@ func TestFlowVersionSnapshot_Concurrency_WithNodes(t *testing.T) { logger := slog.New(slog.NewTextHandler(os.Stdout, nil)) svc := &FlowServiceV2RPC{ - DB: db, - ws: &wsService, - fs: &flowService, - ns: &nodeService, - es: &edgeService, - nrs: &nrsService, - nfs: &nfsService, - nfes: &nfesService, - nifs: nifsService, - njss: &njssService, - fvs: &varService, - logger: logger, + DB: db, + ws: &wsService, + fs: &flowService, + ns: &nodeService, + es: &edgeService, + nrs: &nrsService, + nfs: &nfsService, + nfes: &nfesService, + nifs: nifsService, + njss: &njssService, + fvs: &varService, + logger: logger, + snapshotRegistry: newTestSnapshotRegistry(&nrsService, &nfsService, &nfesService, nifsService, &njssService), } userID := idwrap.NewNow() @@ -676,18 +692,19 @@ func TestFlowVersionSnapshot_Concurrency_Complex(t *testing.T) { logger := slog.New(slog.NewTextHandler(os.Stdout, nil)) svc := &FlowServiceV2RPC{ - DB: db, - ws: &wsService, - fs: &flowService, - ns: &nodeService, - es: &edgeService, - nrs: &nrsService, - nfs: &nfsService, - nfes: &nfesService, - nifs: nifsService, - njss: &njssService, - fvs: &varService, - logger: logger, + DB: db, + ws: &wsService, + fs: &flowService, + ns: &nodeService, + es: &edgeService, + nrs: &nrsService, + nfs: &nfsService, + nfes: &nfesService, + nifs: nifsService, + njss: &njssService, + fvs: &varService, + logger: logger, + snapshotRegistry: newTestSnapshotRegistry(&nrsService, &nfsService, &nfesService, nifsService, &njssService), } userID := idwrap.NewNow() diff --git a/packages/server/internal/api/rflowv2/rflowv2_flow.go b/packages/server/internal/api/rflowv2/rflowv2_flow.go index 34631224c..7d464c54d 100644 --- a/packages/server/internal/api/rflowv2/rflowv2_flow.go +++ b/packages/server/internal/api/rflowv2/rflowv2_flow.go @@ -533,21 +533,27 @@ func (s *FlowServiceV2RPC) FlowDuplicate(ctx context.Context, req *connect.Reque // Collect node details outside TX type nodeDetail struct { - node mflow.Node - request *mflow.NodeRequest - http *mhttp.HTTP - forNode *mflow.NodeFor - forEach *mflow.NodeForEach - ifNode *mflow.NodeIf - jsNode *mflow.NodeJS - aiNode *mflow.NodeAI - aiProvider *mflow.NodeAiProvider - memoryNode *mflow.NodeMemory + node mflow.Node + request *mflow.NodeRequest + http *mhttp.HTTP + forNode *mflow.NodeFor + forEach *mflow.NodeForEach + ifNode *mflow.NodeIf + jsNode *mflow.NodeJS + aiNode *mflow.NodeAI + aiProvider *mflow.NodeAiProvider + memoryNode *mflow.NodeMemory + graphqlNode *mflow.NodeGraphQL + wsConnectionNode *mflow.NodeWsConnection + wsSendNode *mflow.NodeWsSend + waitNode *mflow.NodeWait } details := make([]nodeDetail, 0, len(sourceNodes)) for _, n := range sourceNodes { detail := nodeDetail{node: n} switch n.NodeKind { + case mflow.NODE_KIND_MANUAL_START: + // No type-specific data for ManualStart case mflow.NODE_KIND_REQUEST: if d, err := s.nrs.GetNodeRequest(ctx, n.ID); err == nil && d != nil { detail.request = d @@ -591,6 +597,30 @@ func (s *FlowServiceV2RPC) FlowDuplicate(ctx context.Context, req *connect.Reque detail.memoryNode = d } } + case mflow.NODE_KIND_GRAPHQL: + if s.ngqs != nil { + if d, err := s.ngqs.GetNodeGraphQL(ctx, n.ID); err == nil { + detail.graphqlNode = d + } + } + case mflow.NODE_KIND_WS_CONNECTION: + if s.nwcs != nil { + if d, err := s.nwcs.GetNodeWsConnection(ctx, n.ID); err == nil { + detail.wsConnectionNode = d + } + } + case mflow.NODE_KIND_WS_SEND: + if s.nwss != nil { + if d, err := s.nwss.GetNodeWsSend(ctx, n.ID); err == nil { + detail.wsSendNode = d + } + } + case mflow.NODE_KIND_WAIT: + if s.nwaits != nil { + if d, err := s.nwaits.GetNodeWait(ctx, n.ID); err == nil && d != nil { + detail.waitNode = d + } + } } details = append(details, detail) } @@ -723,6 +753,38 @@ func (s *FlowServiceV2RPC) FlowDuplicate(ctx context.Context, req *connect.Reque return nil, connect.NewError(connect.CodeInternal, err) } } + if d.graphqlNode != nil && s.ngqs != nil { + node := *d.graphqlNode + node.FlowNodeID = newNodeID + ngqsWriter := s.ngqs.TX(tx) + if err := ngqsWriter.CreateNodeGraphQL(ctx, node); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + } + if d.wsConnectionNode != nil && s.nwcs != nil { + node := *d.wsConnectionNode + node.FlowNodeID = newNodeID + nwcsWriter := s.nwcs.TX(tx) + if err := nwcsWriter.CreateNodeWsConnection(ctx, node); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + } + if d.wsSendNode != nil && s.nwss != nil { + node := *d.wsSendNode + node.FlowNodeID = newNodeID + nwssWriter := s.nwss.TX(tx) + if err := nwssWriter.CreateNodeWsSend(ctx, node); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + } + if d.waitNode != nil && s.nwaits != nil { + node := *d.waitNode + node.FlowNodeID = newNodeID + nwaitsWriter := s.nwaits.TX(tx) + if err := nwaitsWriter.CreateNodeWait(ctx, node); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + } } // Track created edges for event publishing diff --git a/packages/server/internal/api/rflowv2/rflowv2_node_condition_test.go b/packages/server/internal/api/rflowv2/rflowv2_node_condition_test.go index 9af57a738..f1a523190 100644 --- a/packages/server/internal/api/rflowv2/rflowv2_node_condition_test.go +++ b/packages/server/internal/api/rflowv2/rflowv2_node_condition_test.go @@ -17,6 +17,7 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/internal/api/middleware/mwauth" "github.com/the-dev-tools/dev-tools/packages/server/pkg/dbtime" "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/flowbuilder" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/flowexec" "github.com/the-dev-tools/dev-tools/packages/server/pkg/http/resolver" "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" @@ -72,6 +73,11 @@ func TestNodeCondition_CRUD(t *testing.T) { nil, // NodeAiProviderService nil, // NodeMemoryService nil, // NodeGraphQLService + nil, // NodeWsConnectionService + nil, // NodeWsSendService + nil, // NodeWaitService + nil, // WebSocketService + nil, // WebSocketHeaderService nil, // GraphQLService nil, // GraphQLHeaderService &wsService, @@ -96,7 +102,7 @@ func TestNodeCondition_CRUD(t *testing.T) { es: &edgeService, fvs: &flowVarService, logger: logger, - builder: builder, + sessionFactory: &flowexec.LocalSessionFactory{Builder: builder}, } // Setup Data diff --git a/packages/server/internal/api/rflowv2/rflowv2_node_exec.go b/packages/server/internal/api/rflowv2/rflowv2_node_exec.go index 834659791..db49ae7df 100644 --- a/packages/server/internal/api/rflowv2/rflowv2_node_exec.go +++ b/packages/server/internal/api/rflowv2/rflowv2_node_exec.go @@ -10,14 +10,9 @@ import ( "connectrpc.com/connect" emptypb "google.golang.org/protobuf/types/known/emptypb" - "github.com/the-dev-tools/dev-tools/packages/server/internal/api/rgraphql" - "github.com/the-dev-tools/dev-tools/packages/server/internal/api/rhttp" - "github.com/the-dev-tools/dev-tools/packages/server/internal/converter" "github.com/the-dev-tools/dev-tools/packages/server/pkg/eventstream" "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" - "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mgraphql" - "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mhttp" flowv1 "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/api/flow/v1" ) @@ -161,71 +156,6 @@ func (s *FlowServiceV2RPC) publishExecutionEvent(eventType string, execution mfl }) } -func (s *FlowServiceV2RPC) publishHttpResponseEvent(eventType string, response mhttp.HTTPResponse, workspaceID idwrap.IDWrap) { - if s.httpResponseStream == nil { - return - } - responsePB := converter.ToAPIHttpResponse(response) - s.httpResponseStream.Publish(rhttp.HttpResponseTopic{WorkspaceID: workspaceID}, rhttp.HttpResponseEvent{ - Type: eventType, - HttpResponse: responsePB, - }) -} - -func (s *FlowServiceV2RPC) publishHttpResponseHeaderEvent(eventType string, header mhttp.HTTPResponseHeader, workspaceID idwrap.IDWrap) { - if s.httpResponseHeaderStream == nil { - return - } - headerPB := converter.ToAPIHttpResponseHeader(header) - s.httpResponseHeaderStream.Publish(rhttp.HttpResponseHeaderTopic{WorkspaceID: workspaceID}, rhttp.HttpResponseHeaderEvent{ - Type: eventType, - HttpResponseHeader: headerPB, - }) -} - -func (s *FlowServiceV2RPC) publishHttpResponseAssertEvent(eventType string, assert mhttp.HTTPResponseAssert, workspaceID idwrap.IDWrap) { - if s.httpResponseAssertStream == nil { - return - } - assertPB := converter.ToAPIHttpResponseAssert(assert) - s.httpResponseAssertStream.Publish(rhttp.HttpResponseAssertTopic{WorkspaceID: workspaceID}, rhttp.HttpResponseAssertEvent{ - Type: eventType, - HttpResponseAssert: assertPB, - }) -} - -func (s *FlowServiceV2RPC) publishGraphQLResponseEvent(eventType string, response mgraphql.GraphQLResponse, workspaceID idwrap.IDWrap) { - if s.graphqlResponseStream == nil { - return - } - responsePB := rgraphql.ToAPIGraphQLResponse(response) - s.graphqlResponseStream.Publish(rgraphql.GraphQLResponseTopic{WorkspaceID: workspaceID}, rgraphql.GraphQLResponseEvent{ - Type: eventType, - GraphQLResponse: responsePB, - }) -} - -func (s *FlowServiceV2RPC) publishGraphQLResponseHeaderEvent(eventType string, header mgraphql.GraphQLResponseHeader, workspaceID idwrap.IDWrap) { - if s.graphqlResponseHeaderStream == nil { - return - } - headerPB := rgraphql.ToAPIGraphQLResponseHeader(header) - s.graphqlResponseHeaderStream.Publish(rgraphql.GraphQLResponseHeaderTopic{WorkspaceID: workspaceID}, rgraphql.GraphQLResponseHeaderEvent{ - Type: eventType, - GraphQLResponseHeader: headerPB, - }) -} - -func (s *FlowServiceV2RPC) publishGraphQLResponseAssertEvent(eventType string, assert mgraphql.GraphQLResponseAssert, workspaceID idwrap.IDWrap) { - if s.graphqlResponseAssertStream == nil { - return - } - assertPB := rgraphql.ToAPIGraphQLResponseAssert(assert) - s.graphqlResponseAssertStream.Publish(rgraphql.GraphQLResponseAssertTopic{WorkspaceID: workspaceID}, rgraphql.GraphQLResponseAssertEvent{ - Type: eventType, - GraphQLResponseAssert: assertPB, - }) -} func (s *FlowServiceV2RPC) executionEventToSyncResponse( ctx context.Context, diff --git a/packages/server/internal/api/rflowv2/rflowv2_node_exec_test.go b/packages/server/internal/api/rflowv2/rflowv2_node_exec_test.go index d75541308..297edd26b 100644 --- a/packages/server/internal/api/rflowv2/rflowv2_node_exec_test.go +++ b/packages/server/internal/api/rflowv2/rflowv2_node_exec_test.go @@ -17,6 +17,7 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/internal/api/middleware/mwauth" "github.com/the-dev-tools/dev-tools/packages/server/pkg/dbtime" "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/flowbuilder" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/flowexec" "github.com/the-dev-tools/dev-tools/packages/server/pkg/http/resolver" "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" @@ -72,6 +73,11 @@ func TestNodeExecution_Collection(t *testing.T) { nil, // NodeAiProviderService nil, // NodeMemoryService nil, // NodeGraphQLService + nil, // NodeWsConnectionService + nil, // NodeWsSendService + nil, // NodeWaitService + nil, // WebSocketService + nil, // WebSocketHeaderService nil, // GraphQLService nil, // GraphQLHeaderService &wsService, @@ -96,7 +102,7 @@ func TestNodeExecution_Collection(t *testing.T) { es: &edgeService, fvs: &flowVarService, logger: logger, - builder: builder, + sessionFactory: &flowexec.LocalSessionFactory{Builder: builder}, } // Setup Data @@ -223,6 +229,11 @@ func TestNodeExecution_Collection_VersionFlow(t *testing.T) { nil, // NodeAiProviderService nil, // NodeMemoryService nil, // NodeGraphQLService + nil, // NodeWsConnectionService + nil, // NodeWsSendService + nil, // NodeWaitService + nil, // WebSocketService + nil, // WebSocketHeaderService nil, // GraphQLService nil, // GraphQLHeaderService &wsService, @@ -247,7 +258,7 @@ func TestNodeExecution_Collection_VersionFlow(t *testing.T) { es: &edgeService, fvs: &flowVarService, logger: logger, - builder: builder, + sessionFactory: &flowexec.LocalSessionFactory{Builder: builder}, } // Setup Data diff --git a/packages/server/internal/api/rflowv2/rflowv2_node_wait.go b/packages/server/internal/api/rflowv2/rflowv2_node_wait.go new file mode 100644 index 000000000..8197beb84 --- /dev/null +++ b/packages/server/internal/api/rflowv2/rflowv2_node_wait.go @@ -0,0 +1,426 @@ +//nolint:revive // exported +package rflowv2 + +import ( + "context" + "database/sql" + "errors" + "fmt" + "sync" + + "connectrpc.com/connect" + emptypb "google.golang.org/protobuf/types/known/emptypb" + + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/mutation" + flowv1 "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/api/flow/v1" +) + +type nodeWaitWithFlow struct { + nodeWait mflow.NodeWait + flowID idwrap.IDWrap + baseNode *mflow.Node +} + +func (s *FlowServiceV2RPC) NodeWaitCollection( + ctx context.Context, + _ *connect.Request[emptypb.Empty], +) (*connect.Response[flowv1.NodeWaitCollectionResponse], error) { + flows, err := s.listAccessibleFlows(ctx) + if err != nil { + return nil, err + } + + var items []*flowv1.NodeWait + for _, flow := range flows { + nodes, err := s.nsReader.GetNodesByFlowID(ctx, flow.ID) + if err != nil && !errors.Is(err, sql.ErrNoRows) { + return nil, connect.NewError(connect.CodeInternal, err) + } + for _, node := range nodes { + if node.NodeKind != mflow.NODE_KIND_WAIT { + continue + } + nodeWait, err := s.nwaits.GetNodeWait(ctx, node.ID) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + continue + } + return nil, connect.NewError(connect.CodeInternal, err) + } + if nodeWait == nil { + continue + } + items = append(items, serializeNodeWait(*nodeWait)) + } + } + + return connect.NewResponse(&flowv1.NodeWaitCollectionResponse{Items: items}), nil +} + +func (s *FlowServiceV2RPC) NodeWaitInsert( + ctx context.Context, + req *connect.Request[flowv1.NodeWaitInsertRequest], +) (*connect.Response[emptypb.Empty], error) { + type insertData struct { + nodeID idwrap.IDWrap + durationMs int64 + baseNode *mflow.Node + flowID idwrap.IDWrap + workspaceID idwrap.IDWrap + } + var validatedItems []insertData + + for _, item := range req.Msg.GetItems() { + nodeID, err := idwrap.NewFromBytes(item.GetNodeId()) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("invalid node id: %w", err)) + } + + baseNode, _ := s.ns.GetNode(ctx, nodeID) + + var flowID idwrap.IDWrap + var workspaceID idwrap.IDWrap + if baseNode != nil { + flowID = baseNode.FlowID + flow, err := s.fsReader.GetFlow(ctx, flowID) + if err == nil { + workspaceID = flow.WorkspaceID + } + } + + validatedItems = append(validatedItems, insertData{ + nodeID: nodeID, + durationMs: item.GetDurationMs(), + baseNode: baseNode, + flowID: flowID, + workspaceID: workspaceID, + }) + } + + if len(validatedItems) == 0 { + return connect.NewResponse(&emptypb.Empty{}), nil + } + + mut := mutation.New(s.DB, mutation.WithPublisher(s.mutationPublisher())) + if err := mut.Begin(ctx); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + defer mut.Rollback() + + nwaitsWriter := s.nwaits.TX(mut.TX()) + + for _, data := range validatedItems { + nodeWait := mflow.NodeWait{ + FlowNodeID: data.nodeID, + DurationMs: data.durationMs, + } + + if err := nwaitsWriter.CreateNodeWait(ctx, nodeWait); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + if data.baseNode != nil { + mut.Track(mutation.Event{ + Entity: mutation.EntityFlowNodeWait, + Op: mutation.OpInsert, + ID: data.nodeID, + WorkspaceID: data.workspaceID, + ParentID: data.flowID, + Payload: nodeWaitWithFlow{ + nodeWait: nodeWait, + flowID: data.flowID, + baseNode: data.baseNode, + }, + }) + } + } + + if err := mut.Commit(ctx); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + return connect.NewResponse(&emptypb.Empty{}), nil +} + +func (s *FlowServiceV2RPC) NodeWaitUpdate( + ctx context.Context, + req *connect.Request[flowv1.NodeWaitUpdateRequest], +) (*connect.Response[emptypb.Empty], error) { + type updateData struct { + nodeID idwrap.IDWrap + durationMs int64 + baseNode *mflow.Node + workspaceID idwrap.IDWrap + } + var validatedItems []updateData + + for _, item := range req.Msg.GetItems() { + nodeID, err := idwrap.NewFromBytes(item.GetNodeId()) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("invalid node id: %w", err)) + } + + nodeModel, err := s.ensureNodeAccess(ctx, nodeID) + if err != nil { + return nil, err + } + + flow, err := s.fsReader.GetFlow(ctx, nodeModel.FlowID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + existing, err := s.nwaits.GetNodeWait(ctx, nodeID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + durationMs := existing.DurationMs + if item.DurationMs != nil { + durationMs = *item.DurationMs + } + + validatedItems = append(validatedItems, updateData{ + nodeID: nodeID, + durationMs: durationMs, + baseNode: nodeModel, + workspaceID: flow.WorkspaceID, + }) + } + + if len(validatedItems) == 0 { + return connect.NewResponse(&emptypb.Empty{}), nil + } + + mut := mutation.New(s.DB, mutation.WithPublisher(s.mutationPublisher())) + if err := mut.Begin(ctx); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + defer mut.Rollback() + + nwaitsWriter := s.nwaits.TX(mut.TX()) + + for _, data := range validatedItems { + nodeWait := mflow.NodeWait{ + FlowNodeID: data.nodeID, + DurationMs: data.durationMs, + } + + if err := nwaitsWriter.UpdateNodeWait(ctx, nodeWait); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + mut.Track(mutation.Event{ + Entity: mutation.EntityFlowNodeWait, + Op: mutation.OpUpdate, + ID: data.nodeID, + WorkspaceID: data.workspaceID, + ParentID: data.baseNode.FlowID, + Payload: nodeWaitWithFlow{ + nodeWait: nodeWait, + flowID: data.baseNode.FlowID, + baseNode: data.baseNode, + }, + }) + } + + if err := mut.Commit(ctx); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + return connect.NewResponse(&emptypb.Empty{}), nil +} + +func (s *FlowServiceV2RPC) NodeWaitDelete( + ctx context.Context, + req *connect.Request[flowv1.NodeWaitDeleteRequest], +) (*connect.Response[emptypb.Empty], error) { + type deleteData struct { + nodeID idwrap.IDWrap + flowID idwrap.IDWrap + } + var validatedItems []deleteData + + for _, item := range req.Msg.GetItems() { + nodeID, err := idwrap.NewFromBytes(item.GetNodeId()) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("invalid node id: %w", err)) + } + + nodeModel, err := s.ensureNodeAccess(ctx, nodeID) + if err != nil { + return nil, err + } + + validatedItems = append(validatedItems, deleteData{ + nodeID: nodeID, + flowID: nodeModel.FlowID, + }) + } + + if len(validatedItems) == 0 { + return connect.NewResponse(&emptypb.Empty{}), nil + } + + mut := mutation.New(s.DB, mutation.WithPublisher(s.mutationPublisher())) + if err := mut.Begin(ctx); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + defer mut.Rollback() + + for _, data := range validatedItems { + mut.Track(mutation.Event{ + Entity: mutation.EntityFlowNodeWait, + Op: mutation.OpDelete, + ID: data.nodeID, + ParentID: data.flowID, + }) + if err := mut.Queries().DeleteFlowNodeWait(ctx, data.nodeID); err != nil && !errors.Is(err, sql.ErrNoRows) { + return nil, connect.NewError(connect.CodeInternal, err) + } + } + + if err := mut.Commit(ctx); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + return connect.NewResponse(&emptypb.Empty{}), nil +} + +func (s *FlowServiceV2RPC) NodeWaitSync( + ctx context.Context, + _ *connect.Request[emptypb.Empty], + stream *connect.ServerStream[flowv1.NodeWaitSyncResponse], +) error { + if stream == nil { + return connect.NewError(connect.CodeInternal, errors.New("stream is required")) + } + return s.streamNodeWaitSync(ctx, func(resp *flowv1.NodeWaitSyncResponse) error { + return stream.Send(resp) + }) +} + +func (s *FlowServiceV2RPC) streamNodeWaitSync( + ctx context.Context, + send func(*flowv1.NodeWaitSyncResponse) error, +) error { + if s.nodeStream == nil { + return connect.NewError(connect.CodeUnavailable, errors.New("node stream not configured")) + } + + var flowSet sync.Map + + filter := func(topic NodeTopic) bool { + if _, ok := flowSet.Load(topic.FlowID.String()); ok { + return true + } + if err := s.ensureFlowAccess(ctx, topic.FlowID); err != nil { + return false + } + flowSet.Store(topic.FlowID.String(), struct{}{}) + return true + } + + events, err := s.nodeStream.Subscribe(ctx, filter) + if err != nil { + return connect.NewError(connect.CodeInternal, err) + } + + for { + select { + case evt, ok := <-events: + if !ok { + return nil + } + resp, err := s.nodeWaitEventToSyncResponse(ctx, evt.Payload) + if err != nil { + return connect.NewError(connect.CodeInternal, fmt.Errorf("failed to convert wait node event: %w", err)) + } + if resp == nil { + continue + } + if err := send(resp); err != nil { + return err + } + case <-ctx.Done(): + return ctx.Err() + } + } +} + +func (s *FlowServiceV2RPC) nodeWaitEventToSyncResponse( + ctx context.Context, + evt NodeEvent, +) (*flowv1.NodeWaitSyncResponse, error) { + if evt.Node == nil { + return nil, nil + } + + if evt.Node.GetKind() != flowv1.NodeKind_NODE_KIND_WAIT { + return nil, nil + } + + nodeID, err := idwrap.NewFromBytes(evt.Node.GetNodeId()) + if err != nil { + return nil, fmt.Errorf("invalid node id: %w", err) + } + + nodeWait, err := s.nwaits.GetNodeWait(ctx, nodeID) + if err != nil && !errors.Is(err, sql.ErrNoRows) { + return nil, err + } + + var syncEvent *flowv1.NodeWaitSync + switch evt.Type { + case nodeEventInsert: + if nodeWait == nil { + return nil, nil + } + syncEvent = &flowv1.NodeWaitSync{ + Value: &flowv1.NodeWaitSync_ValueUnion{ + Kind: flowv1.NodeWaitSync_ValueUnion_KIND_INSERT, + Insert: &flowv1.NodeWaitSyncInsert{ + NodeId: nodeID.Bytes(), + DurationMs: nodeWait.DurationMs, + }, + }, + } + case nodeEventUpdate: + if nodeWait == nil { + return nil, nil + } + syncEvent = &flowv1.NodeWaitSync{ + Value: &flowv1.NodeWaitSync_ValueUnion{ + Kind: flowv1.NodeWaitSync_ValueUnion_KIND_UPDATE, + Update: &flowv1.NodeWaitSyncUpdate{ + NodeId: nodeID.Bytes(), + DurationMs: &nodeWait.DurationMs, + }, + }, + } + case nodeEventDelete: + syncEvent = &flowv1.NodeWaitSync{ + Value: &flowv1.NodeWaitSync_ValueUnion{ + Kind: flowv1.NodeWaitSync_ValueUnion_KIND_DELETE, + Delete: &flowv1.NodeWaitSyncDelete{ + NodeId: nodeID.Bytes(), + }, + }, + } + default: + return nil, nil + } + + return &flowv1.NodeWaitSyncResponse{ + Items: []*flowv1.NodeWaitSync{syncEvent}, + }, nil +} + +func serializeNodeWait(n mflow.NodeWait) *flowv1.NodeWait { + return &flowv1.NodeWait{ + NodeId: n.FlowNodeID.Bytes(), + DurationMs: n.DurationMs, + } +} diff --git a/packages/server/internal/api/rflowv2/rflowv2_node_ws_connection.go b/packages/server/internal/api/rflowv2/rflowv2_node_ws_connection.go new file mode 100644 index 000000000..9869370ec --- /dev/null +++ b/packages/server/internal/api/rflowv2/rflowv2_node_ws_connection.go @@ -0,0 +1,464 @@ +//nolint:revive // exported +package rflowv2 + +import ( + "context" + "database/sql" + "errors" + "fmt" + "sync" + + "connectrpc.com/connect" + emptypb "google.golang.org/protobuf/types/known/emptypb" + + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/mutation" + flowv1 "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/api/flow/v1" +) + +// NodeWsConnectionTopic identifies the flow whose WS Connection nodes are being published. +type NodeWsConnectionTopic struct { + FlowID idwrap.IDWrap +} + +// NodeWsConnectionEvent describes a WS Connection node change for sync streaming. +type NodeWsConnectionEvent struct { + Type string + FlowID idwrap.IDWrap + Node *flowv1.NodeWsConnection +} + +func (s *FlowServiceV2RPC) NodeWsConnectionCollection( + ctx context.Context, + _ *connect.Request[emptypb.Empty], +) (*connect.Response[flowv1.NodeWsConnectionCollectionResponse], error) { + flows, err := s.listAccessibleFlows(ctx) + if err != nil { + return nil, err + } + + var items []*flowv1.NodeWsConnection + for _, flow := range flows { + nodes, err := s.nsReader.GetNodesByFlowID(ctx, flow.ID) + if err != nil && !errors.Is(err, sql.ErrNoRows) { + return nil, connect.NewError(connect.CodeInternal, err) + } + for _, node := range nodes { + if node.NodeKind != mflow.NODE_KIND_WS_CONNECTION { + continue + } + nodeWsConn, err := s.nwcs.GetNodeWsConnection(ctx, node.ID) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + continue + } + return nil, connect.NewError(connect.CodeInternal, err) + } + if nodeWsConn == nil { + continue + } + items = append(items, serializeNodeWsConnection(*nodeWsConn)) + } + } + + return connect.NewResponse(&flowv1.NodeWsConnectionCollectionResponse{Items: items}), nil +} + +func (s *FlowServiceV2RPC) NodeWsConnectionInsert( + ctx context.Context, + req *connect.Request[flowv1.NodeWsConnectionInsertRequest], +) (*connect.Response[emptypb.Empty], error) { + type insertData struct { + nodeID idwrap.IDWrap + wsID *idwrap.IDWrap + baseNode *mflow.Node + flowID idwrap.IDWrap + workspaceID idwrap.IDWrap + } + var validatedItems []insertData + + for _, item := range req.Msg.GetItems() { + nodeID, err := idwrap.NewFromBytes(item.GetNodeId()) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("invalid node id: %w", err)) + } + + var wsID *idwrap.IDWrap + if len(item.GetWebsocketId()) > 0 { + parsedID, err := idwrap.NewFromBytes(item.GetWebsocketId()) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("invalid websocket id: %w", err)) + } + if !isZeroID(parsedID) { + wsID = &parsedID + } + } + + baseNode, _ := s.ns.GetNode(ctx, nodeID) + + var flowID idwrap.IDWrap + var workspaceID idwrap.IDWrap + if baseNode != nil { + flowID = baseNode.FlowID + flow, err := s.fsReader.GetFlow(ctx, flowID) + if err == nil { + workspaceID = flow.WorkspaceID + } + } + + validatedItems = append(validatedItems, insertData{ + nodeID: nodeID, + wsID: wsID, + baseNode: baseNode, + flowID: flowID, + workspaceID: workspaceID, + }) + } + + if len(validatedItems) == 0 { + return connect.NewResponse(&emptypb.Empty{}), nil + } + + mut := mutation.New(s.DB, mutation.WithPublisher(s.mutationPublisher())) + if err := mut.Begin(ctx); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + defer mut.Rollback() + + nwcsWriter := s.nwcs.TX(mut.TX()) + + for _, data := range validatedItems { + nodeWsConn := mflow.NodeWsConnection{ + FlowNodeID: data.nodeID, + WebSocketID: data.wsID, + } + + if err := nwcsWriter.CreateNodeWsConnection(ctx, nodeWsConn); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + if data.baseNode != nil { + mut.Track(mutation.Event{ + Entity: mutation.EntityFlowNodeWsConnection, + Op: mutation.OpInsert, + ID: data.nodeID, + WorkspaceID: data.workspaceID, + ParentID: data.flowID, + Payload: nodeWsConnectionWithFlow{ + nodeWsConnection: nodeWsConn, + flowID: data.flowID, + baseNode: data.baseNode, + }, + }) + } + } + + if err := mut.Commit(ctx); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + return connect.NewResponse(&emptypb.Empty{}), nil +} + +func (s *FlowServiceV2RPC) NodeWsConnectionUpdate( + ctx context.Context, + req *connect.Request[flowv1.NodeWsConnectionUpdateRequest], +) (*connect.Response[emptypb.Empty], error) { + type updateData struct { + nodeID idwrap.IDWrap + wsID *idwrap.IDWrap + baseNode *mflow.Node + workspaceID idwrap.IDWrap + } + var validatedItems []updateData + + for _, item := range req.Msg.GetItems() { + nodeID, err := idwrap.NewFromBytes(item.GetNodeId()) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("invalid node id: %w", err)) + } + + nodeModel, err := s.ensureNodeAccess(ctx, nodeID) + if err != nil { + return nil, err + } + + flow, err := s.fsReader.GetFlow(ctx, nodeModel.FlowID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + var wsID *idwrap.IDWrap + if wsUnion := item.GetWebsocketId(); wsUnion != nil { + if wsUnion.GetKind() == flowv1.NodeWsConnectionUpdate_WebsocketIdUnion_KIND_VALUE { + if len(wsUnion.GetValue()) > 0 { + parsedID, err := idwrap.NewFromBytes(wsUnion.GetValue()) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("invalid websocket id: %w", err)) + } + if !isZeroID(parsedID) { + wsID = &parsedID + } + } + } + // KIND_UNSET leaves wsID as nil (clears it) + } else { + // No update to websocket_id — preserve existing + existing, err := s.nwcs.GetNodeWsConnection(ctx, nodeID) + if err == nil { + wsID = existing.WebSocketID + } + } + + validatedItems = append(validatedItems, updateData{ + nodeID: nodeID, + wsID: wsID, + baseNode: nodeModel, + workspaceID: flow.WorkspaceID, + }) + } + + if len(validatedItems) == 0 { + return connect.NewResponse(&emptypb.Empty{}), nil + } + + mut := mutation.New(s.DB, mutation.WithPublisher(s.mutationPublisher())) + if err := mut.Begin(ctx); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + defer mut.Rollback() + + nwcsWriter := s.nwcs.TX(mut.TX()) + + for _, data := range validatedItems { + nodeWsConn := mflow.NodeWsConnection{ + FlowNodeID: data.nodeID, + WebSocketID: data.wsID, + } + + if err := nwcsWriter.UpdateNodeWsConnection(ctx, nodeWsConn); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + mut.Track(mutation.Event{ + Entity: mutation.EntityFlowNodeWsConnection, + Op: mutation.OpUpdate, + ID: data.nodeID, + WorkspaceID: data.workspaceID, + ParentID: data.baseNode.FlowID, + Payload: nodeWsConnectionWithFlow{ + nodeWsConnection: nodeWsConn, + flowID: data.baseNode.FlowID, + baseNode: data.baseNode, + }, + }) + } + + if err := mut.Commit(ctx); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + return connect.NewResponse(&emptypb.Empty{}), nil +} + +func (s *FlowServiceV2RPC) NodeWsConnectionDelete( + ctx context.Context, + req *connect.Request[flowv1.NodeWsConnectionDeleteRequest], +) (*connect.Response[emptypb.Empty], error) { + type deleteData struct { + nodeID idwrap.IDWrap + flowID idwrap.IDWrap + } + var validatedItems []deleteData + + for _, item := range req.Msg.GetItems() { + nodeID, err := idwrap.NewFromBytes(item.GetNodeId()) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("invalid node id: %w", err)) + } + + nodeModel, err := s.ensureNodeAccess(ctx, nodeID) + if err != nil { + return nil, err + } + + validatedItems = append(validatedItems, deleteData{ + nodeID: nodeID, + flowID: nodeModel.FlowID, + }) + } + + if len(validatedItems) == 0 { + return connect.NewResponse(&emptypb.Empty{}), nil + } + + mut := mutation.New(s.DB, mutation.WithPublisher(s.mutationPublisher())) + if err := mut.Begin(ctx); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + defer mut.Rollback() + + for _, data := range validatedItems { + mut.Track(mutation.Event{ + Entity: mutation.EntityFlowNodeWsConnection, + Op: mutation.OpDelete, + ID: data.nodeID, + ParentID: data.flowID, + }) + if err := mut.Queries().DeleteFlowNodeWsConnection(ctx, data.nodeID); err != nil && !errors.Is(err, sql.ErrNoRows) { + return nil, connect.NewError(connect.CodeInternal, err) + } + } + + if err := mut.Commit(ctx); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + return connect.NewResponse(&emptypb.Empty{}), nil +} + +func (s *FlowServiceV2RPC) NodeWsConnectionSync( + ctx context.Context, + _ *connect.Request[emptypb.Empty], + stream *connect.ServerStream[flowv1.NodeWsConnectionSyncResponse], +) error { + if stream == nil { + return connect.NewError(connect.CodeInternal, errors.New("stream is required")) + } + return s.streamNodeWsConnectionSync(ctx, func(resp *flowv1.NodeWsConnectionSyncResponse) error { + return stream.Send(resp) + }) +} + +func (s *FlowServiceV2RPC) streamNodeWsConnectionSync( + ctx context.Context, + send func(*flowv1.NodeWsConnectionSyncResponse) error, +) error { + if s.nodeStream == nil { + return connect.NewError(connect.CodeUnavailable, errors.New("node stream not configured")) + } + + var flowSet sync.Map + + filter := func(topic NodeTopic) bool { + if _, ok := flowSet.Load(topic.FlowID.String()); ok { + return true + } + if err := s.ensureFlowAccess(ctx, topic.FlowID); err != nil { + return false + } + flowSet.Store(topic.FlowID.String(), struct{}{}) + return true + } + + events, err := s.nodeStream.Subscribe(ctx, filter) + if err != nil { + return connect.NewError(connect.CodeInternal, err) + } + + for { + select { + case evt, ok := <-events: + if !ok { + return nil + } + resp, err := s.nodeWsConnectionEventToSyncResponse(ctx, evt.Payload) + if err != nil { + return connect.NewError(connect.CodeInternal, fmt.Errorf("failed to convert WS connection node event: %w", err)) + } + if resp == nil { + continue + } + if err := send(resp); err != nil { + return err + } + case <-ctx.Done(): + return ctx.Err() + } + } +} + +func (s *FlowServiceV2RPC) nodeWsConnectionEventToSyncResponse( + ctx context.Context, + evt NodeEvent, +) (*flowv1.NodeWsConnectionSyncResponse, error) { + if evt.Node == nil { + return nil, nil + } + + if evt.Node.GetKind() != flowv1.NodeKind_NODE_KIND_WS_CONNECTION { + return nil, nil + } + + nodeID, err := idwrap.NewFromBytes(evt.Node.GetNodeId()) + if err != nil { + return nil, fmt.Errorf("invalid node id: %w", err) + } + + nodeWsConn, err := s.nwcs.GetNodeWsConnection(ctx, nodeID) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, nil // Skip — version nodes don't have WsConnection records + } + return nil, err + } + + var syncEvent *flowv1.NodeWsConnectionSync + switch evt.Type { + case nodeEventInsert: + insert := &flowv1.NodeWsConnectionSyncInsert{ + NodeId: nodeID.Bytes(), + } + if nodeWsConn != nil && nodeWsConn.WebSocketID != nil && !isZeroID(*nodeWsConn.WebSocketID) { + insert.WebsocketId = nodeWsConn.WebSocketID.Bytes() + } + syncEvent = &flowv1.NodeWsConnectionSync{ + Value: &flowv1.NodeWsConnectionSync_ValueUnion{ + Kind: flowv1.NodeWsConnectionSync_ValueUnion_KIND_INSERT, + Insert: insert, + }, + } + case nodeEventUpdate: + update := &flowv1.NodeWsConnectionSyncUpdate{ + NodeId: nodeID.Bytes(), + } + if nodeWsConn != nil && nodeWsConn.WebSocketID != nil && !isZeroID(*nodeWsConn.WebSocketID) { + update.WebsocketId = &flowv1.NodeWsConnectionSyncUpdate_WebsocketIdUnion{ + Kind: flowv1.NodeWsConnectionSyncUpdate_WebsocketIdUnion_KIND_VALUE, + Value: nodeWsConn.WebSocketID.Bytes(), + } + } + syncEvent = &flowv1.NodeWsConnectionSync{ + Value: &flowv1.NodeWsConnectionSync_ValueUnion{ + Kind: flowv1.NodeWsConnectionSync_ValueUnion_KIND_UPDATE, + Update: update, + }, + } + case nodeEventDelete: + syncEvent = &flowv1.NodeWsConnectionSync{ + Value: &flowv1.NodeWsConnectionSync_ValueUnion{ + Kind: flowv1.NodeWsConnectionSync_ValueUnion_KIND_DELETE, + Delete: &flowv1.NodeWsConnectionSyncDelete{ + NodeId: nodeID.Bytes(), + }, + }, + } + default: + return nil, nil + } + + return &flowv1.NodeWsConnectionSyncResponse{ + Items: []*flowv1.NodeWsConnectionSync{syncEvent}, + }, nil +} + +func serializeNodeWsConnection(n mflow.NodeWsConnection) *flowv1.NodeWsConnection { + msg := &flowv1.NodeWsConnection{ + NodeId: n.FlowNodeID.Bytes(), + } + if n.WebSocketID != nil && !isZeroID(*n.WebSocketID) { + msg.WebsocketId = n.WebSocketID.Bytes() + } + return msg +} diff --git a/packages/server/internal/api/rflowv2/rflowv2_node_ws_send.go b/packages/server/internal/api/rflowv2/rflowv2_node_ws_send.go new file mode 100644 index 000000000..8da1796a8 --- /dev/null +++ b/packages/server/internal/api/rflowv2/rflowv2_node_ws_send.go @@ -0,0 +1,446 @@ +//nolint:revive // exported +package rflowv2 + +import ( + "context" + "database/sql" + "errors" + "fmt" + "sync" + + "connectrpc.com/connect" + emptypb "google.golang.org/protobuf/types/known/emptypb" + + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/mutation" + flowv1 "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/api/flow/v1" +) + +// NodeWsSendTopic identifies the flow whose WS Send nodes are being published. +type NodeWsSendTopic struct { + FlowID idwrap.IDWrap +} + +// NodeWsSendEvent describes a WS Send node change for sync streaming. +type NodeWsSendEvent struct { + Type string + FlowID idwrap.IDWrap + Node *flowv1.NodeWsSend +} + +func (s *FlowServiceV2RPC) NodeWsSendCollection( + ctx context.Context, + _ *connect.Request[emptypb.Empty], +) (*connect.Response[flowv1.NodeWsSendCollectionResponse], error) { + flows, err := s.listAccessibleFlows(ctx) + if err != nil { + return nil, err + } + + var items []*flowv1.NodeWsSend + for _, flow := range flows { + nodes, err := s.nsReader.GetNodesByFlowID(ctx, flow.ID) + if err != nil && !errors.Is(err, sql.ErrNoRows) { + return nil, connect.NewError(connect.CodeInternal, err) + } + for _, node := range nodes { + if node.NodeKind != mflow.NODE_KIND_WS_SEND { + continue + } + nodeWsSend, err := s.nwss.GetNodeWsSend(ctx, node.ID) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + continue + } + return nil, connect.NewError(connect.CodeInternal, err) + } + if nodeWsSend == nil { + continue + } + items = append(items, serializeNodeWsSend(*nodeWsSend)) + } + } + + return connect.NewResponse(&flowv1.NodeWsSendCollectionResponse{Items: items}), nil +} + +func (s *FlowServiceV2RPC) NodeWsSendInsert( + ctx context.Context, + req *connect.Request[flowv1.NodeWsSendInsertRequest], +) (*connect.Response[emptypb.Empty], error) { + type insertData struct { + nodeID idwrap.IDWrap + wsConnectionNodeName string + message string + baseNode *mflow.Node + flowID idwrap.IDWrap + workspaceID idwrap.IDWrap + } + var validatedItems []insertData + + for _, item := range req.Msg.GetItems() { + nodeID, err := idwrap.NewFromBytes(item.GetNodeId()) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("invalid node id: %w", err)) + } + + baseNode, _ := s.ns.GetNode(ctx, nodeID) + + var flowID idwrap.IDWrap + var workspaceID idwrap.IDWrap + if baseNode != nil { + flowID = baseNode.FlowID + flow, err := s.fsReader.GetFlow(ctx, flowID) + if err == nil { + workspaceID = flow.WorkspaceID + } + } + + validatedItems = append(validatedItems, insertData{ + nodeID: nodeID, + wsConnectionNodeName: item.GetWsConnectionNodeName(), + message: item.GetMessage(), + baseNode: baseNode, + flowID: flowID, + workspaceID: workspaceID, + }) + } + + if len(validatedItems) == 0 { + return connect.NewResponse(&emptypb.Empty{}), nil + } + + mut := mutation.New(s.DB, mutation.WithPublisher(s.mutationPublisher())) + if err := mut.Begin(ctx); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + defer mut.Rollback() + + nwssWriter := s.nwss.TX(mut.TX()) + + for _, data := range validatedItems { + nodeWsSend := mflow.NodeWsSend{ + FlowNodeID: data.nodeID, + WsConnectionNodeName: data.wsConnectionNodeName, + Message: data.message, + } + + if err := nwssWriter.CreateNodeWsSend(ctx, nodeWsSend); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + if data.baseNode != nil { + mut.Track(mutation.Event{ + Entity: mutation.EntityFlowNodeWsSend, + Op: mutation.OpInsert, + ID: data.nodeID, + WorkspaceID: data.workspaceID, + ParentID: data.flowID, + Payload: nodeWsSendWithFlow{ + nodeWsSend: nodeWsSend, + flowID: data.flowID, + baseNode: data.baseNode, + }, + }) + } + } + + if err := mut.Commit(ctx); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + return connect.NewResponse(&emptypb.Empty{}), nil +} + +func (s *FlowServiceV2RPC) NodeWsSendUpdate( + ctx context.Context, + req *connect.Request[flowv1.NodeWsSendUpdateRequest], +) (*connect.Response[emptypb.Empty], error) { + type updateData struct { + nodeID idwrap.IDWrap + wsConnectionNodeName string + message string + baseNode *mflow.Node + workspaceID idwrap.IDWrap + } + var validatedItems []updateData + + for _, item := range req.Msg.GetItems() { + nodeID, err := idwrap.NewFromBytes(item.GetNodeId()) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("invalid node id: %w", err)) + } + + nodeModel, err := s.ensureNodeAccess(ctx, nodeID) + if err != nil { + return nil, err + } + + flow, err := s.fsReader.GetFlow(ctx, nodeModel.FlowID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + // Get existing values to merge partial updates + existing, err := s.nwss.GetNodeWsSend(ctx, nodeID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + wsConnName := existing.WsConnectionNodeName + if item.WsConnectionNodeName != nil { + wsConnName = *item.WsConnectionNodeName + } + msg := existing.Message + if item.Message != nil { + msg = *item.Message + } + + validatedItems = append(validatedItems, updateData{ + nodeID: nodeID, + wsConnectionNodeName: wsConnName, + message: msg, + baseNode: nodeModel, + workspaceID: flow.WorkspaceID, + }) + } + + if len(validatedItems) == 0 { + return connect.NewResponse(&emptypb.Empty{}), nil + } + + mut := mutation.New(s.DB, mutation.WithPublisher(s.mutationPublisher())) + if err := mut.Begin(ctx); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + defer mut.Rollback() + + nwssWriter := s.nwss.TX(mut.TX()) + + for _, data := range validatedItems { + nodeWsSend := mflow.NodeWsSend{ + FlowNodeID: data.nodeID, + WsConnectionNodeName: data.wsConnectionNodeName, + Message: data.message, + } + + if err := nwssWriter.UpdateNodeWsSend(ctx, nodeWsSend); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + mut.Track(mutation.Event{ + Entity: mutation.EntityFlowNodeWsSend, + Op: mutation.OpUpdate, + ID: data.nodeID, + WorkspaceID: data.workspaceID, + ParentID: data.baseNode.FlowID, + Payload: nodeWsSendWithFlow{ + nodeWsSend: nodeWsSend, + flowID: data.baseNode.FlowID, + baseNode: data.baseNode, + }, + }) + } + + if err := mut.Commit(ctx); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + return connect.NewResponse(&emptypb.Empty{}), nil +} + +func (s *FlowServiceV2RPC) NodeWsSendDelete( + ctx context.Context, + req *connect.Request[flowv1.NodeWsSendDeleteRequest], +) (*connect.Response[emptypb.Empty], error) { + type deleteData struct { + nodeID idwrap.IDWrap + flowID idwrap.IDWrap + } + var validatedItems []deleteData + + for _, item := range req.Msg.GetItems() { + nodeID, err := idwrap.NewFromBytes(item.GetNodeId()) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("invalid node id: %w", err)) + } + + nodeModel, err := s.ensureNodeAccess(ctx, nodeID) + if err != nil { + return nil, err + } + + validatedItems = append(validatedItems, deleteData{ + nodeID: nodeID, + flowID: nodeModel.FlowID, + }) + } + + if len(validatedItems) == 0 { + return connect.NewResponse(&emptypb.Empty{}), nil + } + + mut := mutation.New(s.DB, mutation.WithPublisher(s.mutationPublisher())) + if err := mut.Begin(ctx); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + defer mut.Rollback() + + for _, data := range validatedItems { + mut.Track(mutation.Event{ + Entity: mutation.EntityFlowNodeWsSend, + Op: mutation.OpDelete, + ID: data.nodeID, + ParentID: data.flowID, + }) + if err := mut.Queries().DeleteFlowNodeWsSend(ctx, data.nodeID); err != nil && !errors.Is(err, sql.ErrNoRows) { + return nil, connect.NewError(connect.CodeInternal, err) + } + } + + if err := mut.Commit(ctx); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + return connect.NewResponse(&emptypb.Empty{}), nil +} + +func (s *FlowServiceV2RPC) NodeWsSendSync( + ctx context.Context, + _ *connect.Request[emptypb.Empty], + stream *connect.ServerStream[flowv1.NodeWsSendSyncResponse], +) error { + if stream == nil { + return connect.NewError(connect.CodeInternal, errors.New("stream is required")) + } + return s.streamNodeWsSendSync(ctx, func(resp *flowv1.NodeWsSendSyncResponse) error { + return stream.Send(resp) + }) +} + +func (s *FlowServiceV2RPC) streamNodeWsSendSync( + ctx context.Context, + send func(*flowv1.NodeWsSendSyncResponse) error, +) error { + if s.nodeStream == nil { + return connect.NewError(connect.CodeUnavailable, errors.New("node stream not configured")) + } + + var flowSet sync.Map + + filter := func(topic NodeTopic) bool { + if _, ok := flowSet.Load(topic.FlowID.String()); ok { + return true + } + if err := s.ensureFlowAccess(ctx, topic.FlowID); err != nil { + return false + } + flowSet.Store(topic.FlowID.String(), struct{}{}) + return true + } + + events, err := s.nodeStream.Subscribe(ctx, filter) + if err != nil { + return connect.NewError(connect.CodeInternal, err) + } + + for { + select { + case evt, ok := <-events: + if !ok { + return nil + } + resp, err := s.nodeWsSendEventToSyncResponse(ctx, evt.Payload) + if err != nil { + return connect.NewError(connect.CodeInternal, fmt.Errorf("failed to convert WS send node event: %w", err)) + } + if resp == nil { + continue + } + if err := send(resp); err != nil { + return err + } + case <-ctx.Done(): + return ctx.Err() + } + } +} + +func (s *FlowServiceV2RPC) nodeWsSendEventToSyncResponse( + ctx context.Context, + evt NodeEvent, +) (*flowv1.NodeWsSendSyncResponse, error) { + if evt.Node == nil { + return nil, nil + } + + if evt.Node.GetKind() != flowv1.NodeKind_NODE_KIND_WS_SEND { + return nil, nil + } + + nodeID, err := idwrap.NewFromBytes(evt.Node.GetNodeId()) + if err != nil { + return nil, fmt.Errorf("invalid node id: %w", err) + } + + nodeWsSend, err := s.nwss.GetNodeWsSend(ctx, nodeID) + if err != nil && !errors.Is(err, sql.ErrNoRows) { + return nil, err + } + + var syncEvent *flowv1.NodeWsSendSync + switch evt.Type { + case nodeEventInsert: + insert := &flowv1.NodeWsSendSyncInsert{ + NodeId: nodeID.Bytes(), + } + if nodeWsSend != nil { + insert.WsConnectionNodeName = nodeWsSend.WsConnectionNodeName + insert.Message = nodeWsSend.Message + } + syncEvent = &flowv1.NodeWsSendSync{ + Value: &flowv1.NodeWsSendSync_ValueUnion{ + Kind: flowv1.NodeWsSendSync_ValueUnion_KIND_INSERT, + Insert: insert, + }, + } + case nodeEventUpdate: + update := &flowv1.NodeWsSendSyncUpdate{ + NodeId: nodeID.Bytes(), + } + if nodeWsSend != nil { + update.WsConnectionNodeName = &nodeWsSend.WsConnectionNodeName + update.Message = &nodeWsSend.Message + } + syncEvent = &flowv1.NodeWsSendSync{ + Value: &flowv1.NodeWsSendSync_ValueUnion{ + Kind: flowv1.NodeWsSendSync_ValueUnion_KIND_UPDATE, + Update: update, + }, + } + case nodeEventDelete: + syncEvent = &flowv1.NodeWsSendSync{ + Value: &flowv1.NodeWsSendSync_ValueUnion{ + Kind: flowv1.NodeWsSendSync_ValueUnion_KIND_DELETE, + Delete: &flowv1.NodeWsSendSyncDelete{ + NodeId: nodeID.Bytes(), + }, + }, + } + default: + return nil, nil + } + + return &flowv1.NodeWsSendSyncResponse{ + Items: []*flowv1.NodeWsSendSync{syncEvent}, + }, nil +} + +func serializeNodeWsSend(n mflow.NodeWsSend) *flowv1.NodeWsSend { + return &flowv1.NodeWsSend{ + NodeId: n.FlowNodeID.Bytes(), + WsConnectionNodeName: n.WsConnectionNodeName, + Message: n.Message, + } +} diff --git a/packages/server/internal/api/rflowv2/rflowv2_sync_zero_value_test.go b/packages/server/internal/api/rflowv2/rflowv2_sync_zero_value_test.go index 4e0efb777..e113ec1f9 100644 --- a/packages/server/internal/api/rflowv2/rflowv2_sync_zero_value_test.go +++ b/packages/server/internal/api/rflowv2/rflowv2_sync_zero_value_test.go @@ -654,6 +654,6 @@ func TestNodeHttp_DeleteConfig(t *testing.T) { // Wait for sync event evt, ok := waitForEvent(t, eventChan, 2*time.Second) require.True(t, ok, "Should receive sync event for NodeHttp delete") - assert.Equal(t, nodeEventUpdate, evt.Type) + assert.Equal(t, nodeEventDelete, evt.Type) }) } diff --git a/packages/server/internal/api/rflowv2/rflowv2_testutil_test.go b/packages/server/internal/api/rflowv2/rflowv2_testutil_test.go index a644cb5f9..8ad0571fc 100644 --- a/packages/server/internal/api/rflowv2/rflowv2_testutil_test.go +++ b/packages/server/internal/api/rflowv2/rflowv2_testutil_test.go @@ -14,6 +14,7 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/internal/api/middleware/mwauth" "github.com/the-dev-tools/dev-tools/packages/server/pkg/dbtime" "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/flowbuilder" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/flowexec" "github.com/the-dev-tools/dev-tools/packages/server/pkg/http/resolver" "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" @@ -92,6 +93,11 @@ func NewRFlowTestContext(t *testing.T) *RFlowTestContext { nil, // NodeAiProviderService - not needed for non-AI tests nil, // NodeMemoryService - not needed for non-AI tests nil, // NodeGraphQLService - not needed for non-GraphQL tests + nil, // NodeWsConnectionService - not needed for non-WS tests + nil, // NodeWsSendService - not needed for non-WS tests + nil, // NodeWaitService - not needed for non-wait tests + nil, // WebSocketService - not needed for non-WS tests + nil, // WebSocketHeaderService - not needed for non-WS tests nil, // GraphQLService - not needed for non-GraphQL tests nil, // GraphQLHeaderService - not needed for non-GraphQL tests &wsService, @@ -121,7 +127,7 @@ func NewRFlowTestContext(t *testing.T) *RFlowTestContext { nifs: nifsService, njss: &njssService, logger: logger, - builder: builder, + sessionFactory: &flowexec.LocalSessionFactory{Builder: builder}, } // Create User diff --git a/packages/server/internal/api/rflowv2/sync_robustness_test.go b/packages/server/internal/api/rflowv2/sync_robustness_test.go index 6d34bb671..5a43cda66 100644 --- a/packages/server/internal/api/rflowv2/sync_robustness_test.go +++ b/packages/server/internal/api/rflowv2/sync_robustness_test.go @@ -51,7 +51,7 @@ func TestSync_DeleteRobustness(t *testing.T) { // Should still receive an event because we publish it to trigger re-fetch events := collectNodeEvents(registry.nodeEvents, 1, 100*time.Millisecond) require.Len(t, events, 1) - assert.Equal(t, nodeEventUpdate, events[0].Type) + assert.Equal(t, nodeEventDelete, events[0].Type) }) t.Run("NodeJs Delete robustness", func(t *testing.T) { diff --git a/packages/server/internal/api/rgraphql/rgraphql.go b/packages/server/internal/api/rgraphql/rgraphql.go index 4de3ef65c..184e9288b 100644 --- a/packages/server/internal/api/rgraphql/rgraphql.go +++ b/packages/server/internal/api/rgraphql/rgraphql.go @@ -53,6 +53,7 @@ type GraphQLHeaderTopic struct { type GraphQLHeaderEvent struct { Type string GraphQLHeader *graphqlv1.GraphQLHeader + IsDelta bool } type GraphQLResponseTopic struct { @@ -333,6 +334,7 @@ func (p *rgraphqlPublisher) publishGraphQLHeader(evt mutation.Event) { } var model *graphqlv1.GraphQLHeader var eventType string + isDelta := false switch evt.Op { case mutation.OpInsert, mutation.OpUpdate: @@ -343,8 +345,10 @@ func (p *rgraphqlPublisher) publishGraphQLHeader(evt mutation.Event) { } if h, ok := evt.Payload.(mgraphql.GraphQLHeader); ok { model = ToAPIGraphQLHeader(h) + isDelta = h.IsDelta } else if hp, ok := evt.Payload.(*mgraphql.GraphQLHeader); ok { model = ToAPIGraphQLHeader(*hp) + isDelta = hp.IsDelta } case mutation.OpDelete: eventType = eventTypeDelete @@ -355,6 +359,7 @@ func (p *rgraphqlPublisher) publishGraphQLHeader(evt mutation.Event) { p.streamers.GraphQLHeader.Publish(GraphQLHeaderTopic{WorkspaceID: evt.WorkspaceID}, GraphQLHeaderEvent{ Type: eventType, GraphQLHeader: model, + IsDelta: isDelta, }) } } diff --git a/packages/server/internal/api/rgraphql/rgraphql_converter.go b/packages/server/internal/api/rgraphql/rgraphql_converter.go index f28287e0f..226d1a55f 100644 --- a/packages/server/internal/api/rgraphql/rgraphql_converter.go +++ b/packages/server/internal/api/rgraphql/rgraphql_converter.go @@ -8,6 +8,7 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mgraphql" graphqlv1 "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/api/graph_q_l/v1" + globalv1 "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/global/v1" ) // Model -> Proto @@ -288,6 +289,226 @@ func graphqlDeltaSyncResponseFrom(event GraphQLEvent) *graphqlv1.GraphQLDeltaSyn return nil } +func graphqlHeaderDeltaSyncResponseFrom(event GraphQLHeaderEvent, header mgraphql.GraphQLHeader) *graphqlv1.GraphQLHeaderDeltaSyncResponse { + var value *graphqlv1.GraphQLHeaderDeltaSync_ValueUnion + + switch event.Type { + case eventTypeInsert: + delta := &graphqlv1.GraphQLHeaderDeltaSyncInsert{ + DeltaGraphqlHeaderId: header.ID.Bytes(), + GraphqlId: header.GraphQLID.Bytes(), + } + if header.ParentGraphQLHeaderID != nil { + delta.GraphqlHeaderId = header.ParentGraphQLHeaderID.Bytes() + } + if header.DeltaKey != nil { + delta.Key = header.DeltaKey + } + if header.DeltaValue != nil { + delta.Value = header.DeltaValue + } + if header.DeltaEnabled != nil { + delta.Enabled = header.DeltaEnabled + } + if header.DeltaDescription != nil { + delta.Description = header.DeltaDescription + } + if header.DeltaDisplayOrder != nil { + delta.Order = header.DeltaDisplayOrder + } + value = &graphqlv1.GraphQLHeaderDeltaSync_ValueUnion{ + Kind: graphqlv1.GraphQLHeaderDeltaSync_ValueUnion_KIND_INSERT, + Insert: delta, + } + case eventTypeUpdate: + delta := &graphqlv1.GraphQLHeaderDeltaSyncUpdate{ + DeltaGraphqlHeaderId: header.ID.Bytes(), + GraphqlId: header.GraphQLID.Bytes(), + } + if header.ParentGraphQLHeaderID != nil { + delta.GraphqlHeaderId = header.ParentGraphQLHeaderID.Bytes() + } + if header.DeltaKey != nil { + keyStr := *header.DeltaKey + delta.Key = &graphqlv1.GraphQLHeaderDeltaSyncUpdate_KeyUnion{ + Kind: graphqlv1.GraphQLHeaderDeltaSyncUpdate_KeyUnion_KIND_VALUE, + Value: &keyStr, + } + } else { + delta.Key = &graphqlv1.GraphQLHeaderDeltaSyncUpdate_KeyUnion{ + Kind: graphqlv1.GraphQLHeaderDeltaSyncUpdate_KeyUnion_KIND_UNSET, + Unset: globalv1.Unset_UNSET.Enum(), + } + } + if header.DeltaValue != nil { + valueStr := *header.DeltaValue + delta.Value = &graphqlv1.GraphQLHeaderDeltaSyncUpdate_ValueUnion{ + Kind: graphqlv1.GraphQLHeaderDeltaSyncUpdate_ValueUnion_KIND_VALUE, + Value: &valueStr, + } + } else { + delta.Value = &graphqlv1.GraphQLHeaderDeltaSyncUpdate_ValueUnion{ + Kind: graphqlv1.GraphQLHeaderDeltaSyncUpdate_ValueUnion_KIND_UNSET, + Unset: globalv1.Unset_UNSET.Enum(), + } + } + if header.DeltaEnabled != nil { + enabledBool := *header.DeltaEnabled + delta.Enabled = &graphqlv1.GraphQLHeaderDeltaSyncUpdate_EnabledUnion{ + Kind: graphqlv1.GraphQLHeaderDeltaSyncUpdate_EnabledUnion_KIND_VALUE, + Value: &enabledBool, + } + } else { + delta.Enabled = &graphqlv1.GraphQLHeaderDeltaSyncUpdate_EnabledUnion{ + Kind: graphqlv1.GraphQLHeaderDeltaSyncUpdate_EnabledUnion_KIND_UNSET, + Unset: globalv1.Unset_UNSET.Enum(), + } + } + if header.DeltaDescription != nil { + descStr := *header.DeltaDescription + delta.Description = &graphqlv1.GraphQLHeaderDeltaSyncUpdate_DescriptionUnion{ + Kind: graphqlv1.GraphQLHeaderDeltaSyncUpdate_DescriptionUnion_KIND_VALUE, + Value: &descStr, + } + } else { + delta.Description = &graphqlv1.GraphQLHeaderDeltaSyncUpdate_DescriptionUnion{ + Kind: graphqlv1.GraphQLHeaderDeltaSyncUpdate_DescriptionUnion_KIND_UNSET, + Unset: globalv1.Unset_UNSET.Enum(), + } + } + if header.DeltaDisplayOrder != nil { + orderFloat := *header.DeltaDisplayOrder + delta.Order = &graphqlv1.GraphQLHeaderDeltaSyncUpdate_OrderUnion{ + Kind: graphqlv1.GraphQLHeaderDeltaSyncUpdate_OrderUnion_KIND_VALUE, + Value: &orderFloat, + } + } else { + delta.Order = &graphqlv1.GraphQLHeaderDeltaSyncUpdate_OrderUnion{ + Kind: graphqlv1.GraphQLHeaderDeltaSyncUpdate_OrderUnion_KIND_UNSET, + Unset: globalv1.Unset_UNSET.Enum(), + } + } + value = &graphqlv1.GraphQLHeaderDeltaSync_ValueUnion{ + Kind: graphqlv1.GraphQLHeaderDeltaSync_ValueUnion_KIND_UPDATE, + Update: delta, + } + case eventTypeDelete: + value = &graphqlv1.GraphQLHeaderDeltaSync_ValueUnion{ + Kind: graphqlv1.GraphQLHeaderDeltaSync_ValueUnion_KIND_DELETE, + Delete: &graphqlv1.GraphQLHeaderDeltaSyncDelete{ + DeltaGraphqlHeaderId: header.ID.Bytes(), + }, + } + } + + if value == nil { + return nil + } + + return &graphqlv1.GraphQLHeaderDeltaSyncResponse{ + Items: []*graphqlv1.GraphQLHeaderDeltaSync{ + { + Value: value, + }, + }, + } +} + +func graphqlAssertDeltaSyncResponseFrom(event GraphQLAssertEvent, assert mgraphql.GraphQLAssert) *graphqlv1.GraphQLAssertDeltaSyncResponse { + var value *graphqlv1.GraphQLAssertDeltaSync_ValueUnion + + switch event.Type { + case eventTypeInsert: + delta := &graphqlv1.GraphQLAssertDeltaSyncInsert{ + DeltaGraphqlAssertId: assert.ID.Bytes(), + GraphqlId: assert.GraphQLID.Bytes(), + } + if assert.ParentGraphQLAssertID != nil { + delta.GraphqlAssertId = assert.ParentGraphQLAssertID.Bytes() + } + if assert.DeltaValue != nil { + delta.Value = assert.DeltaValue + } + if assert.DeltaEnabled != nil { + delta.Enabled = assert.DeltaEnabled + } + if assert.DeltaDisplayOrder != nil { + delta.Order = assert.DeltaDisplayOrder + } + value = &graphqlv1.GraphQLAssertDeltaSync_ValueUnion{ + Kind: graphqlv1.GraphQLAssertDeltaSync_ValueUnion_KIND_INSERT, + Insert: delta, + } + case eventTypeUpdate: + delta := &graphqlv1.GraphQLAssertDeltaSyncUpdate{ + DeltaGraphqlAssertId: assert.ID.Bytes(), + GraphqlId: assert.GraphQLID.Bytes(), + } + if assert.ParentGraphQLAssertID != nil { + delta.GraphqlAssertId = assert.ParentGraphQLAssertID.Bytes() + } + if assert.DeltaValue != nil { + valueStr := *assert.DeltaValue + delta.Value = &graphqlv1.GraphQLAssertDeltaSyncUpdate_ValueUnion{ + Kind: graphqlv1.GraphQLAssertDeltaSyncUpdate_ValueUnion_KIND_VALUE, + Value: &valueStr, + } + } else { + delta.Value = &graphqlv1.GraphQLAssertDeltaSyncUpdate_ValueUnion{ + Kind: graphqlv1.GraphQLAssertDeltaSyncUpdate_ValueUnion_KIND_UNSET, + Unset: globalv1.Unset_UNSET.Enum(), + } + } + if assert.DeltaEnabled != nil { + enabledBool := *assert.DeltaEnabled + delta.Enabled = &graphqlv1.GraphQLAssertDeltaSyncUpdate_EnabledUnion{ + Kind: graphqlv1.GraphQLAssertDeltaSyncUpdate_EnabledUnion_KIND_VALUE, + Value: &enabledBool, + } + } else { + delta.Enabled = &graphqlv1.GraphQLAssertDeltaSyncUpdate_EnabledUnion{ + Kind: graphqlv1.GraphQLAssertDeltaSyncUpdate_EnabledUnion_KIND_UNSET, + Unset: globalv1.Unset_UNSET.Enum(), + } + } + if assert.DeltaDisplayOrder != nil { + orderFloat := *assert.DeltaDisplayOrder + delta.Order = &graphqlv1.GraphQLAssertDeltaSyncUpdate_OrderUnion{ + Kind: graphqlv1.GraphQLAssertDeltaSyncUpdate_OrderUnion_KIND_VALUE, + Value: &orderFloat, + } + } else { + delta.Order = &graphqlv1.GraphQLAssertDeltaSyncUpdate_OrderUnion{ + Kind: graphqlv1.GraphQLAssertDeltaSyncUpdate_OrderUnion_KIND_UNSET, + Unset: globalv1.Unset_UNSET.Enum(), + } + } + value = &graphqlv1.GraphQLAssertDeltaSync_ValueUnion{ + Kind: graphqlv1.GraphQLAssertDeltaSync_ValueUnion_KIND_UPDATE, + Update: delta, + } + case eventTypeDelete: + value = &graphqlv1.GraphQLAssertDeltaSync_ValueUnion{ + Kind: graphqlv1.GraphQLAssertDeltaSync_ValueUnion_KIND_DELETE, + Delete: &graphqlv1.GraphQLAssertDeltaSyncDelete{ + DeltaGraphqlAssertId: assert.ID.Bytes(), + }, + } + } + + if value == nil { + return nil + } + + return &graphqlv1.GraphQLAssertDeltaSyncResponse{ + Items: []*graphqlv1.GraphQLAssertDeltaSync{ + { + Value: value, + }, + }, + } +} + // graphqlAssertSyncResponseFrom converts GraphQLAssertEvent to GraphQLAssertSync response func graphqlAssertSyncResponseFrom(event GraphQLAssertEvent) *graphqlv1.GraphQLAssertSyncResponse { var value *graphqlv1.GraphQLAssertSync_ValueUnion diff --git a/packages/server/internal/api/rgraphql/rgraphql_crud_assert.go b/packages/server/internal/api/rgraphql/rgraphql_crud_assert.go index 746bf4097..118fc452b 100644 --- a/packages/server/internal/api/rgraphql/rgraphql_crud_assert.go +++ b/packages/server/internal/api/rgraphql/rgraphql_crud_assert.go @@ -830,8 +830,62 @@ func (s *GraphQLServiceRPC) GraphQLAssertDeltaDelete(ctx context.Context, req *c } func (s *GraphQLServiceRPC) GraphQLAssertDeltaSync(ctx context.Context, req *connect.Request[emptypb.Empty], stream *connect.ServerStream[graphqlv1.GraphQLAssertDeltaSyncResponse]) error { - // TODO: Implement streaming delta sync - return nil + userID, err := mwauth.GetContextUserID(ctx) + if err != nil { + return connect.NewError(connect.CodeUnauthenticated, err) + } + + return s.streamGraphQLAssertDeltaSync(ctx, userID, stream.Send) +} + +func (s *GraphQLServiceRPC) streamGraphQLAssertDeltaSync(ctx context.Context, userID idwrap.IDWrap, send func(*graphqlv1.GraphQLAssertDeltaSyncResponse) error) error { + var workspaceSet sync.Map + + filter := func(topic GraphQLAssertTopic) bool { + if _, ok := workspaceSet.Load(topic.WorkspaceID.String()); ok { + return true + } + belongs, err := s.us.CheckUserBelongsToWorkspace(ctx, userID, topic.WorkspaceID) + if err != nil || !belongs { + return false + } + workspaceSet.Store(topic.WorkspaceID.String(), struct{}{}) + return true + } + + events, err := s.streamers.GraphQLAssert.Subscribe(ctx, filter) + if err != nil { + return connect.NewError(connect.CodeInternal, err) + } + + for { + select { + case evt, ok := <-events: + if !ok { + return nil + } + if !evt.Payload.IsDelta { + continue + } + assertID, err := idwrap.NewFromBytes(evt.Payload.GraphQLAssert.GetGraphqlAssertId()) + if err != nil { + continue + } + assertRecord, err := s.graphqlAssertService.GetByID(ctx, assertID) + if err != nil { + continue + } + resp := graphqlAssertDeltaSyncResponseFrom(evt.Payload, *assertRecord) + if resp == nil { + continue + } + if err := send(resp); err != nil { + return err + } + case <-ctx.Done(): + return ctx.Err() + } + } } // Helper functions for null conversions diff --git a/packages/server/internal/api/rgraphql/rgraphql_crud_header_delta.go b/packages/server/internal/api/rgraphql/rgraphql_crud_header_delta.go index 5789f81c3..2271dbf53 100644 --- a/packages/server/internal/api/rgraphql/rgraphql_crud_header_delta.go +++ b/packages/server/internal/api/rgraphql/rgraphql_crud_header_delta.go @@ -4,6 +4,7 @@ package rgraphql import ( "context" "errors" + "sync" "connectrpc.com/connect" "google.golang.org/protobuf/types/known/emptypb" @@ -335,9 +336,60 @@ func (s *GraphQLServiceRPC) GraphQLHeaderDeltaDelete(ctx context.Context, req *c // GraphQLHeaderDeltaSync streams delta header changes to the client func (s *GraphQLServiceRPC) GraphQLHeaderDeltaSync(ctx context.Context, req *connect.Request[emptypb.Empty], stream *connect.ServerStream[graphqlv1.GraphQLHeaderDeltaSyncResponse]) error { - // TODO: Implement streaming delta sync with proper event filtering - // Similar to GraphQLDeltaSync, this requires a delta-specific event stream - // that only publishes delta-related changes to prevent flooding clients - // with non-delta header updates. - return nil + userID, err := mwauth.GetContextUserID(ctx) + if err != nil { + return connect.NewError(connect.CodeUnauthenticated, err) + } + + return s.streamGraphQLHeaderDeltaSync(ctx, userID, stream.Send) +} + +func (s *GraphQLServiceRPC) streamGraphQLHeaderDeltaSync(ctx context.Context, userID idwrap.IDWrap, send func(*graphqlv1.GraphQLHeaderDeltaSyncResponse) error) error { + var workspaceSet sync.Map + + filter := func(topic GraphQLHeaderTopic) bool { + if _, ok := workspaceSet.Load(topic.WorkspaceID.String()); ok { + return true + } + belongs, err := s.us.CheckUserBelongsToWorkspace(ctx, userID, topic.WorkspaceID) + if err != nil || !belongs { + return false + } + workspaceSet.Store(topic.WorkspaceID.String(), struct{}{}) + return true + } + + events, err := s.streamers.GraphQLHeader.Subscribe(ctx, filter) + if err != nil { + return connect.NewError(connect.CodeInternal, err) + } + + for { + select { + case evt, ok := <-events: + if !ok { + return nil + } + headerID, err := idwrap.NewFromBytes(evt.Payload.GraphQLHeader.GetGraphqlHeaderId()) + if err != nil { + continue + } + headerRecord, err := s.headerService.GetByID(ctx, headerID) + if err != nil { + continue + } + if !headerRecord.IsDelta { + continue + } + resp := graphqlHeaderDeltaSyncResponseFrom(evt.Payload, *headerRecord) + if resp == nil { + continue + } + if err := send(resp); err != nil { + return err + } + case <-ctx.Done(): + return ctx.Err() + } + } } diff --git a/packages/server/internal/api/rimportv2/integration_test.go b/packages/server/internal/api/rimportv2/integration_test.go index 0d6dd678f..461ad2133 100644 --- a/packages/server/internal/api/rimportv2/integration_test.go +++ b/packages/server/internal/api/rimportv2/integration_test.go @@ -1788,6 +1788,7 @@ flows: require.NotEmpty(t, forEachNode.IterExpression, "ForEach node should have items expression for node %s", node.Name) t.Logf(" ForEach Node: Items=%q", forEachNode.IterExpression) forEachNodesFound++ + default: } } @@ -1976,6 +1977,7 @@ flows: if fe != nil { gotForEach++ } + default: } } diff --git a/packages/server/internal/api/rimportv2/integrity.go b/packages/server/internal/api/rimportv2/integrity.go index c8eb60224..4b39052af 100644 --- a/packages/server/internal/api/rimportv2/integrity.go +++ b/packages/server/internal/api/rimportv2/integrity.go @@ -108,6 +108,9 @@ func ValidateImportIntegrity( case mfile.ContentTypeGraphQL: // GraphQL files reference GraphQL IDs - validation not yet implemented continue + case mfile.ContentTypeWebSocket: + // WebSocket files reference WebSocket IDs - validation not yet implemented + continue case mfile.ContentTypeFlow, mfile.ContentTypeFolder, mfile.ContentTypeCredential: // Flow files reference flow IDs - we could validate these too // Folders don't have ContentID @@ -178,6 +181,9 @@ func ValidateTranslationResult(result *TranslationResult) *IntegrityReport { case mfile.ContentTypeGraphQL: // GraphQL files reference GraphQL IDs - validation not yet implemented continue + case mfile.ContentTypeWebSocket: + // WebSocket files reference WebSocket IDs - validation not yet implemented + continue case mfile.ContentTypeFlow, mfile.ContentTypeFolder, mfile.ContentTypeCredential: continue } diff --git a/packages/server/internal/api/rimportv2/rimportv2_event.go b/packages/server/internal/api/rimportv2/rimportv2_event.go index ced5dbc86..9b6ca468a 100644 --- a/packages/server/internal/api/rimportv2/rimportv2_event.go +++ b/packages/server/internal/api/rimportv2/rimportv2_event.go @@ -74,7 +74,7 @@ func (h *ImportV2RPC) publishEvents(ctx context.Context, results *ImportResults) kind = eventsync.KindFlowFile case mfile.ContentTypeFolder: kind = eventsync.KindFolder - case mfile.ContentTypeHTTP, mfile.ContentTypeHTTPDelta, mfile.ContentTypeCredential, mfile.ContentTypeGraphQL: + case mfile.ContentTypeHTTP, mfile.ContentTypeHTTPDelta, mfile.ContentTypeCredential, mfile.ContentTypeGraphQL, mfile.ContentTypeWebSocket: // Keep default KindHTTPFile } diff --git a/packages/server/internal/api/rreference/rreference.go b/packages/server/internal/api/rreference/rreference.go index 4f0ad9fe0..08ec536d1 100644 --- a/packages/server/internal/api/rreference/rreference.go +++ b/packages/server/internal/api/rreference/rreference.go @@ -563,8 +563,9 @@ func (c *ReferenceServiceRPC) HandleNode(ctx context.Context, nodeID idwrap.IDWr if err := appendNodeRef(nodeVarRef, fmt.Sprintf("node %q request schema", node.Name)); err != nil { return nil, connect.NewError(connect.CodeInternal, err) } + default: + // Other node types (JS, CONDITION, etc.) don't have default schemas } - // Other node types (JS, CONDITION, etc.) don't have default schemas } return nodeRefs, nil @@ -860,6 +861,8 @@ func (c *ReferenceServiceRPC) ReferenceCompletion(ctx context.Context, req *conn "metrics": map[string]interface{}{}, } creator.AddWithKey(node.Name, nodeVarsMap) + default: + // Other node types don't have default schemas for completion } } @@ -1014,6 +1017,8 @@ func (c *ReferenceServiceRPC) ReferenceCompletion(ctx context.Context, req *conn "duration": 0, }) } + default: + // Other node types don't have self-reference schemas } } } @@ -1297,8 +1302,9 @@ func (c *ReferenceServiceRPC) ReferenceValue(ctx context.Context, req *connect.R }, } lookup.AddWithKey(node.Name, nodeVarsMap) + default: + // Other node types (JS, CONDITION, etc.) don't have default schemas } - // Other node types (JS, CONDITION, etc.) don't have default schemas } // Add self-reference for REQUEST, FOR, and FOREACH nodes so they can reference their own variables @@ -1412,6 +1418,8 @@ func (c *ReferenceServiceRPC) ReferenceValue(ctx context.Context, req *connect.R "duration": 0, }) } + default: + // Other node types don't have self-reference schemas } } } diff --git a/packages/server/internal/api/rwebsocket/rwebsocket.go b/packages/server/internal/api/rwebsocket/rwebsocket.go new file mode 100644 index 000000000..7c8eae00f --- /dev/null +++ b/packages/server/internal/api/rwebsocket/rwebsocket.go @@ -0,0 +1,790 @@ +package rwebsocket + +import ( + "context" + "database/sql" + "errors" + "sync" + "time" + + "connectrpc.com/connect" + "google.golang.org/protobuf/types/known/emptypb" + + devtoolsdb "github.com/the-dev-tools/dev-tools/packages/db" + "github.com/the-dev-tools/dev-tools/packages/server/internal/api" + "github.com/the-dev-tools/dev-tools/packages/server/internal/api/middleware/mwauth" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/eventstream" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mwebsocket" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/permcheck" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/suser" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/swebsocket" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sworkspace" + apiv1 "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/api/web_socket/v1" + "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/api/web_socket/v1/web_socketv1connect" +) + +const ( + eventTypeInsert = "insert" + eventTypeUpdate = "update" + eventTypeDelete = "delete" +) + +type WebSocketTopic struct { + WorkspaceID idwrap.IDWrap +} + +type WebSocketEvent struct { + Type string + WebSocket *apiv1.WebSocket +} + +type WebSocketHeaderTopic struct { + WorkspaceID idwrap.IDWrap +} + +type WebSocketHeaderEvent struct { + Type string + WebSocketHeader *apiv1.WebSocketHeader +} + +// WebSocketRPC handles WebSocket CRUD operations and real-time sync. +type WebSocketRPC struct { + web_socketv1connect.UnimplementedWebSocketServiceHandler + + DB *sql.DB + ws swebsocket.WebSocketService + wsh swebsocket.WebSocketHeaderService + us suser.UserService + wk sworkspace.WorkspaceService + wsStream eventstream.SyncStreamer[WebSocketTopic, WebSocketEvent] + wshStream eventstream.SyncStreamer[WebSocketHeaderTopic, WebSocketHeaderEvent] +} + +type Deps struct { + DB *sql.DB + WS swebsocket.WebSocketService + WSH swebsocket.WebSocketHeaderService + US suser.UserService + Workspace sworkspace.WorkspaceService + WSStream eventstream.SyncStreamer[WebSocketTopic, WebSocketEvent] + WSHStream eventstream.SyncStreamer[WebSocketHeaderTopic, WebSocketHeaderEvent] +} + +func New(deps Deps) WebSocketRPC { + return WebSocketRPC{ + DB: deps.DB, + ws: deps.WS, + wsh: deps.WSH, + us: deps.US, + wk: deps.Workspace, + wsStream: deps.WSStream, + wshStream: deps.WSHStream, + } +} + +func CreateService(srv WebSocketRPC, options []connect.HandlerOption) (*api.Service, error) { + path, handler := web_socketv1connect.NewWebSocketServiceHandler(&srv, options...) + return &api.Service{Path: path, Handler: handler}, nil +} + +func (s *WebSocketRPC) WebSocketCollection(ctx context.Context, _ *connect.Request[emptypb.Empty]) (*connect.Response[apiv1.WebSocketCollectionResponse], error) { + userID, err := mwauth.GetContextUserID(ctx) + if err != nil { + return nil, connect.NewError(connect.CodeUnauthenticated, err) + } + + workspaces, err := s.wk.GetWorkspacesByUserIDOrdered(ctx, userID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + var items []*apiv1.WebSocket + for _, workspace := range workspaces { + wsList, err := s.ws.GetByWorkspaceID(ctx, workspace.ID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + for _, ws := range wsList { + items = append(items, &apiv1.WebSocket{ + WebsocketId: ws.ID.Bytes(), + Name: ws.Name, + Url: ws.Url, + }) + } + } + + return connect.NewResponse(&apiv1.WebSocketCollectionResponse{Items: items}), nil +} + +func (s *WebSocketRPC) WebSocketSync(ctx context.Context, _ *connect.Request[emptypb.Empty], stream *connect.ServerStream[apiv1.WebSocketSyncResponse]) error { + userID, err := mwauth.GetContextUserID(ctx) + if err != nil { + return connect.NewError(connect.CodeUnauthenticated, err) + } + + var workspaceSet sync.Map + filter := func(topic WebSocketTopic) bool { + if _, ok := workspaceSet.Load(topic.WorkspaceID.String()); ok { + return true + } + belongs, err := s.us.CheckUserBelongsToWorkspace(ctx, userID, topic.WorkspaceID) + if err != nil || !belongs { + return false + } + workspaceSet.Store(topic.WorkspaceID.String(), struct{}{}) + return true + } + + events, err := s.wsStream.Subscribe(ctx, filter) + if err != nil { + return connect.NewError(connect.CodeInternal, err) + } + + for { + select { + case evt, ok := <-events: + if !ok { + return nil + } + resp := webSocketSyncResponseFrom(evt.Payload) + if resp == nil { + continue + } + if err := stream.Send(resp); err != nil { + return err + } + case <-ctx.Done(): + return ctx.Err() + } + } +} + +func (s *WebSocketRPC) WebSocketHeaderCollection(ctx context.Context, _ *connect.Request[emptypb.Empty]) (*connect.Response[apiv1.WebSocketHeaderCollectionResponse], error) { + userID, err := mwauth.GetContextUserID(ctx) + if err != nil { + return nil, connect.NewError(connect.CodeUnauthenticated, err) + } + + workspaces, err := s.wk.GetWorkspacesByUserIDOrdered(ctx, userID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + var items []*apiv1.WebSocketHeader + for _, workspace := range workspaces { + wsList, err := s.ws.GetByWorkspaceID(ctx, workspace.ID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + for _, ws := range wsList { + headers, err := s.wsh.GetByWebSocketID(ctx, ws.ID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + for _, h := range headers { + items = append(items, toAPIWebSocketHeader(h)) + } + } + } + + return connect.NewResponse(&apiv1.WebSocketHeaderCollectionResponse{Items: items}), nil +} + +func (s *WebSocketRPC) WebSocketHeaderSync(ctx context.Context, _ *connect.Request[emptypb.Empty], stream *connect.ServerStream[apiv1.WebSocketHeaderSyncResponse]) error { + userID, err := mwauth.GetContextUserID(ctx) + if err != nil { + return connect.NewError(connect.CodeUnauthenticated, err) + } + + var workspaceSet sync.Map + filter := func(topic WebSocketHeaderTopic) bool { + if _, ok := workspaceSet.Load(topic.WorkspaceID.String()); ok { + return true + } + belongs, err := s.us.CheckUserBelongsToWorkspace(ctx, userID, topic.WorkspaceID) + if err != nil || !belongs { + return false + } + workspaceSet.Store(topic.WorkspaceID.String(), struct{}{}) + return true + } + + events, err := s.wshStream.Subscribe(ctx, filter) + if err != nil { + return connect.NewError(connect.CodeInternal, err) + } + + for { + select { + case evt, ok := <-events: + if !ok { + return nil + } + resp := webSocketHeaderSyncResponseFrom(evt.Payload) + if resp == nil { + continue + } + if err := stream.Send(resp); err != nil { + return err + } + case <-ctx.Done(): + return ctx.Err() + } + } +} + +func (s *WebSocketRPC) WebSocketInsert(ctx context.Context, req *connect.Request[apiv1.WebSocketInsertRequest]) (*connect.Response[emptypb.Empty], error) { + if len(req.Msg.GetItems()) == 0 { + return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("at least one item must be provided")) + } + + // FETCH + userID, err := mwauth.GetContextUserID(ctx) + if err != nil { + return nil, connect.NewError(connect.CodeUnauthenticated, err) + } + + workspaces, err := s.wk.GetWorkspacesByUserIDOrdered(ctx, userID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + if len(workspaces) == 0 { + return nil, connect.NewError(connect.CodeNotFound, errors.New("user has no workspaces")) + } + defaultWorkspaceID := workspaces[0].ID + + // CHECK + rpcErr := permcheck.CheckPerm(mwauth.CheckOwnerWorkspace(ctx, s.us, defaultWorkspaceID)) + if rpcErr != nil { + return nil, rpcErr + } + + // Parse items + now := time.Now().Unix() + items := make([]mwebsocket.WebSocket, 0, len(req.Msg.Items)) + for _, item := range req.Msg.Items { + if len(item.GetWebsocketId()) == 0 { + return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("websocket_id is required")) + } + wsID, err := idwrap.NewFromBytes(item.GetWebsocketId()) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, err) + } + items = append(items, mwebsocket.WebSocket{ + ID: wsID, + WorkspaceID: defaultWorkspaceID, + Name: item.GetName(), + Url: item.GetUrl(), + CreatedAt: now, + UpdatedAt: now, + }) + } + + // ACT + tx, err := s.DB.BeginTx(ctx, nil) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + defer devtoolsdb.TxnRollback(tx) + + wsTx := s.ws.TX(tx) + for i := range items { + if err := wsTx.Create(ctx, &items[i]); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + } + + if err := tx.Commit(); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + for _, item := range items { + s.wsStream.Publish(WebSocketTopic{WorkspaceID: item.WorkspaceID}, WebSocketEvent{ + Type: eventTypeInsert, + WebSocket: &apiv1.WebSocket{ + WebsocketId: item.ID.Bytes(), + Name: item.Name, + Url: item.Url, + }, + }) + } + + return connect.NewResponse(&emptypb.Empty{}), nil +} + +func (s *WebSocketRPC) WebSocketUpdate(ctx context.Context, req *connect.Request[apiv1.WebSocketUpdateRequest]) (*connect.Response[emptypb.Empty], error) { + if len(req.Msg.GetItems()) == 0 { + return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("at least one item must be provided")) + } + + // FETCH + CHECK + updates := make([]mwebsocket.WebSocket, 0, len(req.Msg.Items)) + for _, item := range req.Msg.Items { + if len(item.GetWebsocketId()) == 0 { + return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("websocket_id is required")) + } + wsID, err := idwrap.NewFromBytes(item.GetWebsocketId()) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, err) + } + + existing, err := s.ws.Get(ctx, wsID) + if err != nil { + if errors.Is(err, swebsocket.ErrNoWebSocketFound) { + return nil, connect.NewError(connect.CodeNotFound, err) + } + return nil, connect.NewError(connect.CodeInternal, err) + } + + rpcErr := permcheck.CheckPerm(mwauth.CheckOwnerWorkspace(ctx, s.us, existing.WorkspaceID)) + if rpcErr != nil { + return nil, rpcErr + } + + // Apply partial updates + if item.Name != nil { + existing.Name = *item.Name + } + if item.Url != nil { + existing.Url = *item.Url + } + existing.UpdatedAt = time.Now().Unix() + + updates = append(updates, *existing) + } + + // ACT + tx, err := s.DB.BeginTx(ctx, nil) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + defer devtoolsdb.TxnRollback(tx) + + wsTx := s.ws.TX(tx) + for i := range updates { + if err := wsTx.Update(ctx, &updates[i]); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + } + + if err := tx.Commit(); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + for _, item := range updates { + s.wsStream.Publish(WebSocketTopic{WorkspaceID: item.WorkspaceID}, WebSocketEvent{ + Type: eventTypeUpdate, + WebSocket: &apiv1.WebSocket{ + WebsocketId: item.ID.Bytes(), + Name: item.Name, + Url: item.Url, + }, + }) + } + + return connect.NewResponse(&emptypb.Empty{}), nil +} + +func (s *WebSocketRPC) WebSocketDelete(ctx context.Context, req *connect.Request[apiv1.WebSocketDeleteRequest]) (*connect.Response[emptypb.Empty], error) { + if len(req.Msg.GetItems()) == 0 { + return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("at least one item must be provided")) + } + + // FETCH + CHECK + type deleteItem struct { + ID idwrap.IDWrap + WorkspaceID idwrap.IDWrap + } + deleteItems := make([]deleteItem, 0, len(req.Msg.Items)) + for _, item := range req.Msg.Items { + if len(item.GetWebsocketId()) == 0 { + return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("websocket_id is required")) + } + wsID, err := idwrap.NewFromBytes(item.GetWebsocketId()) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, err) + } + + workspaceID, err := s.ws.GetWorkspaceID(ctx, wsID) + if err != nil { + if errors.Is(err, swebsocket.ErrNoWebSocketFound) { + return nil, connect.NewError(connect.CodeNotFound, err) + } + return nil, connect.NewError(connect.CodeInternal, err) + } + + rpcErr := permcheck.CheckPerm(mwauth.CheckOwnerWorkspace(ctx, s.us, workspaceID)) + if rpcErr != nil { + return nil, rpcErr + } + + deleteItems = append(deleteItems, deleteItem{ID: wsID, WorkspaceID: workspaceID}) + } + + // ACT + tx, err := s.DB.BeginTx(ctx, nil) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + defer devtoolsdb.TxnRollback(tx) + + wsTx := s.ws.TX(tx) + for _, item := range deleteItems { + if err := wsTx.Delete(ctx, item.ID); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + } + + if err := tx.Commit(); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + for _, item := range deleteItems { + s.wsStream.Publish(WebSocketTopic{WorkspaceID: item.WorkspaceID}, WebSocketEvent{ + Type: eventTypeDelete, + WebSocket: &apiv1.WebSocket{ + WebsocketId: item.ID.Bytes(), + }, + }) + } + + return connect.NewResponse(&emptypb.Empty{}), nil +} + +func (s *WebSocketRPC) WebSocketHeaderInsert(ctx context.Context, req *connect.Request[apiv1.WebSocketHeaderInsertRequest]) (*connect.Response[emptypb.Empty], error) { + if len(req.Msg.GetItems()) == 0 { + return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("at least one item must be provided")) + } + + // FETCH + CHECK + items := make([]mwebsocket.WebSocketHeader, 0, len(req.Msg.Items)) + workspaceIDs := make([]idwrap.IDWrap, 0, len(req.Msg.Items)) + now := time.Now().Unix() + for _, item := range req.Msg.Items { + if len(item.GetWebsocketHeaderId()) == 0 { + return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("websocket_header_id is required")) + } + headerID, err := idwrap.NewFromBytes(item.GetWebsocketHeaderId()) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, err) + } + if len(item.GetWebsocketId()) == 0 { + return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("websocket_id is required")) + } + wsID, err := idwrap.NewFromBytes(item.GetWebsocketId()) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, err) + } + + workspaceID, err := s.ws.GetWorkspaceID(ctx, wsID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + rpcErr := permcheck.CheckPerm(mwauth.CheckOwnerWorkspace(ctx, s.us, workspaceID)) + if rpcErr != nil { + return nil, rpcErr + } + + items = append(items, mwebsocket.WebSocketHeader{ + ID: headerID, + WebSocketID: wsID, + Key: item.GetKey(), + Value: item.GetValue(), + Enabled: item.GetEnabled(), + Description: item.GetDescription(), + DisplayOrder: item.GetOrder(), + CreatedAt: now, + UpdatedAt: now, + }) + workspaceIDs = append(workspaceIDs, workspaceID) + } + + // ACT + tx, err := s.DB.BeginTx(ctx, nil) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + defer devtoolsdb.TxnRollback(tx) + + wshTx := s.wsh.TX(tx) + for _, h := range items { + if err := wshTx.Create(ctx, h); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + } + + if err := tx.Commit(); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + for i, h := range items { + s.wshStream.Publish(WebSocketHeaderTopic{WorkspaceID: workspaceIDs[i]}, WebSocketHeaderEvent{ + Type: eventTypeInsert, + WebSocketHeader: toAPIWebSocketHeader(h), + }) + } + + return connect.NewResponse(&emptypb.Empty{}), nil +} + +func (s *WebSocketRPC) WebSocketHeaderUpdate(ctx context.Context, req *connect.Request[apiv1.WebSocketHeaderUpdateRequest]) (*connect.Response[emptypb.Empty], error) { + if len(req.Msg.GetItems()) == 0 { + return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("at least one item must be provided")) + } + + // FETCH + CHECK + updates := make([]mwebsocket.WebSocketHeader, 0, len(req.Msg.Items)) + updateWorkspaceIDs := make([]idwrap.IDWrap, 0, len(req.Msg.Items)) + for _, item := range req.Msg.Items { + if len(item.GetWebsocketHeaderId()) == 0 { + return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("websocket_header_id is required")) + } + headerID, err := idwrap.NewFromBytes(item.GetWebsocketHeaderId()) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, err) + } + + existing, err := s.wsh.GetByID(ctx, headerID) + if err != nil { + return nil, connect.NewError(connect.CodeNotFound, err) + } + + workspaceID, err := s.ws.GetWorkspaceID(ctx, existing.WebSocketID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + rpcErr := permcheck.CheckPerm(mwauth.CheckOwnerWorkspace(ctx, s.us, workspaceID)) + if rpcErr != nil { + return nil, rpcErr + } + + if item.Key != nil { + existing.Key = *item.Key + } + if item.Value != nil { + existing.Value = *item.Value + } + if item.Enabled != nil { + existing.Enabled = *item.Enabled + } + if item.Description != nil { + existing.Description = *item.Description + } + if item.Order != nil { + existing.DisplayOrder = *item.Order + } + existing.UpdatedAt = time.Now().Unix() + + updates = append(updates, existing) + updateWorkspaceIDs = append(updateWorkspaceIDs, workspaceID) + } + + // ACT + tx, err := s.DB.BeginTx(ctx, nil) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + defer devtoolsdb.TxnRollback(tx) + + wshTx := s.wsh.TX(tx) + for _, h := range updates { + if err := wshTx.Update(ctx, h); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + } + + if err := tx.Commit(); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + for i, h := range updates { + s.wshStream.Publish(WebSocketHeaderTopic{WorkspaceID: updateWorkspaceIDs[i]}, WebSocketHeaderEvent{ + Type: eventTypeUpdate, + WebSocketHeader: toAPIWebSocketHeader(h), + }) + } + + return connect.NewResponse(&emptypb.Empty{}), nil +} + +func (s *WebSocketRPC) WebSocketHeaderDelete(ctx context.Context, req *connect.Request[apiv1.WebSocketHeaderDeleteRequest]) (*connect.Response[emptypb.Empty], error) { + if len(req.Msg.GetItems()) == 0 { + return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("at least one item must be provided")) + } + + // FETCH + CHECK + type headerDeleteItem struct { + ID idwrap.IDWrap + WorkspaceID idwrap.IDWrap + } + headerDeleteItems := make([]headerDeleteItem, 0, len(req.Msg.Items)) + for _, item := range req.Msg.Items { + if len(item.GetWebsocketHeaderId()) == 0 { + return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("websocket_header_id is required")) + } + headerID, err := idwrap.NewFromBytes(item.GetWebsocketHeaderId()) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, err) + } + + existing, err := s.wsh.GetByID(ctx, headerID) + if err != nil { + return nil, connect.NewError(connect.CodeNotFound, err) + } + + workspaceID, err := s.ws.GetWorkspaceID(ctx, existing.WebSocketID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + rpcErr := permcheck.CheckPerm(mwauth.CheckOwnerWorkspace(ctx, s.us, workspaceID)) + if rpcErr != nil { + return nil, rpcErr + } + + headerDeleteItems = append(headerDeleteItems, headerDeleteItem{ID: headerID, WorkspaceID: workspaceID}) + } + + // ACT + tx, err := s.DB.BeginTx(ctx, nil) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + defer devtoolsdb.TxnRollback(tx) + + wshTx := s.wsh.TX(tx) + for _, item := range headerDeleteItems { + if err := wshTx.Delete(ctx, item.ID); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + } + + if err := tx.Commit(); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + for _, item := range headerDeleteItems { + s.wshStream.Publish(WebSocketHeaderTopic{WorkspaceID: item.WorkspaceID}, WebSocketHeaderEvent{ + Type: eventTypeDelete, + WebSocketHeader: &apiv1.WebSocketHeader{ + WebsocketHeaderId: item.ID.Bytes(), + }, + }) + } + + return connect.NewResponse(&emptypb.Empty{}), nil +} + +func toAPIWebSocketHeader(h mwebsocket.WebSocketHeader) *apiv1.WebSocketHeader { + return &apiv1.WebSocketHeader{ + WebsocketHeaderId: h.ID.Bytes(), + WebsocketId: h.WebSocketID.Bytes(), + Key: h.Key, + Value: h.Value, + Enabled: h.Enabled, + Description: h.Description, + Order: h.DisplayOrder, + } +} + +func stringPtr(s string) *string { return &s } +func boolPtr(b bool) *bool { return &b } +func float32Ptr(f float32) *float32 { return &f } + +func webSocketSyncResponseFrom(evt WebSocketEvent) *apiv1.WebSocketSyncResponse { + if evt.WebSocket == nil { + return nil + } + + switch evt.Type { + case eventTypeInsert: + msg := &apiv1.WebSocketSync{ + Value: &apiv1.WebSocketSync_ValueUnion{ + Kind: apiv1.WebSocketSync_ValueUnion_KIND_INSERT, + Insert: &apiv1.WebSocketSyncInsert{ + WebsocketId: evt.WebSocket.WebsocketId, + Name: evt.WebSocket.Name, + Url: evt.WebSocket.Url, + }, + }, + } + return &apiv1.WebSocketSyncResponse{Items: []*apiv1.WebSocketSync{msg}} + case eventTypeUpdate: + msg := &apiv1.WebSocketSync{ + Value: &apiv1.WebSocketSync_ValueUnion{ + Kind: apiv1.WebSocketSync_ValueUnion_KIND_UPDATE, + Update: &apiv1.WebSocketSyncUpdate{ + WebsocketId: evt.WebSocket.WebsocketId, + Name: stringPtr(evt.WebSocket.Name), + Url: stringPtr(evt.WebSocket.Url), + }, + }, + } + return &apiv1.WebSocketSyncResponse{Items: []*apiv1.WebSocketSync{msg}} + case eventTypeDelete: + msg := &apiv1.WebSocketSync{ + Value: &apiv1.WebSocketSync_ValueUnion{ + Kind: apiv1.WebSocketSync_ValueUnion_KIND_DELETE, + Delete: &apiv1.WebSocketSyncDelete{ + WebsocketId: evt.WebSocket.WebsocketId, + }, + }, + } + return &apiv1.WebSocketSyncResponse{Items: []*apiv1.WebSocketSync{msg}} + default: + return nil + } +} + +func webSocketHeaderSyncResponseFrom(evt WebSocketHeaderEvent) *apiv1.WebSocketHeaderSyncResponse { + if evt.WebSocketHeader == nil { + return nil + } + + switch evt.Type { + case eventTypeInsert: + msg := &apiv1.WebSocketHeaderSync{ + Value: &apiv1.WebSocketHeaderSync_ValueUnion{ + Kind: apiv1.WebSocketHeaderSync_ValueUnion_KIND_INSERT, + Insert: &apiv1.WebSocketHeaderSyncInsert{ + WebsocketHeaderId: evt.WebSocketHeader.WebsocketHeaderId, + WebsocketId: evt.WebSocketHeader.WebsocketId, + Key: evt.WebSocketHeader.Key, + Value: evt.WebSocketHeader.Value, + Enabled: evt.WebSocketHeader.Enabled, + Description: evt.WebSocketHeader.Description, + Order: evt.WebSocketHeader.Order, + }, + }, + } + return &apiv1.WebSocketHeaderSyncResponse{Items: []*apiv1.WebSocketHeaderSync{msg}} + case eventTypeUpdate: + msg := &apiv1.WebSocketHeaderSync{ + Value: &apiv1.WebSocketHeaderSync_ValueUnion{ + Kind: apiv1.WebSocketHeaderSync_ValueUnion_KIND_UPDATE, + Update: &apiv1.WebSocketHeaderSyncUpdate{ + WebsocketHeaderId: evt.WebSocketHeader.WebsocketHeaderId, + WebsocketId: evt.WebSocketHeader.WebsocketId, + Key: stringPtr(evt.WebSocketHeader.Key), + Value: stringPtr(evt.WebSocketHeader.Value), + Enabled: boolPtr(evt.WebSocketHeader.Enabled), + Description: stringPtr(evt.WebSocketHeader.Description), + Order: float32Ptr(evt.WebSocketHeader.Order), + }, + }, + } + return &apiv1.WebSocketHeaderSyncResponse{Items: []*apiv1.WebSocketHeaderSync{msg}} + case eventTypeDelete: + msg := &apiv1.WebSocketHeaderSync{ + Value: &apiv1.WebSocketHeaderSync_ValueUnion{ + Kind: apiv1.WebSocketHeaderSync_ValueUnion_KIND_DELETE, + Delete: &apiv1.WebSocketHeaderSyncDelete{ + WebsocketHeaderId: evt.WebSocketHeader.WebsocketHeaderId, + }, + }, + } + return &apiv1.WebSocketHeaderSyncResponse{Items: []*apiv1.WebSocketHeaderSync{msg}} + default: + return nil + } +} diff --git a/packages/server/internal/converter/converter.go b/packages/server/internal/converter/converter.go index 1bb61310a..2f33f94f1 100644 --- a/packages/server/internal/converter/converter.go +++ b/packages/server/internal/converter/converter.go @@ -379,6 +379,12 @@ func ToAPINodeKind(kind mflow.NodeKind) flowv1.NodeKind { return flowv1.NodeKind_NODE_KIND_AI_MEMORY case mflow.NODE_KIND_GRAPHQL: return flowv1.NodeKind_NODE_KIND_GRAPH_Q_L + case mflow.NODE_KIND_WS_CONNECTION: + return flowv1.NodeKind_NODE_KIND_WS_CONNECTION + case mflow.NODE_KIND_WS_SEND: + return flowv1.NodeKind_NODE_KIND_WS_SEND + case mflow.NODE_KIND_WAIT: + return flowv1.NodeKind_NODE_KIND_WAIT default: return flowv1.NodeKind_NODE_KIND_UNSPECIFIED } diff --git a/packages/server/internal/converter/converter_test.go b/packages/server/internal/converter/converter_test.go index 690f864cd..f67b5ee60 100644 --- a/packages/server/internal/converter/converter_test.go +++ b/packages/server/internal/converter/converter_test.go @@ -626,6 +626,8 @@ func TestToAPINodeKind(t *testing.T) { {mflow.NODE_KIND_FOR, flowv1.NodeKind_NODE_KIND_FOR}, {mflow.NODE_KIND_FOR_EACH, flowv1.NodeKind_NODE_KIND_FOR_EACH}, {mflow.NODE_KIND_JS, flowv1.NodeKind_NODE_KIND_JS}, + {mflow.NODE_KIND_WS_CONNECTION, flowv1.NodeKind_NODE_KIND_WS_CONNECTION}, + {mflow.NODE_KIND_WS_SEND, flowv1.NodeKind_NODE_KIND_WS_SEND}, {mflow.NodeKind(-1), flowv1.NodeKind_NODE_KIND_UNSPECIFIED}, } diff --git a/packages/server/internal/migrations/01KJZMR5_add_flow_node_wait.go b/packages/server/internal/migrations/01KJZMR5_add_flow_node_wait.go new file mode 100644 index 000000000..cfde105fa --- /dev/null +++ b/packages/server/internal/migrations/01KJZMR5_add_flow_node_wait.go @@ -0,0 +1,50 @@ +package migrations + +import ( + "context" + "database/sql" + "fmt" + + "github.com/the-dev-tools/dev-tools/packages/server/internal/migrate" +) + +const MigrationAddFlowNodeWaitID = "01KJZMR5232X0983HYB7GS2WZ7" + +const MigrationAddFlowNodeWaitChecksum = "sha256:add-flow-node-wait-v1" + +func init() { + if err := migrate.Register(migrate.Migration{ + ID: MigrationAddFlowNodeWaitID, + Checksum: MigrationAddFlowNodeWaitChecksum, + Description: "Add flow_node_wait table for wait/delay nodes", + Apply: applyFlowNodeWait, + Validate: validateFlowNodeWait, + RequiresBackup: false, + }); err != nil { + panic("failed to register flow_node_wait migration: " + err.Error()) + } +} + +func applyFlowNodeWait(ctx context.Context, tx *sql.Tx) error { + if _, err := tx.ExecContext(ctx, ` + CREATE TABLE IF NOT EXISTS flow_node_wait ( + flow_node_id BLOB NOT NULL PRIMARY KEY, + duration_ms BIGINT NOT NULL + ) + `); err != nil { + return fmt.Errorf("create flow_node_wait table: %w", err) + } + return nil +} + +func validateFlowNodeWait(ctx context.Context, db *sql.DB) error { + var name string + err := db.QueryRowContext(ctx, ` + SELECT name FROM sqlite_master + WHERE type='table' AND name='flow_node_wait' + `).Scan(&name) + if err != nil { + return fmt.Errorf("flow_node_wait table not found: %w", err) + } + return nil +} diff --git a/packages/server/internal/migrations/01KKFQT8_add_websocket_tables.go b/packages/server/internal/migrations/01KKFQT8_add_websocket_tables.go new file mode 100644 index 000000000..362a7b66e --- /dev/null +++ b/packages/server/internal/migrations/01KKFQT8_add_websocket_tables.go @@ -0,0 +1,233 @@ +package migrations + +import ( + "context" + "database/sql" + "fmt" + "strings" + + "github.com/the-dev-tools/dev-tools/packages/server/internal/migrate" +) + +// MigrationAddWebSocketTablesID is the ULID for the WebSocket tables migration. +const MigrationAddWebSocketTablesID = "01KKFQT81KV5MX8H9MNTPCWDV9" + +// MigrationAddWebSocketTablesChecksum is a stable hash of this migration. +const MigrationAddWebSocketTablesChecksum = "sha256:add-websocket-tables-v1" + +func init() { + if err := migrate.Register(migrate.Migration{ + ID: MigrationAddWebSocketTablesID, + Checksum: MigrationAddWebSocketTablesChecksum, + Description: "Add WebSocket tables for connections, headers, and flow nodes", + Apply: applyWebSocketTables, + Validate: validateWebSocketTables, + RequiresBackup: true, + }); err != nil { + panic("failed to register WebSocket tables migration: " + err.Error()) + } +} + +func applyWebSocketTables(ctx context.Context, tx *sql.Tx) error { + // 1. Create websocket table + if _, err := tx.ExecContext(ctx, ` + CREATE TABLE IF NOT EXISTS websocket ( + id BLOB NOT NULL PRIMARY KEY, + workspace_id BLOB NOT NULL, + folder_id BLOB, + name TEXT NOT NULL, + url TEXT NOT NULL, + description TEXT NOT NULL DEFAULT '', + last_run_at BIGINT NULL, + created_at BIGINT NOT NULL DEFAULT (unixepoch()), + updated_at BIGINT NOT NULL DEFAULT (unixepoch()), + + FOREIGN KEY (workspace_id) REFERENCES workspaces (id) ON DELETE CASCADE, + FOREIGN KEY (folder_id) REFERENCES files (id) ON DELETE SET NULL + ) + `); err != nil { + return err + } + + wsIndexes := []string{ + `CREATE INDEX IF NOT EXISTS websocket_workspace_idx ON websocket (workspace_id)`, + `CREATE INDEX IF NOT EXISTS websocket_folder_idx ON websocket (folder_id) WHERE folder_id IS NOT NULL`, + } + for _, idx := range wsIndexes { + if _, err := tx.ExecContext(ctx, idx); err != nil { + return fmt.Errorf("create websocket index: %w", err) + } + } + + // 2. Create websocket_header table + if _, err := tx.ExecContext(ctx, ` + CREATE TABLE IF NOT EXISTS websocket_header ( + id BLOB NOT NULL PRIMARY KEY, + websocket_id BLOB NOT NULL, + header_key TEXT NOT NULL, + header_value TEXT NOT NULL, + description TEXT NOT NULL DEFAULT '', + enabled BOOLEAN NOT NULL DEFAULT TRUE, + display_order REAL NOT NULL DEFAULT 0, + created_at BIGINT NOT NULL DEFAULT (unixepoch()), + updated_at BIGINT NOT NULL DEFAULT (unixepoch()), + + FOREIGN KEY (websocket_id) REFERENCES websocket (id) ON DELETE CASCADE + ) + `); err != nil { + return err + } + + headerIndexes := []string{ + `CREATE INDEX IF NOT EXISTS websocket_header_ws_idx ON websocket_header (websocket_id)`, + `CREATE INDEX IF NOT EXISTS websocket_header_order_idx ON websocket_header (websocket_id, display_order)`, + } + for _, idx := range headerIndexes { + if _, err := tx.ExecContext(ctx, idx); err != nil { + return fmt.Errorf("create websocket_header index: %w", err) + } + } + + // 3. Create flow_node_ws_connection table + if _, err := tx.ExecContext(ctx, ` + CREATE TABLE IF NOT EXISTS flow_node_ws_connection ( + flow_node_id BLOB NOT NULL PRIMARY KEY, + websocket_id BLOB, + FOREIGN KEY (websocket_id) REFERENCES websocket (id) ON DELETE SET NULL + ) + `); err != nil { + return err + } + + // 4. Create flow_node_ws_send table + if _, err := tx.ExecContext(ctx, ` + CREATE TABLE IF NOT EXISTS flow_node_ws_send ( + flow_node_id BLOB NOT NULL PRIMARY KEY, + ws_connection_node_name TEXT NOT NULL DEFAULT '', + message TEXT NOT NULL DEFAULT '' + ) + `); err != nil { + return err + } + + // 5. Update files table CHECK constraint to allow content_kind = 6 (websocket) + if err := updateFilesCheckConstraintWebSocket(ctx, tx); err != nil { + return fmt.Errorf("update files check constraint: %w", err) + } + + return nil +} + +// updateFilesCheckConstraintWebSocket recreates the files table with WebSocket content_kind support. +func updateFilesCheckConstraintWebSocket(ctx context.Context, tx *sql.Tx) error { + var tableSql string + err := tx.QueryRowContext(ctx, ` + SELECT sql FROM sqlite_master WHERE type='table' AND name='files' + `).Scan(&tableSql) + if err != nil { + return fmt.Errorf("read files table schema: %w", err) + } + if strings.Contains(tableSql, "5, 6)") { + return nil + } + + if _, err := tx.ExecContext(ctx, ` + CREATE TABLE files_new ( + id BLOB NOT NULL PRIMARY KEY, + workspace_id BLOB NOT NULL, + parent_id BLOB, + content_id BLOB, + content_kind INT8 NOT NULL DEFAULT 0, + name TEXT NOT NULL, + display_order REAL NOT NULL DEFAULT 0, + path_hash TEXT, + updated_at BIGINT NOT NULL DEFAULT (unixepoch()), + CHECK (length (id) == 16), + CHECK (content_kind IN (0, 1, 2, 3, 4, 5, 6)), + CHECK ( + (content_kind = 0 AND content_id IS NOT NULL) OR + (content_kind = 1 AND content_id IS NOT NULL) OR + (content_kind = 2 AND content_id IS NOT NULL) OR + (content_kind = 3 AND content_id IS NOT NULL) OR + (content_kind = 4 AND content_id IS NOT NULL) OR + (content_kind = 5 AND content_id IS NOT NULL) OR + (content_kind = 6 AND content_id IS NOT NULL) OR + (content_id IS NULL) + ), + FOREIGN KEY (workspace_id) REFERENCES workspaces (id) ON DELETE CASCADE, + FOREIGN KEY (parent_id) REFERENCES files (id) ON DELETE SET NULL + ) + `); err != nil { + return fmt.Errorf("create files_new: %w", err) + } + + if _, err := tx.ExecContext(ctx, `INSERT INTO files_new SELECT * FROM files`); err != nil { + return fmt.Errorf("copy files data: %w", err) + } + + if _, err := tx.ExecContext(ctx, `DROP TABLE files`); err != nil { + return fmt.Errorf("drop old files: %w", err) + } + + if _, err := tx.ExecContext(ctx, `ALTER TABLE files_new RENAME TO files`); err != nil { + return fmt.Errorf("rename files_new: %w", err) + } + + indexes := []string{ + `CREATE INDEX files_workspace_idx ON files (workspace_id)`, + `CREATE UNIQUE INDEX files_path_hash_idx ON files (workspace_id, path_hash) WHERE path_hash IS NOT NULL`, + `CREATE INDEX files_hierarchy_idx ON files (workspace_id, parent_id, display_order)`, + `CREATE INDEX files_content_lookup_idx ON files (content_kind, content_id) WHERE content_id IS NOT NULL`, + `CREATE INDEX files_parent_lookup_idx ON files (parent_id, display_order) WHERE parent_id IS NOT NULL`, + `CREATE INDEX files_name_search_idx ON files (workspace_id, name)`, + `CREATE INDEX files_kind_filter_idx ON files (workspace_id, content_kind)`, + `CREATE INDEX files_workspace_hierarchy_idx ON files (workspace_id, parent_id, content_kind, display_order)`, + } + for _, idx := range indexes { + if _, err := tx.ExecContext(ctx, idx); err != nil { + return fmt.Errorf("recreate index: %w", err) + } + } + + return nil +} + +func validateWebSocketTables(ctx context.Context, db *sql.DB) error { + tables := []string{ + "websocket", + "websocket_header", + "flow_node_ws_connection", + "flow_node_ws_send", + } + + for _, table := range tables { + var name string + err := db.QueryRowContext(ctx, ` + SELECT name FROM sqlite_master + WHERE type='table' AND name=? + `, table).Scan(&name) + if err != nil { + return fmt.Errorf("table %s not found: %w", table, err) + } + } + + indexes := []string{ + "websocket_workspace_idx", + "websocket_folder_idx", + "websocket_header_ws_idx", + "websocket_header_order_idx", + } + + for _, idx := range indexes { + var name string + err := db.QueryRowContext(ctx, ` + SELECT name FROM sqlite_master + WHERE type='index' AND name=? + `, idx).Scan(&name) + if err != nil { + return fmt.Errorf("index %s not found: %w", idx, err) + } + } + + return nil +} diff --git a/packages/server/internal/migrations/migrations_test.go b/packages/server/internal/migrations/migrations_test.go index 00932679b..4f506acad 100644 --- a/packages/server/internal/migrations/migrations_test.go +++ b/packages/server/internal/migrations/migrations_test.go @@ -210,7 +210,7 @@ func TestFilesTableConstraintUpdated(t *testing.T) { t.Fatalf("failed to run migrations: %v", err) } - // Verify files table supports content_kind=5 (graphql) + // Verify files table supports content_kind=6 (websocket) var tableDef string err = db.QueryRowContext(ctx, ` SELECT sql FROM sqlite_master @@ -220,9 +220,9 @@ func TestFilesTableConstraintUpdated(t *testing.T) { t.Fatalf("failed to get files table definition: %v", err) } - // Check that the constraint includes content_kind=5 - if !contains(tableDef, "content_kind IN (0, 1, 2, 3, 4, 5)") { - t.Errorf("files table CHECK constraint doesn't include content_kind=5: %s", tableDef) + // Check that the constraint includes content_kind=6 + if !contains(tableDef, "content_kind IN (0, 1, 2, 3, 4, 5, 6)") { + t.Errorf("files table CHECK constraint doesn't include content_kind=6: %s", tableDef) } } diff --git a/packages/server/pkg/flow/flowbuilder/builder.go b/packages/server/pkg/flow/flowbuilder/builder.go index 018b4e809..3248fdedd 100644 --- a/packages/server/pkg/flow/flowbuilder/builder.go +++ b/packages/server/pkg/flow/flowbuilder/builder.go @@ -20,6 +20,9 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node/naiprovider" "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node/nrequest" "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node/nstart" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node/nwait" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node/nwsconnection" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node/nwssend" gqlresolver "github.com/the-dev-tools/dev-tools/packages/server/pkg/graphql/resolver" "github.com/the-dev-tools/dev-tools/packages/server/pkg/http/resolver" "github.com/the-dev-tools/dev-tools/packages/server/pkg/httpclient" @@ -30,6 +33,7 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/senv" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sflow" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sgraphql" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/swebsocket" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sworkspace" "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/api/private/node_js_executor/v1/node_js_executorv1connect" ) @@ -44,9 +48,14 @@ type Builder struct { NodeAI *sflow.NodeAIService NodeAiProvider *sflow.NodeAiProviderService NodeMemory *sflow.NodeMemoryService - NodeGraphQL *sflow.NodeGraphQLService - GraphQL *sgraphql.GraphQLService - GraphQLHeader *sgraphql.GraphQLHeaderService + NodeGraphQL *sflow.NodeGraphQLService + NodeWsConnection *sflow.NodeWsConnectionService + NodeWsSend *sflow.NodeWsSendService + NodeWait *sflow.NodeWaitService + WebSocket *swebsocket.WebSocketService + WebSocketHeader *swebsocket.WebSocketHeaderService + GraphQL *sgraphql.GraphQLService + GraphQLHeader *sgraphql.GraphQLHeaderService Workspace *sworkspace.WorkspaceService Variable *senv.VariableService @@ -69,6 +78,11 @@ func New( naps *sflow.NodeAiProviderService, nmems *sflow.NodeMemoryService, ngqs *sflow.NodeGraphQLService, + nwcs *sflow.NodeWsConnectionService, + nwss *sflow.NodeWsSendService, + nwaits *sflow.NodeWaitService, + wsSvc *swebsocket.WebSocketService, + wsHeaderSvc *swebsocket.WebSocketHeaderService, gqls *sgraphql.GraphQLService, gqlhs *sgraphql.GraphQLHeaderService, ws *sworkspace.WorkspaceService, @@ -90,6 +104,11 @@ func New( NodeAiProvider: naps, NodeMemory: nmems, NodeGraphQL: ngqs, + NodeWsConnection: nwcs, + NodeWsSend: nwss, + NodeWait: nwaits, + WebSocket: wsSvc, + WebSocketHeader: wsHeaderSvc, GraphQL: gqls, GraphQLHeader: gqlhs, Workspace: ws, @@ -111,27 +130,27 @@ func (b *Builder) BuildNodes( respChan chan nrequest.NodeRequestSideResp, gqlRespChan chan ngraphql.NodeGraphQLSideResp, jsClient node_js_executorv1connect.NodeJsExecutorServiceClient, -) (map[idwrap.IDWrap]node.FlowNode, idwrap.IDWrap, error) { +) (map[idwrap.IDWrap]node.FlowNode, []idwrap.IDWrap, error) { flowNodeMap := make(map[idwrap.IDWrap]node.FlowNode, len(nodes)) - var startNodeID idwrap.IDWrap + var startNodeIDs []idwrap.IDWrap for _, nodeModel := range nodes { switch nodeModel.NodeKind { case mflow.NODE_KIND_MANUAL_START: flowNodeMap[nodeModel.ID] = nstart.New(nodeModel.ID, nodeModel.Name) - startNodeID = nodeModel.ID + startNodeIDs = append(startNodeIDs, nodeModel.ID) case mflow.NODE_KIND_REQUEST: requestCfg, err := b.NodeRequest.GetNodeRequest(ctx, nodeModel.ID) if err != nil { - return nil, idwrap.IDWrap{}, err + return nil, nil, err } if requestCfg == nil || requestCfg.HttpID == nil || isZeroID(*requestCfg.HttpID) { - return nil, idwrap.IDWrap{}, fmt.Errorf("request node %s missing http configuration", nodeModel.ID.String()) + return nil, nil, fmt.Errorf("request node %s missing http configuration", nodeModel.ID.String()) } resolved, err := b.Resolver.Resolve(ctx, *requestCfg.HttpID, requestCfg.DeltaHttpID) if err != nil { - return nil, idwrap.IDWrap{}, fmt.Errorf("resolve http %s: %w", requestCfg.HttpID.String(), err) + return nil, nil, fmt.Errorf("resolve http %s: %w", requestCfg.HttpID.String(), err) } requestNode := nrequest.New( @@ -153,7 +172,7 @@ func (b *Builder) BuildNodes( case mflow.NODE_KIND_FOR: forCfg, err := b.NodeFor.GetNodeFor(ctx, nodeModel.ID) if err != nil { - return nil, idwrap.IDWrap{}, err + return nil, nil, err } if forCfg == nil { // Default configuration if missing @@ -173,7 +192,7 @@ func (b *Builder) BuildNodes( case mflow.NODE_KIND_FOR_EACH: forEachCfg, err := b.NodeForEach.GetNodeForEach(ctx, nodeModel.ID) if err != nil { - return nil, idwrap.IDWrap{}, err + return nil, nil, err } if forEachCfg == nil { // Default configuration if missing @@ -184,7 +203,7 @@ func (b *Builder) BuildNodes( case mflow.NODE_KIND_CONDITION: condCfg, err := b.NodeIf.GetNodeIf(ctx, nodeModel.ID) if err != nil { - return nil, idwrap.IDWrap{}, err + return nil, nil, err } if condCfg == nil { // Default to "true" or "false"? Usually better to default to something safe or empty. @@ -196,7 +215,7 @@ func (b *Builder) BuildNodes( case mflow.NODE_KIND_JS: jsCfg, err := b.NodeJS.GetNodeJS(ctx, nodeModel.ID) if err != nil { - return nil, idwrap.IDWrap{}, err + return nil, nil, err } if jsCfg == nil { // Default empty JS @@ -206,7 +225,7 @@ func (b *Builder) BuildNodes( if jsCfg.CodeCompressType != compress.CompressTypeNone { codeBytes, err = compress.Decompress(jsCfg.Code, jsCfg.CodeCompressType) if err != nil { - return nil, idwrap.IDWrap{}, fmt.Errorf("decompress js code: %w", err) + return nil, nil, fmt.Errorf("decompress js code: %w", err) } } flowNodeMap[nodeModel.ID] = njs.New(nodeModel.ID, nodeModel.Name, string(codeBytes), jsClient) @@ -214,7 +233,7 @@ func (b *Builder) BuildNodes( case mflow.NODE_KIND_AI: aiCfg, err := b.NodeAI.GetNodeAI(ctx, nodeModel.ID) if err != nil { - return nil, idwrap.IDWrap{}, err + return nil, nil, err } if aiCfg == nil { // Default AI node with empty prompt @@ -237,7 +256,7 @@ func (b *Builder) BuildNodes( case mflow.NODE_KIND_AI_PROVIDER: providerCfg, err := b.NodeAiProvider.GetNodeAiProvider(ctx, nodeModel.ID) if err != nil && !errors.Is(err, sflow.ErrNoNodeAiProviderFound) { - return nil, idwrap.IDWrap{}, err + return nil, nil, err } if providerCfg == nil { // Default AI Provider node (no credential set) @@ -262,7 +281,7 @@ func (b *Builder) BuildNodes( case mflow.NODE_KIND_AI_MEMORY: memoryCfg, err := b.NodeMemory.GetNodeMemory(ctx, nodeModel.ID) if err != nil && !errors.Is(err, sflow.ErrNoNodeMemoryFound) { - return nil, idwrap.IDWrap{}, err + return nil, nil, err } if memoryCfg == nil { // Default Memory node with window buffer of 10 messages @@ -283,16 +302,16 @@ func (b *Builder) BuildNodes( case mflow.NODE_KIND_GRAPHQL: gqlCfg, err := b.NodeGraphQL.GetNodeGraphQL(ctx, nodeModel.ID) if err != nil { - return nil, idwrap.IDWrap{}, err + return nil, nil, err } if gqlCfg == nil || gqlCfg.GraphQLID == nil || isZeroID(*gqlCfg.GraphQLID) { - return nil, idwrap.IDWrap{}, fmt.Errorf("graphql node %s missing graphql configuration", nodeModel.ID.String()) + return nil, nil, fmt.Errorf("graphql node %s missing graphql configuration", nodeModel.ID.String()) } // Resolve GraphQL entity with delta resolved, err := b.GraphQLResolver.Resolve(ctx, *gqlCfg.GraphQLID, gqlCfg.DeltaGraphQLID) if err != nil { - return nil, idwrap.IDWrap{}, fmt.Errorf("resolve graphql %s: %w", gqlCfg.GraphQLID.String(), err) + return nil, nil, fmt.Errorf("resolve graphql %s: %w", gqlCfg.GraphQLID.String(), err) } flowNodeMap[nodeModel.ID] = ngraphql.New( @@ -305,16 +324,72 @@ func (b *Builder) BuildNodes( gqlRespChan, b.Logger, ) + case mflow.NODE_KIND_WS_CONNECTION: + var url string + var headers map[string]string + if b.NodeWsConnection != nil { + wsCfg, err := b.NodeWsConnection.GetNodeWsConnection(ctx, nodeModel.ID) + if err != nil { + return nil, nil, fmt.Errorf("get ws connection config: %w", err) + } + if wsCfg != nil && wsCfg.WebSocketID != nil && !isZeroID(*wsCfg.WebSocketID) && b.WebSocket != nil { + wsEntity, err := b.WebSocket.Get(ctx, *wsCfg.WebSocketID) + if err != nil { + return nil, nil, fmt.Errorf("resolve websocket %s: %w", wsCfg.WebSocketID.String(), err) + } + url = wsEntity.Url + if b.WebSocketHeader != nil { + wsHeaders, err := b.WebSocketHeader.GetByWebSocketID(ctx, *wsCfg.WebSocketID) + if err != nil { + return nil, nil, fmt.Errorf("resolve websocket headers %s: %w", wsCfg.WebSocketID.String(), err) + } + headers = make(map[string]string, len(wsHeaders)) + for _, h := range wsHeaders { + if h.Enabled { + headers[h.Key] = h.Value + } + } + } + } + } + wsNode := nwsconnection.New(nodeModel.ID, nodeModel.Name, url, headers) + flowNodeMap[nodeModel.ID] = wsNode + case mflow.NODE_KIND_WS_SEND: + var wsConnName string + var message string + if b.NodeWsSend != nil { + wsCfg, err := b.NodeWsSend.GetNodeWsSend(ctx, nodeModel.ID) + if err != nil { + return nil, nil, fmt.Errorf("get ws send config: %w", err) + } + if wsCfg != nil { + wsConnName = wsCfg.WsConnectionNodeName + message = wsCfg.Message + } + } + flowNodeMap[nodeModel.ID] = nwssend.New(nodeModel.ID, nodeModel.Name, wsConnName, message) + case mflow.NODE_KIND_WAIT: + var durationMs int64 = 1000 // default 1 second + if b.NodeWait != nil { + waitCfg, err := b.NodeWait.GetNodeWait(ctx, nodeModel.ID) + if err != nil { + return nil, nil, fmt.Errorf("get wait config: %w", err) + } + if waitCfg != nil { + durationMs = waitCfg.DurationMs + } + } + flowNodeMap[nodeModel.ID] = nwait.New(nodeModel.ID, nodeModel.Name, durationMs) default: - return nil, idwrap.IDWrap{}, fmt.Errorf("node kind %d not supported", nodeModel.NodeKind) + return nil, nil, fmt.Errorf("node kind %d not supported", nodeModel.NodeKind) } } - if startNodeID == (idwrap.IDWrap{}) { - return nil, idwrap.IDWrap{}, errors.New("flow missing start node") + if len(startNodeIDs) == 0 { + return nil, nil, errors.New("flow missing start node") } - return flowNodeMap, startNodeID, nil + return flowNodeMap, startNodeIDs, nil } func (b *Builder) BuildVariables( diff --git a/packages/server/pkg/flow/flowexec/session.go b/packages/server/pkg/flow/flowexec/session.go new file mode 100644 index 000000000..d406ab34a --- /dev/null +++ b/packages/server/pkg/flow/flowexec/session.go @@ -0,0 +1,165 @@ +// Package flowexec manages flow execution sessions. +// It orchestrates the flow lifecycle: variable resolution, node construction, +// runner creation, and result processing. +// +// The ExecutionSession interface supports both local execution (ServerSession) +// and future distributed execution across regions. +package flowexec + +import ( + "context" + "fmt" + "math" + "time" + + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/flowbuilder" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/flowresult" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/runner" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/runner/flowlocalrunner" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/httpclient" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" + "github.com/the-dev-tools/dev-tools/packages/spec/dist/buf/go/api/private/node_js_executor/v1/node_js_executorv1connect" +) + +// ExecutionSession manages a single flow execution lifecycle. +// Implementations may run the flow locally (ServerSession) or dispatch +// to remote workers for distributed execution. +type ExecutionSession interface { + // Prepare builds the execution graph from flow data. + // Must be called before Run. + Prepare(ctx context.Context, params ExecutionParams) error + + // Run executes the prepared flow and returns the result. + // The processor lifecycle (Start/Wait) is managed internally. + Run(ctx context.Context) (ExecutionResult, error) +} + +// ExecutionParams contains the flow data needed for execution. +type ExecutionParams struct { + Flow mflow.Flow + Nodes []mflow.Node + Edges []mflow.Edge // Only valid edges (no orphaned source/target references) + FlowVars []mflow.FlowVariable +} + +// ExecutionResult contains the outcome of a flow execution. +type ExecutionResult struct { + Duration int32 +} + +// SessionFactory creates ExecutionSession instances. +// Implementations control where the flow runs: locally (LocalSessionFactory) +// or on remote workers for distributed execution. +type SessionFactory interface { + Create(processor flowresult.ResultProcessor) ExecutionSession +} + +// LocalSessionFactory creates ServerSession instances for local execution. +type LocalSessionFactory struct { + Builder *flowbuilder.Builder + JsClient node_js_executorv1connect.NodeJsExecutorServiceClient +} + +var _ SessionFactory = (*LocalSessionFactory)(nil) + +func (f *LocalSessionFactory) Create(processor flowresult.ResultProcessor) ExecutionSession { + return NewServerSession(ServerSessionOpts{ + Builder: f.Builder, + JsClient: f.JsClient, + Processor: processor, + }) +} + +// ServerSessionOpts configures a ServerSession. +type ServerSessionOpts struct { + Builder *flowbuilder.Builder + JsClient node_js_executorv1connect.NodeJsExecutorServiceClient + Processor flowresult.ResultProcessor +} + +// ServerSession implements ExecutionSession for local server execution. +// It builds the execution graph, runs the flow via FlowLocalRunner, +// and delegates result processing to a ResultProcessor. +type ServerSession struct { + builder *flowbuilder.Builder + jsClient node_js_executorv1connect.NodeJsExecutorServiceClient + processor flowresult.ResultProcessor + + // Prepared state (set by Prepare, consumed by Run) + flowRunner runner.FlowRunner + baseVars map[string]any +} + +var _ ExecutionSession = (*ServerSession)(nil) + +// NewServerSession creates a new ServerSession for local flow execution. +func NewServerSession(opts ServerSessionOpts) *ServerSession { + return &ServerSession{ + builder: opts.Builder, + jsClient: opts.JsClient, + processor: opts.Processor, + } +} + +// Prepare builds execution variables, constructs flow nodes, and creates the runner. +func (s *ServerSession) Prepare(ctx context.Context, params ExecutionParams) error { + baseVars, err := s.builder.BuildVariables(ctx, params.Flow.WorkspaceID, params.FlowVars) + if err != nil { + return fmt.Errorf("failed to build execution variables: %w", err) + } + s.baseVars = baseVars + + edgeMap := mflow.NewEdgesMap(params.Edges) + sharedHTTPClient := httpclient.New() + + const defaultNodeTimeout = 60 // seconds + timeoutDuration := time.Duration(defaultNodeTimeout) * time.Second + + flowNodeMap, startNodeIDs, err := s.builder.BuildNodes( + ctx, + params.Flow, + params.Nodes, + timeoutDuration, + sharedHTTPClient, + s.processor.HTTPResponseChan(), + s.processor.GraphQLResponseChan(), + s.jsClient, + ) + if err != nil { + return err + } + + s.flowRunner = flowlocalrunner.CreateFlowRunner( + idwrap.NewMonotonic(), + params.Flow.ID, + startNodeIDs, + flowNodeMap, + edgeMap, + 0, + nil, + ) + + return nil +} + +// Run starts the result processor, executes the flow, waits for all result +// processing to complete, and returns the execution duration. +func (s *ServerSession) Run(ctx context.Context) (ExecutionResult, error) { + s.processor.Start() + + startTime := time.Now() + runErr := s.flowRunner.RunWithEvents(ctx, runner.FlowEventChannels{ + NodeStates: s.processor.NodeStateChan(), + }, s.baseVars) + + duration := time.Since(startTime).Milliseconds() + if duration > math.MaxInt32 { + duration = math.MaxInt32 + } + + s.processor.Wait() + + //nolint:gosec // duration clamped to MaxInt32 + return ExecutionResult{Duration: int32(duration)}, runErr +} diff --git a/packages/server/pkg/flow/flowexec/session_test.go b/packages/server/pkg/flow/flowexec/session_test.go new file mode 100644 index 000000000..46d151c9d --- /dev/null +++ b/packages/server/pkg/flow/flowexec/session_test.go @@ -0,0 +1,36 @@ +package flowexec + +import ( + "log/slog" + "os" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/flowresult" +) + +func TestLocalSessionFactory_Create(t *testing.T) { + t.Parallel() + + factory := &LocalSessionFactory{ + Builder: nil, // Not used until Prepare + } + + proc := flowresult.NewNoopResultProcessor(0) + session := factory.Create(proc) + + assert.NotNil(t, session) + _, ok := session.(*ServerSession) + assert.True(t, ok, "factory should create ServerSession") +} + +func TestLocalSessionFactory_Interface(t *testing.T) { + t.Parallel() + + // Verify LocalSessionFactory satisfies SessionFactory at compile time + var _ SessionFactory = (*LocalSessionFactory)(nil) + + logger := slog.New(slog.NewTextHandler(os.Stdout, nil)) + _ = logger +} diff --git a/packages/server/pkg/flow/flowexec/snapshot.go b/packages/server/pkg/flow/flowexec/snapshot.go new file mode 100644 index 000000000..03c4b2ae6 --- /dev/null +++ b/packages/server/pkg/flow/flowexec/snapshot.go @@ -0,0 +1,396 @@ +package flowexec + +import ( + "context" + "database/sql" + "fmt" + + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mcondition" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sflow" +) + +// NodeConfigSnapshot reads and writes a single node kind's type-specific +// configuration during flow version snapshots. +type NodeConfigSnapshot interface { + Kind() mflow.NodeKind + // Read fetches the type-specific config for a node. Returns (nil, nil) if none exists. + Read(ctx context.Context, nodeID idwrap.IDWrap) (any, error) + // WriteTx creates a copy of the config with the new node ID inside the given transaction. + // Returns the created model (for event publishing) or (nil, nil) if skipped. + WriteTx(ctx context.Context, tx *sql.Tx, newNodeID idwrap.IDWrap, config any) (any, error) +} + +// SnapshotRegistry maps node kinds to their snapshot handlers. +type SnapshotRegistry struct { + handlers map[mflow.NodeKind]NodeConfigSnapshot +} + +// NewSnapshotRegistry creates an empty registry. +func NewSnapshotRegistry() *SnapshotRegistry { + return &SnapshotRegistry{handlers: make(map[mflow.NodeKind]NodeConfigSnapshot)} +} + +// Register adds a snapshot handler for a node kind. +func (r *SnapshotRegistry) Register(s NodeConfigSnapshot) { + r.handlers[s.Kind()] = s +} + +// Get returns the snapshot handler for a node kind, if registered. +// Returns (nil, false) if the registry is nil or the kind is not registered. +func (r *SnapshotRegistry) Get(kind mflow.NodeKind) (NodeConfigSnapshot, bool) { + if r == nil { + return nil, false + } + s, ok := r.handlers[kind] + return s, ok +} + +// ReadAll reads type-specific configurations for all nodes that have registered handlers. +// Returns a map from node ID to the config value. Errors are logged and the node is +// skipped (resulting in default config when written). +func (r *SnapshotRegistry) ReadAll(ctx context.Context, nodes []mflow.Node, logger interface{ Warn(msg string, args ...any) }) map[idwrap.IDWrap]any { + configs := make(map[idwrap.IDWrap]any, len(nodes)) + for _, node := range nodes { + handler, ok := r.Get(node.NodeKind) + if !ok { + continue + } + config, err := handler.Read(ctx, node.ID) + if err != nil { + logger.Warn("failed to read node config, using defaults", + "node_id", node.ID.String(), "kind", node.NodeKind, "error", err) + continue + } + configs[node.ID] = config + } + return configs +} + +// NodeConfigResult holds the result of writing a single node's type-specific config. +type NodeConfigResult struct { + NodeKind mflow.NodeKind + Config any // The created model (e.g., mflow.NodeFor, mflow.NodeJS) +} + +// WriteAllTx writes type-specific configurations for all nodes within a transaction. +// Uses configs from ReadAll. Returns the created configs for event publishing. +func (r *SnapshotRegistry) WriteAllTx( + ctx context.Context, + tx *sql.Tx, + sourceNodes []mflow.Node, + nodeIDMapping map[string]idwrap.IDWrap, + configs map[idwrap.IDWrap]any, +) ([]NodeConfigResult, error) { + var results []NodeConfigResult + for _, sourceNode := range sourceNodes { + handler, ok := r.Get(sourceNode.NodeKind) + if !ok { + continue + } + newNodeID, ok := nodeIDMapping[sourceNode.ID.String()] + if !ok { + continue + } + config := configs[sourceNode.ID] + created, err := handler.WriteTx(ctx, tx, newNodeID, config) + if err != nil { + return nil, fmt.Errorf("create %s node config: %w", sourceNode.Name, err) + } + if created != nil { + results = append(results, NodeConfigResult{ + NodeKind: sourceNode.NodeKind, + Config: created, + }) + } + } + return results, nil +} + +// --- Request --- + +type RequestSnapshot struct{ Service *sflow.NodeRequestService } + +func (s *RequestSnapshot) Kind() mflow.NodeKind { return mflow.NODE_KIND_REQUEST } + +func (s *RequestSnapshot) Read(ctx context.Context, nodeID idwrap.IDWrap) (any, error) { + return s.Service.GetNodeRequest(ctx, nodeID) +} + +func (s *RequestSnapshot) WriteTx(ctx context.Context, tx *sql.Tx, newNodeID idwrap.IDWrap, config any) (any, error) { + src, _ := config.(*mflow.NodeRequest) + if src == nil { + return nil, nil + } + newData := mflow.NodeRequest{ + FlowNodeID: newNodeID, + HttpID: src.HttpID, + DeltaHttpID: src.DeltaHttpID, + HasRequestConfig: src.HasRequestConfig, + } + writer := s.Service.TX(tx) + return newData, writer.CreateNodeRequest(ctx, newData) +} + +// --- For --- + +type ForSnapshot struct{ Service *sflow.NodeForService } + +func (s *ForSnapshot) Kind() mflow.NodeKind { return mflow.NODE_KIND_FOR } + +func (s *ForSnapshot) Read(ctx context.Context, nodeID idwrap.IDWrap) (any, error) { + return s.Service.GetNodeFor(ctx, nodeID) +} + +func (s *ForSnapshot) WriteTx(ctx context.Context, tx *sql.Tx, newNodeID idwrap.IDWrap, config any) (any, error) { + newData := mflow.NodeFor{ + FlowNodeID: newNodeID, + IterCount: 1, + Condition: mcondition.Condition{}, + ErrorHandling: mflow.ErrorHandling_ERROR_HANDLING_BREAK, + } + if src, ok := config.(*mflow.NodeFor); ok && src != nil { + if src.IterCount > 0 { + newData.IterCount = src.IterCount + } + newData.Condition = src.Condition + newData.ErrorHandling = src.ErrorHandling + } + writer := s.Service.TX(tx) + return newData, writer.CreateNodeFor(ctx, newData) +} + +// --- ForEach --- + +type ForEachSnapshot struct{ Service *sflow.NodeForEachService } + +func (s *ForEachSnapshot) Kind() mflow.NodeKind { return mflow.NODE_KIND_FOR_EACH } + +func (s *ForEachSnapshot) Read(ctx context.Context, nodeID idwrap.IDWrap) (any, error) { + return s.Service.GetNodeForEach(ctx, nodeID) +} + +func (s *ForEachSnapshot) WriteTx(ctx context.Context, tx *sql.Tx, newNodeID idwrap.IDWrap, config any) (any, error) { + newData := mflow.NodeForEach{ + FlowNodeID: newNodeID, + IterExpression: "", + Condition: mcondition.Condition{}, + ErrorHandling: mflow.ErrorHandling_ERROR_HANDLING_BREAK, + } + if src, ok := config.(*mflow.NodeForEach); ok && src != nil { + newData.IterExpression = src.IterExpression + newData.Condition = src.Condition + newData.ErrorHandling = src.ErrorHandling + } + writer := s.Service.TX(tx) + return newData, writer.CreateNodeForEach(ctx, newData) +} + +// --- Condition (If) --- + +type ConditionSnapshot struct{ Service *sflow.NodeIfService } + +func (s *ConditionSnapshot) Kind() mflow.NodeKind { return mflow.NODE_KIND_CONDITION } + +func (s *ConditionSnapshot) Read(ctx context.Context, nodeID idwrap.IDWrap) (any, error) { + return s.Service.GetNodeIf(ctx, nodeID) +} + +func (s *ConditionSnapshot) WriteTx(ctx context.Context, tx *sql.Tx, newNodeID idwrap.IDWrap, config any) (any, error) { + newData := mflow.NodeIf{ + FlowNodeID: newNodeID, + Condition: mcondition.Condition{}, + } + if src, ok := config.(*mflow.NodeIf); ok && src != nil { + newData.Condition = src.Condition + } + writer := s.Service.TX(tx) + return newData, writer.CreateNodeIf(ctx, newData) +} + +// --- JS --- + +type JSSnapshot struct{ Service *sflow.NodeJsService } + +func (s *JSSnapshot) Kind() mflow.NodeKind { return mflow.NODE_KIND_JS } + +func (s *JSSnapshot) Read(ctx context.Context, nodeID idwrap.IDWrap) (any, error) { + return s.Service.GetNodeJS(ctx, nodeID) +} + +func (s *JSSnapshot) WriteTx(ctx context.Context, tx *sql.Tx, newNodeID idwrap.IDWrap, config any) (any, error) { + newData := mflow.NodeJS{ + FlowNodeID: newNodeID, + Code: nil, + CodeCompressType: 0, + } + if src, ok := config.(*mflow.NodeJS); ok && src != nil { + newData.Code = src.Code + newData.CodeCompressType = src.CodeCompressType + } + writer := s.Service.TX(tx) + return newData, writer.CreateNodeJS(ctx, newData) +} + +// --- AI --- + +type AISnapshot struct{ Service *sflow.NodeAIService } + +func (s *AISnapshot) Kind() mflow.NodeKind { return mflow.NODE_KIND_AI } + +func (s *AISnapshot) Read(ctx context.Context, nodeID idwrap.IDWrap) (any, error) { + return s.Service.GetNodeAI(ctx, nodeID) +} + +func (s *AISnapshot) WriteTx(ctx context.Context, tx *sql.Tx, newNodeID idwrap.IDWrap, config any) (any, error) { + newData := mflow.NodeAI{ + FlowNodeID: newNodeID, + Prompt: "", + MaxIterations: 5, + } + if src, ok := config.(*mflow.NodeAI); ok && src != nil { + newData.Prompt = src.Prompt + newData.MaxIterations = src.MaxIterations + } + writer := s.Service.TX(tx) + return newData, writer.CreateNodeAI(ctx, newData) +} + +// --- AI Provider --- + +type AIProviderSnapshot struct{ Service *sflow.NodeAiProviderService } + +func (s *AIProviderSnapshot) Kind() mflow.NodeKind { return mflow.NODE_KIND_AI_PROVIDER } + +func (s *AIProviderSnapshot) Read(ctx context.Context, nodeID idwrap.IDWrap) (any, error) { + return s.Service.GetNodeAiProvider(ctx, nodeID) +} + +func (s *AIProviderSnapshot) WriteTx(ctx context.Context, tx *sql.Tx, newNodeID idwrap.IDWrap, config any) (any, error) { + newData := mflow.NodeAiProvider{ + FlowNodeID: newNodeID, + CredentialID: nil, + Model: mflow.AiModelUnspecified, + Temperature: nil, + MaxTokens: nil, + } + if src, ok := config.(*mflow.NodeAiProvider); ok && src != nil { + newData.CredentialID = src.CredentialID + newData.Model = src.Model + newData.Temperature = src.Temperature + newData.MaxTokens = src.MaxTokens + } + writer := s.Service.TX(tx) + return newData, writer.CreateNodeAiProvider(ctx, newData) +} + +// --- Memory --- + +type MemorySnapshot struct{ Service *sflow.NodeMemoryService } + +func (s *MemorySnapshot) Kind() mflow.NodeKind { return mflow.NODE_KIND_AI_MEMORY } + +func (s *MemorySnapshot) Read(ctx context.Context, nodeID idwrap.IDWrap) (any, error) { + return s.Service.GetNodeMemory(ctx, nodeID) +} + +func (s *MemorySnapshot) WriteTx(ctx context.Context, tx *sql.Tx, newNodeID idwrap.IDWrap, config any) (any, error) { + newData := mflow.NodeMemory{ + FlowNodeID: newNodeID, + MemoryType: mflow.AiMemoryTypeWindowBuffer, + WindowSize: 10, + } + if src, ok := config.(*mflow.NodeMemory); ok && src != nil { + newData.MemoryType = src.MemoryType + newData.WindowSize = src.WindowSize + } + writer := s.Service.TX(tx) + return newData, writer.CreateNodeMemory(ctx, newData) +} + +// --- GraphQL --- + +type GraphQLSnapshot struct{ Service *sflow.NodeGraphQLService } + +func (s *GraphQLSnapshot) Kind() mflow.NodeKind { return mflow.NODE_KIND_GRAPHQL } + +func (s *GraphQLSnapshot) Read(ctx context.Context, nodeID idwrap.IDWrap) (any, error) { + return s.Service.GetNodeGraphQL(ctx, nodeID) +} + +func (s *GraphQLSnapshot) WriteTx(ctx context.Context, tx *sql.Tx, newNodeID idwrap.IDWrap, config any) (any, error) { + src, _ := config.(*mflow.NodeGraphQL) + if src == nil { + return nil, nil + } + newData := mflow.NodeGraphQL{ + FlowNodeID: newNodeID, + GraphQLID: src.GraphQLID, + } + writer := s.Service.TX(tx) + return newData, writer.CreateNodeGraphQL(ctx, newData) +} + +// --- WebSocket Connection --- + +type WsConnectionSnapshot struct{ Service *sflow.NodeWsConnectionService } + +func (s *WsConnectionSnapshot) Kind() mflow.NodeKind { return mflow.NODE_KIND_WS_CONNECTION } + +func (s *WsConnectionSnapshot) Read(ctx context.Context, nodeID idwrap.IDWrap) (any, error) { + return s.Service.GetNodeWsConnection(ctx, nodeID) +} + +func (s *WsConnectionSnapshot) WriteTx(ctx context.Context, tx *sql.Tx, newNodeID idwrap.IDWrap, config any) (any, error) { + src, _ := config.(*mflow.NodeWsConnection) + if src == nil { + return nil, nil + } + newData := *src + newData.FlowNodeID = newNodeID + writer := s.Service.TX(tx) + return newData, writer.CreateNodeWsConnection(ctx, newData) +} + +// --- WebSocket Send --- + +type WsSendSnapshot struct{ Service *sflow.NodeWsSendService } + +func (s *WsSendSnapshot) Kind() mflow.NodeKind { return mflow.NODE_KIND_WS_SEND } + +func (s *WsSendSnapshot) Read(ctx context.Context, nodeID idwrap.IDWrap) (any, error) { + return s.Service.GetNodeWsSend(ctx, nodeID) +} + +func (s *WsSendSnapshot) WriteTx(ctx context.Context, tx *sql.Tx, newNodeID idwrap.IDWrap, config any) (any, error) { + src, _ := config.(*mflow.NodeWsSend) + if src == nil { + return nil, nil + } + newData := *src + newData.FlowNodeID = newNodeID + writer := s.Service.TX(tx) + return newData, writer.CreateNodeWsSend(ctx, newData) +} + +// --- Wait --- + +type WaitSnapshot struct{ Service *sflow.NodeWaitService } + +func (s *WaitSnapshot) Kind() mflow.NodeKind { return mflow.NODE_KIND_WAIT } + +func (s *WaitSnapshot) Read(ctx context.Context, nodeID idwrap.IDWrap) (any, error) { + return s.Service.GetNodeWait(ctx, nodeID) +} + +func (s *WaitSnapshot) WriteTx(ctx context.Context, tx *sql.Tx, newNodeID idwrap.IDWrap, config any) (any, error) { + src, _ := config.(*mflow.NodeWait) + if src == nil { + return nil, nil + } + newData := *src + newData.FlowNodeID = newNodeID + writer := s.Service.TX(tx) + return newData, writer.CreateNodeWait(ctx, newData) +} diff --git a/packages/server/pkg/flow/flowexec/snapshot_test.go b/packages/server/pkg/flow/flowexec/snapshot_test.go new file mode 100644 index 000000000..46f69f90e --- /dev/null +++ b/packages/server/pkg/flow/flowexec/snapshot_test.go @@ -0,0 +1,238 @@ +package flowexec + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/the-dev-tools/dev-tools/packages/db/pkg/dbtest" + gen "github.com/the-dev-tools/dev-tools/packages/db/pkg/sqlc/gen" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sflow" +) + +func TestSnapshotRegistry_NilSafe(t *testing.T) { + t.Parallel() + + var r *SnapshotRegistry + handler, ok := r.Get(mflow.NODE_KIND_REQUEST) + assert.False(t, ok) + assert.Nil(t, handler) +} + +func TestSnapshotRegistry_GetUnregistered(t *testing.T) { + t.Parallel() + + r := NewSnapshotRegistry() + handler, ok := r.Get(mflow.NODE_KIND_REQUEST) + assert.False(t, ok) + assert.Nil(t, handler) +} + +func TestSnapshotRegistry_RegisterAndGet(t *testing.T) { + t.Parallel() + + ctx := context.Background() + db, err := dbtest.GetTestDB(ctx) + require.NoError(t, err) + defer db.Close() + + queries := gen.New(db) + forService := sflow.NewNodeForService(queries) + + r := NewSnapshotRegistry() + r.Register(&ForSnapshot{Service: &forService}) + + handler, ok := r.Get(mflow.NODE_KIND_FOR) + assert.True(t, ok) + assert.Equal(t, mflow.NODE_KIND_FOR, handler.Kind()) + + // Unregistered kind still returns false + _, ok = r.Get(mflow.NODE_KIND_REQUEST) + assert.False(t, ok) +} + +// TestWriteTx_TypedNilConfig verifies that WriteTx handles Go's typed nil +// interface gotcha: (*T)(nil) wrapped in any is NOT == nil. +func TestWriteTx_TypedNilConfig(t *testing.T) { + t.Parallel() + + ctx := context.Background() + db, err := dbtest.GetTestDB(ctx) + require.NoError(t, err) + defer db.Close() + + queries := gen.New(db) + newNodeID := idwrap.NewNow() + + nrsService := sflow.NewNodeRequestService(queries) + ngqsService := sflow.NewNodeGraphQLService(queries) + nwcsService := sflow.NewNodeWsConnectionService(queries) + nwssService := sflow.NewNodeWsSendService(queries) + nwaitsService := sflow.NewNodeWaitService(queries) + + tests := []struct { + name string + handler NodeConfigSnapshot + config any // typed nil pointer + }{ + { + name: "Request typed nil", + handler: &RequestSnapshot{Service: &nrsService}, + config: (*mflow.NodeRequest)(nil), + }, + { + name: "GraphQL typed nil", + handler: &GraphQLSnapshot{Service: &ngqsService}, + config: (*mflow.NodeGraphQL)(nil), + }, + { + name: "WsConnection typed nil", + handler: &WsConnectionSnapshot{Service: &nwcsService}, + config: (*mflow.NodeWsConnection)(nil), + }, + { + name: "WsSend typed nil", + handler: &WsSendSnapshot{Service: &nwssService}, + config: (*mflow.NodeWsSend)(nil), + }, + { + name: "Wait typed nil", + handler: &WaitSnapshot{Service: &nwaitsService}, + config: (*mflow.NodeWait)(nil), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Should NOT panic — must handle typed nil gracefully + result, err := tt.handler.WriteTx(ctx, nil, newNodeID, tt.config) + assert.NoError(t, err) + assert.Nil(t, result) + }) + } +} + +// TestWriteTx_DefaultsWithTypedNil verifies that "always create with defaults" +// snapshot types create valid records even with typed nil config. +func TestWriteTx_DefaultsWithTypedNil(t *testing.T) { + t.Parallel() + + ctx := context.Background() + db, err := dbtest.GetTestDB(ctx) + require.NoError(t, err) + defer db.Close() + + queries := gen.New(db) + + // Create required parent records + flowID := idwrap.NewNow() + err = queries.CreateFlow(ctx, gen.CreateFlowParams{ + ID: flowID, + WorkspaceID: idwrap.NewNow(), + Name: "test", + }) + require.NoError(t, err) + + nfsService := sflow.NewNodeForService(queries) + naisService := sflow.NewNodeAIService(queries) + nmemsService := sflow.NewNodeMemoryService(queries) + + tests := []struct { + name string + handler NodeConfigSnapshot + config any + checkDefaults func(t *testing.T, result any) + }{ + { + name: "For with typed nil uses defaults", + handler: &ForSnapshot{Service: &nfsService}, + config: (*mflow.NodeFor)(nil), + checkDefaults: func(t *testing.T, result any) { + data := result.(mflow.NodeFor) + assert.Equal(t, int64(1), data.IterCount, "default IterCount") + assert.Equal(t, mflow.ErrorHandling_ERROR_HANDLING_BREAK, data.ErrorHandling, "default ErrorHandling") + }, + }, + { + name: "For with config copies values", + handler: &ForSnapshot{Service: &nfsService}, + config: &mflow.NodeFor{ + IterCount: 10, + ErrorHandling: mflow.ErrorHandling_ERROR_HANDLING_IGNORE, + }, + checkDefaults: func(t *testing.T, result any) { + data := result.(mflow.NodeFor) + assert.Equal(t, int64(10), data.IterCount, "copied IterCount") + assert.Equal(t, mflow.ErrorHandling_ERROR_HANDLING_IGNORE, data.ErrorHandling, "copied ErrorHandling") + }, + }, + { + name: "AI with typed nil uses defaults", + handler: &AISnapshot{Service: &naisService}, + config: (*mflow.NodeAI)(nil), + checkDefaults: func(t *testing.T, result any) { + data := result.(mflow.NodeAI) + assert.Equal(t, "", data.Prompt, "default Prompt") + assert.Equal(t, int32(5), data.MaxIterations, "default MaxIterations") + }, + }, + { + name: "Memory with typed nil uses defaults", + handler: &MemorySnapshot{Service: &nmemsService}, + config: (*mflow.NodeMemory)(nil), + checkDefaults: func(t *testing.T, result any) { + data := result.(mflow.NodeMemory) + assert.Equal(t, mflow.AiMemoryTypeWindowBuffer, data.MemoryType) + assert.Equal(t, int32(10), data.WindowSize) + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + nodeID := idwrap.NewNow() + err := queries.CreateFlowNode(ctx, gen.CreateFlowNodeParams{ + ID: nodeID, + FlowID: flowID, + Name: tt.name, + NodeKind: int32(tt.handler.Kind()), + }) + require.NoError(t, err) + + tx, err := db.BeginTx(ctx, nil) + require.NoError(t, err) + defer tx.Rollback() //nolint:errcheck + + result, err := tt.handler.WriteTx(ctx, tx, nodeID, tt.config) + require.NoError(t, err) + require.NotNil(t, result) + + tt.checkDefaults(t, result) + + err = tx.Commit() + require.NoError(t, err) + }) + } +} + +// TestWriteTx_UntypedNil verifies that pure nil (not typed nil) is also handled. +func TestWriteTx_UntypedNil(t *testing.T) { + t.Parallel() + + ctx := context.Background() + db, err := dbtest.GetTestDB(ctx) + require.NoError(t, err) + defer db.Close() + + queries := gen.New(db) + nrsService := sflow.NewNodeRequestService(queries) + + handler := &RequestSnapshot{Service: &nrsService} + result, err := handler.WriteTx(ctx, nil, idwrap.NewNow(), nil) + assert.NoError(t, err) + assert.Nil(t, result) +} diff --git a/packages/server/pkg/flow/flowresult/drain.go b/packages/server/pkg/flow/flowresult/drain.go new file mode 100644 index 000000000..d15b9952a --- /dev/null +++ b/packages/server/pkg/flow/flowresult/drain.go @@ -0,0 +1,212 @@ +package flowresult + +import ( + "context" + "log/slog" + "sync" + + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node/ngraphql" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node/nrequest" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mgraphql" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sgraphql" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/shttp" +) + +// ResponseDrain persists HTTP and GraphQL responses produced during flow execution. +// It runs two goroutines (one per protocol) that consume from channels, persist +// to the database, publish events, and signal completion via per-response channels. +// +// The signal mechanism allows the ExecutionStateTracker to wait for a response +// to be published before publishing the execution event that references it, +// ensuring correct event ordering for frontends. +type ResponseDrain struct { + workspaceID idwrap.IDWrap + + httpChan chan nrequest.NodeRequestSideResp + gqlChan chan ngraphql.NodeGraphQLSideResp + + // Per-response signal: closed when the response has been persisted and published. + httpSignals map[string]chan struct{} + httpSignalsMu sync.Mutex + gqlSignals map[string]chan struct{} + gqlSignalsMu sync.Mutex + + httpSvc shttp.HttpResponseService + gqlSvc sgraphql.GraphQLResponseService + + publisher EventPublisher + logger *slog.Logger + + httpWg sync.WaitGroup + gqlWg sync.WaitGroup +} + +// ResponseDrainOpts configures a ResponseDrain. +type ResponseDrainOpts struct { + WorkspaceID idwrap.IDWrap + BufSize int + + HTTPResponseService shttp.HttpResponseService + GraphQLResponseService sgraphql.GraphQLResponseService + + Publisher EventPublisher + Logger *slog.Logger +} + +func newResponseDrain(opts ResponseDrainOpts) *ResponseDrain { + return &ResponseDrain{ + workspaceID: opts.WorkspaceID, + httpChan: make(chan nrequest.NodeRequestSideResp, opts.BufSize), + gqlChan: make(chan ngraphql.NodeGraphQLSideResp, opts.BufSize), + httpSignals: make(map[string]chan struct{}), + gqlSignals: make(map[string]chan struct{}), + httpSvc: opts.HTTPResponseService, + gqlSvc: opts.GraphQLResponseService, + publisher: opts.Publisher, + logger: opts.Logger, + } +} + +func (d *ResponseDrain) start(ctx context.Context) { + d.httpWg.Add(1) + go d.runHTTP(ctx) + + d.gqlWg.Add(1) + go d.runGraphQL(ctx) +} + +// closeAndWait closes both channels and waits for goroutines to finish. +func (d *ResponseDrain) closeAndWait() { + close(d.httpChan) + d.httpWg.Wait() + + close(d.gqlChan) + d.gqlWg.Wait() +} + +// WaitForResponse blocks until the response with the given ID has been +// persisted and its event published. Call this before publishing an +// execution event that references the response. +func (d *ResponseDrain) WaitForResponse(respID string) { + // Check HTTP signals + d.httpSignalsMu.Lock() + ch, ok := d.httpSignals[respID] + d.httpSignalsMu.Unlock() + if ok { + <-ch + d.httpSignalsMu.Lock() + delete(d.httpSignals, respID) + d.httpSignalsMu.Unlock() + } + + // Check GraphQL signals + d.gqlSignalsMu.Lock() + ch, ok = d.gqlSignals[respID] + d.gqlSignalsMu.Unlock() + if ok { + <-ch + d.gqlSignalsMu.Lock() + delete(d.gqlSignals, respID) + d.gqlSignalsMu.Unlock() + } +} + +func (d *ResponseDrain) runHTTP(ctx context.Context) { + defer d.httpWg.Done() + for resp := range d.httpChan { + responseID := resp.Resp.HTTPResponse.ID.String() + + // Register signal before processing so state tracker can find it + d.httpSignalsMu.Lock() + signal := make(chan struct{}) + d.httpSignals[responseID] = signal + d.httpSignalsMu.Unlock() + + // Save HTTP Response + if err := d.httpSvc.Create(ctx, resp.Resp.HTTPResponse); err != nil { + d.logger.Error("failed to save http response", "error", err) + } else { + d.publisher.PublishHTTPResponse(resp.Resp.HTTPResponse, d.workspaceID) + } + + // Save Headers + for _, h := range resp.Resp.ResponseHeaders { + if err := d.httpSvc.CreateHeader(ctx, h); err != nil { + d.logger.Error("failed to save http response header", "error", err) + } else { + d.publisher.PublishHTTPResponseHeader(h, d.workspaceID) + } + } + + // Save Asserts + for _, a := range resp.Resp.ResponseAsserts { + if err := d.httpSvc.CreateAssert(ctx, a); err != nil { + d.logger.Error("failed to save http response assert", "error", err) + } else { + d.publisher.PublishHTTPResponseAssert(a, d.workspaceID) + } + } + + close(signal) + + if resp.Done != nil { + close(resp.Done) + } + } +} + +func (d *ResponseDrain) runGraphQL(ctx context.Context) { + defer d.gqlWg.Done() + for resp := range d.gqlChan { + responseID := resp.Response.ID.String() + + d.gqlSignalsMu.Lock() + signal := make(chan struct{}) + d.gqlSignals[responseID] = signal + d.gqlSignalsMu.Unlock() + + // Save all entities first, THEN publish events + responseSuccess := false + if err := d.gqlSvc.Create(ctx, resp.Response); err != nil { + d.logger.Error("failed to save graphql response", "error", err) + } else { + responseSuccess = true + } + + var successHeaders []mgraphql.GraphQLResponseHeader + for _, h := range resp.RespHeaders { + if err := d.gqlSvc.CreateHeader(ctx, h); err != nil { + d.logger.Error("failed to save graphql response header", "error", err) + } else { + successHeaders = append(successHeaders, h) + } + } + + var successAsserts []mgraphql.GraphQLResponseAssert + for _, a := range resp.RespAsserts { + if err := d.gqlSvc.CreateAssert(ctx, a); err != nil { + d.logger.Error("failed to save graphql response assert", "error", err) + } else { + successAsserts = append(successAsserts, a) + } + } + + // Publish events atomically after saves + if responseSuccess { + d.publisher.PublishGraphQLResponse(resp.Response, d.workspaceID) + for _, h := range successHeaders { + d.publisher.PublishGraphQLResponseHeader(h, d.workspaceID) + } + for _, a := range successAsserts { + d.publisher.PublishGraphQLResponseAssert(a, d.workspaceID) + } + } + + close(signal) + + if resp.Done != nil { + close(resp.Done) + } + } +} diff --git a/packages/server/pkg/flow/flowresult/noop.go b/packages/server/pkg/flow/flowresult/noop.go new file mode 100644 index 000000000..509e2927e --- /dev/null +++ b/packages/server/pkg/flow/flowresult/noop.go @@ -0,0 +1,70 @@ +package flowresult + +import ( + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node/ngraphql" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node/nrequest" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/runner" +) + +// NoopResultProcessor discards all execution results. +// Used for testing and CLI where persistence/events are not needed. +type NoopResultProcessor struct { + httpChan chan nrequest.NodeRequestSideResp + gqlChan chan ngraphql.NodeGraphQLSideResp + stateChan chan runner.FlowNodeStatus +} + +var _ ResultProcessor = (*NoopResultProcessor)(nil) + +func NewNoopResultProcessor(nodeCount int) *NoopResultProcessor { + bufSize := nodeCount*2 + 1 + return &NoopResultProcessor{ + httpChan: make(chan nrequest.NodeRequestSideResp, bufSize), + gqlChan: make(chan ngraphql.NodeGraphQLSideResp, bufSize), + stateChan: make(chan runner.FlowNodeStatus, bufSize), + } +} + +func (n *NoopResultProcessor) HTTPResponseChan() chan nrequest.NodeRequestSideResp { + return n.httpChan +} + +func (n *NoopResultProcessor) GraphQLResponseChan() chan ngraphql.NodeGraphQLSideResp { + return n.gqlChan +} + +func (n *NoopResultProcessor) NodeStateChan() chan runner.FlowNodeStatus { + return n.stateChan +} + +func (n *NoopResultProcessor) Start() { + // Drain HTTP responses + go func() { + for resp := range n.httpChan { + if resp.Done != nil { + close(resp.Done) + } + } + }() + + // Drain GraphQL responses + go func() { + for resp := range n.gqlChan { + if resp.Done != nil { + close(resp.Done) + } + } + }() + + // Drain node statuses + go func() { + //nolint:revive // intentional empty drain + for range n.stateChan { + } + }() +} + +func (n *NoopResultProcessor) Wait() { + // Channels are closed by their producers (runner closes stateChan). + // Response channels should be closed by the caller after the runner completes. +} diff --git a/packages/server/pkg/flow/flowresult/processor.go b/packages/server/pkg/flow/flowresult/processor.go new file mode 100644 index 000000000..6471e8cf6 --- /dev/null +++ b/packages/server/pkg/flow/flowresult/processor.go @@ -0,0 +1,152 @@ +package flowresult + +import ( + "context" + "log/slog" + + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node/ngraphql" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node/nrequest" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/runner" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sflow" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sgraphql" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/shttp" +) + +// ResultProcessor handles the side effects of flow execution: +// response persistence, execution state tracking, and event publishing. +// +// Channel accessors are exposed because local execution requires wiring +// channels between the node builder (producer) and the processor (consumer). +// In a distributed scenario, remote workers would use their own channels +// locally and send results back via RPC to a different ResultProcessor +// implementation that doesn't need these channels. +type ResultProcessor interface { + // HTTPResponseChan returns the channel for HTTP response side-effects. + // Pass this to the node builder so request nodes can send responses. + HTTPResponseChan() chan nrequest.NodeRequestSideResp + + // GraphQLResponseChan returns the channel for GraphQL response side-effects. + // Pass this to the node builder so GraphQL nodes can send responses. + GraphQLResponseChan() chan ngraphql.NodeGraphQLSideResp + + // NodeStateChan returns the channel for node execution status events. + // Pass this to the FlowRunner via FlowEventChannels.NodeStates. + NodeStateChan() chan runner.FlowNodeStatus + + // Start begins the drain goroutines that process responses and status events. + // Must be called before the flow runner starts. + Start() + + // Wait blocks until all processing is complete. + // The runner must have finished (closing NodeStateChan) before Wait returns. + // Wait also closes the response channels and waits for their drains. + Wait() +} + +// ServerResultProcessorOpts configures a ServerResultProcessor. +type ServerResultProcessorOpts struct { + FlowID idwrap.IDWrap + WorkspaceID idwrap.IDWrap + + // Flow data — maps are built internally from these + Nodes []mflow.Node + Edges []mflow.Edge + NodeIDMapping map[string]idwrap.IDWrap // original → versioned node ID mapping + + // Services for persistence + HTTPResponseService shttp.HttpResponseService + GraphQLResponseService sgraphql.GraphQLResponseService + NodeExecutionService *sflow.NodeExecutionService + NodeService *sflow.NodeService + EdgeService *sflow.EdgeService + + // Event publishing + Publisher EventPublisher + Logger *slog.Logger +} + +// ServerResultProcessor coordinates response persistence (ResponseDrain) +// and execution state tracking (ExecutionStateTracker) during flow execution. +type ServerResultProcessor struct { + drain *ResponseDrain + tracker *ExecutionStateTracker +} + +var _ ResultProcessor = (*ServerResultProcessor)(nil) + +// NewServerResultProcessor creates a processor that persists execution results +// and publishes real-time events for connected clients. +func NewServerResultProcessor(opts ServerResultProcessorOpts) *ServerResultProcessor { + bufSize := len(opts.Nodes)*2 + 1 + + // Build lookup maps from raw flow data + nodeKindMap := make(map[idwrap.IDWrap]mflow.NodeKind, len(opts.Nodes)) + for _, node := range opts.Nodes { + nodeKindMap[node.ID] = node.NodeKind + } + edgesBySource := make(map[idwrap.IDWrap][]mflow.Edge, len(opts.Edges)) + for _, edge := range opts.Edges { + edgesBySource[edge.SourceID] = append(edgesBySource[edge.SourceID], edge) + } + inverseNodeIDMap := make(map[string]idwrap.IDWrap, len(opts.NodeIDMapping)) + for k, v := range opts.NodeIDMapping { + inverseNodeIDMap[v.String()] = idwrap.NewTextMust(k) + } + + drain := newResponseDrain(ResponseDrainOpts{ + WorkspaceID: opts.WorkspaceID, + BufSize: bufSize, + HTTPResponseService: opts.HTTPResponseService, + GraphQLResponseService: opts.GraphQLResponseService, + Publisher: opts.Publisher, + Logger: opts.Logger, + }) + + tracker := newExecutionStateTracker(ExecutionStateTrackerOpts{ + FlowID: opts.FlowID, + BufSize: bufSize, + NodeKindMap: nodeKindMap, + EdgesBySource: edgesBySource, + InverseNodeIDMap: inverseNodeIDMap, + Drain: drain, + NodeExecutionService: opts.NodeExecutionService, + NodeService: opts.NodeService, + EdgeService: opts.EdgeService, + Publisher: opts.Publisher, + Logger: opts.Logger, + }) + + return &ServerResultProcessor{ + drain: drain, + tracker: tracker, + } +} + +func (p *ServerResultProcessor) HTTPResponseChan() chan nrequest.NodeRequestSideResp { + return p.drain.httpChan +} + +func (p *ServerResultProcessor) GraphQLResponseChan() chan ngraphql.NodeGraphQLSideResp { + return p.drain.gqlChan +} + +func (p *ServerResultProcessor) NodeStateChan() chan runner.FlowNodeStatus { + return p.tracker.stateChan +} + +func (p *ServerResultProcessor) Start() { + // Background context: persistence must outlive flow cancellation + ctx := context.Background() + p.drain.start(ctx) + p.tracker.start(ctx) +} + +// Wait blocks until all processing completes. +// Order: state tracker finishes (nodeStateChan closed by runner) → +// close response channels → response drains finish. +func (p *ServerResultProcessor) Wait() { + p.tracker.wait() + p.drain.closeAndWait() +} diff --git a/packages/server/pkg/flow/flowresult/publisher.go b/packages/server/pkg/flow/flowresult/publisher.go new file mode 100644 index 000000000..f0009867f --- /dev/null +++ b/packages/server/pkg/flow/flowresult/publisher.go @@ -0,0 +1,28 @@ +// Package flowresult handles the side effects of flow execution: +// response persistence, execution state tracking, and event publishing. +package flowresult + +import ( + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/runner" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mgraphql" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mhttp" +) + +// EventPublisher abstracts the event stream publishing that happens during flow execution. +// The rflowv2 package provides the concrete implementation backed by eventstream.SyncStreamer. +type EventPublisher interface { + PublishHTTPResponse(response mhttp.HTTPResponse, workspaceID idwrap.IDWrap) + PublishHTTPResponseHeader(header mhttp.HTTPResponseHeader, workspaceID idwrap.IDWrap) + PublishHTTPResponseAssert(assert mhttp.HTTPResponseAssert, workspaceID idwrap.IDWrap) + + PublishGraphQLResponse(response mgraphql.GraphQLResponse, workspaceID idwrap.IDWrap) + PublishGraphQLResponseHeader(header mgraphql.GraphQLResponseHeader, workspaceID idwrap.IDWrap) + PublishGraphQLResponseAssert(assert mgraphql.GraphQLResponseAssert, workspaceID idwrap.IDWrap) + + PublishExecution(eventType string, execution mflow.NodeExecution, flowID idwrap.IDWrap) + PublishNodeState(flowID, originalNodeID idwrap.IDWrap, state mflow.NodeState, info string) + PublishEdgeState(edge mflow.Edge) + PublishLog(flowID idwrap.IDWrap, status runner.FlowNodeStatus) +} diff --git a/packages/server/pkg/flow/flowresult/statetracker.go b/packages/server/pkg/flow/flowresult/statetracker.go new file mode 100644 index 000000000..1550ccb3b --- /dev/null +++ b/packages/server/pkg/flow/flowresult/statetracker.go @@ -0,0 +1,247 @@ +package flowresult + +import ( + "context" + "encoding/json" + "fmt" + "log/slog" + "sync" + "time" + + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/runner" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sflow" +) + +// ExecutionStateTracker handles node execution lifecycle events: +// - Persists NodeExecution records (with dedup via execution cache) +// - Updates node and edge states in the database +// - Waits for response signals from ResponseDrain before publishing execution events +// - Publishes node state, edge state, and log events +type ExecutionStateTracker struct { + flowID idwrap.IDWrap + + nodeKindMap map[idwrap.IDWrap]mflow.NodeKind + edgesBySource map[idwrap.IDWrap][]mflow.Edge + inverseNodeIDMap map[string]idwrap.IDWrap + + stateChan chan runner.FlowNodeStatus + + drain *ResponseDrain + + nodeExecSvc *sflow.NodeExecutionService + nodeSvc *sflow.NodeService + edgeSvc *sflow.EdgeService + + publisher EventPublisher + logger *slog.Logger + + wg sync.WaitGroup +} + +// ExecutionStateTrackerOpts configures an ExecutionStateTracker. +type ExecutionStateTrackerOpts struct { + FlowID idwrap.IDWrap + BufSize int + + NodeKindMap map[idwrap.IDWrap]mflow.NodeKind + EdgesBySource map[idwrap.IDWrap][]mflow.Edge + InverseNodeIDMap map[string]idwrap.IDWrap + + Drain *ResponseDrain + + NodeExecutionService *sflow.NodeExecutionService + NodeService *sflow.NodeService + EdgeService *sflow.EdgeService + + Publisher EventPublisher + Logger *slog.Logger +} + +func newExecutionStateTracker(opts ExecutionStateTrackerOpts) *ExecutionStateTracker { + return &ExecutionStateTracker{ + flowID: opts.FlowID, + nodeKindMap: opts.NodeKindMap, + edgesBySource: opts.EdgesBySource, + inverseNodeIDMap: opts.InverseNodeIDMap, + stateChan: make(chan runner.FlowNodeStatus, opts.BufSize), + drain: opts.Drain, + nodeExecSvc: opts.NodeExecutionService, + nodeSvc: opts.NodeService, + edgeSvc: opts.EdgeService, + publisher: opts.Publisher, + logger: opts.Logger, + } +} + +func (t *ExecutionStateTracker) start(ctx context.Context) { + t.wg.Add(1) + go t.run(ctx) +} + +func (t *ExecutionStateTracker) wait() { + t.wg.Wait() +} + +func (t *ExecutionStateTracker) run(ctx context.Context) { + defer t.wg.Done() + + // Execution cache: prevents duplicate NodeExecution creation for same iteration + executionCache := make(map[string]idwrap.IDWrap) + + for status := range t.stateChan { + t.processStatus(ctx, status, executionCache) + } +} + +func (t *ExecutionStateTracker) processStatus(ctx context.Context, status runner.FlowNodeStatus, executionCache map[string]idwrap.IDWrap) { + // Find the original node ID if this is a versioned ID + originalNodeID := status.NodeID + if origID, ok := t.inverseNodeIDMap[status.NodeID.String()]; ok { + originalNodeID = origID + } + + // Check if this is a loop coordinator wrapper status + nodeKind := t.nodeKindMap[status.NodeID] + isLoopNode := nodeKind == mflow.NODE_KIND_FOR || nodeKind == mflow.NODE_KIND_FOR_EACH || nodeKind == mflow.NODE_KIND_WS_CONNECTION + skipExecution := isLoopNode && !status.IterationEvent + + // Persist execution state (skip for loop node wrapper statuses) + if !skipExecution { + t.persistExecution(ctx, status, executionCache) + } + + // Update node state in database + if err := t.nodeSvc.UpdateNodeState(ctx, status.NodeID, status.State); err != nil { + t.logger.Error("failed to update node state", "node_id", status.NodeID.String(), "error", err) + } + + // Update edge states based on node execution state + if status.State == mflow.NODE_STATE_SUCCESS || status.State == mflow.NODE_STATE_FAILURE { + edgesFromNode := t.edgesBySource[status.NodeID] + edgeState := mflow.NODE_STATE_SUCCESS + if status.State == mflow.NODE_STATE_FAILURE { + edgeState = mflow.NODE_STATE_FAILURE + } + for _, edge := range edgesFromNode { + if err := t.edgeSvc.UpdateEdgeState(ctx, edge.ID, edgeState); err != nil { + t.logger.Error("failed to update edge state", "edge_id", edge.ID.String(), "error", err) + } else { + updatedEdge := edge + updatedEdge.State = edgeState + t.publisher.PublishEdgeState(updatedEdge) + } + } + } + + // Publish node state event (map versioned ID back to original for live sync) + var info string + if status.Error != nil { + info = status.Error.Error() + } else { + iterIndex := -1 + if status.IterationEvent { + iterIndex = status.IterationIndex + } else if status.IterationContext != nil { + iterIndex = status.IterationContext.ExecutionIndex + } + if iterIndex >= 0 { + info = fmt.Sprintf("Iter: %d", iterIndex+1) + } + } + t.publisher.PublishNodeState(t.flowID, originalNodeID, status.State, info) + + // Publish log event for terminal states + if status.State != mflow.NODE_STATE_RUNNING { + t.publisher.PublishLog(t.flowID, status) + } +} + +func (t *ExecutionStateTracker) persistExecution(ctx context.Context, status runner.FlowNodeStatus, executionCache map[string]idwrap.IDWrap) { + execID := status.ExecutionID + isNewExecution := false + + if isZeroID(execID) { + // Construct cache key based on node and iteration context + cacheKey := status.NodeID.String() + if status.IterationContext != nil { + cacheKey = fmt.Sprintf("%s:%v:%d", cacheKey, status.IterationContext.IterationPath, status.IterationContext.ExecutionIndex) + } else if status.IterationIndex >= 0 { + cacheKey = fmt.Sprintf("%s:%d", cacheKey, status.IterationIndex) + } + + if cachedID, ok := executionCache[cacheKey]; ok { + execID = cachedID + } else { + execID = idwrap.NewMonotonic() + executionCache[cacheKey] = execID + isNewExecution = true + } + } + + executionName := fmt.Sprintf("%s - %s", status.Name, time.Now().Format("2006-01-02 15:04")) + + model := mflow.NodeExecution{ + ID: execID, + NodeID: status.NodeID, + Name: executionName, + State: status.State, + } + + // Set the appropriate response ID based on node kind + nodeKindForAux := t.nodeKindMap[status.NodeID] + if status.AuxiliaryID != nil { + if nodeKindForAux == mflow.NODE_KIND_GRAPHQL { + model.GraphQLResponseID = status.AuxiliaryID + } else { + model.ResponseID = status.AuxiliaryID + } + } + + if status.Error != nil { + errStr := status.Error.Error() + model.Error = &errStr + } + + if status.InputData != nil { + if b, err := json.Marshal(status.InputData); err == nil { + _ = model.SetInputJSON(b) + } + } + if status.OutputData != nil { + if b, err := json.Marshal(status.OutputData); err == nil { + _ = model.SetOutputJSON(b) + } + } + + // Set CompletedAt for terminal states + if status.State == mflow.NODE_STATE_SUCCESS || + status.State == mflow.NODE_STATE_FAILURE || + status.State == mflow.NODE_STATE_CANCELED { + now := time.Now().Unix() + model.CompletedAt = &now + } + + eventType := "insert" + if !isNewExecution && (status.State == mflow.NODE_STATE_SUCCESS || + status.State == mflow.NODE_STATE_FAILURE || + status.State == mflow.NODE_STATE_CANCELED) { + eventType = "update" + } + + if err := t.nodeExecSvc.UpsertNodeExecution(ctx, model); err != nil { + t.logger.Error("failed to persist node execution", "error", err) + } + + // Wait for response to be published before publishing execution event + if status.AuxiliaryID != nil { + t.drain.WaitForResponse(status.AuxiliaryID.String()) + } + + t.publisher.PublishExecution(eventType, model, t.flowID) +} + +func isZeroID(id idwrap.IDWrap) bool { + return id == idwrap.IDWrap{} +} diff --git a/packages/server/pkg/flow/node/entry.go b/packages/server/pkg/flow/node/entry.go new file mode 100644 index 000000000..7cf1e625e --- /dev/null +++ b/packages/server/pkg/flow/node/entry.go @@ -0,0 +1,26 @@ +//nolint:revive // exported +package node + +// EntryNode marks a node as a valid flow entry point (no incoming edges expected). +// The runner collects all EntryNodes and starts them concurrently. +type EntryNode interface { + FlowNode + IsEntryNode() bool +} + +// ListenerEntry is an entry node that runs for the flow's lifetime, +// receiving events in a loop (e.g., WebSocket Connection). +// It implements LoopCoordinator so the runner doesn't apply per-node timeout. +type ListenerEntry interface { + EntryNode + LoopCoordinator +} + +// TriggerEntry is an entry node whose external event initiates the flow run. +// Examples: Webhook (HTTP request triggers flow), Queue (message triggers flow). +// The trigger payload is written to VarMap before downstream nodes execute. +type TriggerEntry interface { + EntryNode + // TriggerType returns a string identifier for the trigger kind (e.g., "webhook", "queue"). + TriggerType() string +} diff --git a/packages/server/pkg/flow/node/nfor/nfor_test.go b/packages/server/pkg/flow/node/nfor/nfor_test.go index e8e2cc7e0..813411261 100644 --- a/packages/server/pkg/flow/node/nfor/nfor_test.go +++ b/packages/server/pkg/flow/node/nfor/nfor_test.go @@ -98,7 +98,7 @@ func TestNodeForDefaultErrorDoesNotLogLoopFailure(t *testing.T) { }, } - flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), loopID, map[idwrap.IDWrap]node.FlowNode{ + flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), []idwrap.IDWrap{loopID}, map[idwrap.IDWrap]node.FlowNode{ loopID: loop, childID: child, }, edgeMap, 0, nil) @@ -165,7 +165,7 @@ func TestNodeForSetsIterationEventFlag(t *testing.T) { }, } - flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), loopID, map[idwrap.IDWrap]node.FlowNode{ + flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), []idwrap.IDWrap{loopID}, map[idwrap.IDWrap]node.FlowNode{ loopID: loop, }, edgeMap, 0, nil) @@ -225,7 +225,7 @@ func TestNodeForSkipsDuplicateLoopEntryTargets(t *testing.T) { flowRunner := flowlocalrunner.CreateFlowRunner( idwrap.NewNow(), idwrap.NewNow(), - loopID, + []idwrap.IDWrap{loopID}, map[idwrap.IDWrap]node.FlowNode{ loopID: loop, nodeAID: nodeA, diff --git a/packages/server/pkg/flow/node/nforeach/nforeach_test.go b/packages/server/pkg/flow/node/nforeach/nforeach_test.go index a2f744921..f8d71c471 100644 --- a/packages/server/pkg/flow/node/nforeach/nforeach_test.go +++ b/packages/server/pkg/flow/node/nforeach/nforeach_test.go @@ -101,7 +101,7 @@ func TestNodeForEachDefaultErrorDoesNotLogLoopFailure(t *testing.T) { }, } - flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), loopID, map[idwrap.IDWrap]node.FlowNode{ + flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), []idwrap.IDWrap{loopID}, map[idwrap.IDWrap]node.FlowNode{ loopID: loop, childID: child, }, edgeMap, 0, nil) @@ -167,7 +167,7 @@ func TestNodeForEachSetsIterationEventFlag(t *testing.T) { }, } - flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), loopID, map[idwrap.IDWrap]node.FlowNode{ + flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), []idwrap.IDWrap{loopID}, map[idwrap.IDWrap]node.FlowNode{ loopID: loop, }, edgeMap, 0, nil) @@ -228,7 +228,7 @@ func TestNodeForEachSkipsDuplicateLoopEntryTargets(t *testing.T) { flowRunner := flowlocalrunner.CreateFlowRunner( idwrap.NewNow(), idwrap.NewNow(), - loopID, + []idwrap.IDWrap{loopID}, map[idwrap.IDWrap]node.FlowNode{ loopID: loop, nodeAID: nodeA, diff --git a/packages/server/pkg/flow/node/node.go b/packages/server/pkg/flow/node/node.go index 7435e8295..c7dc06894 100644 --- a/packages/server/pkg/flow/node/node.go +++ b/packages/server/pkg/flow/node/node.go @@ -56,6 +56,7 @@ type FlowNodeRequest struct { Timeout time.Duration LogPushFunc LogPushFunc PendingAtmoicMap map[idwrap.IDWrap]uint32 + PendingMapMu *sync.Mutex // Thread-safe pending map across concurrent entry chains VariableTracker *tracking.VariableTracker // Optional tracking for input/output data IterationContext *runner.IterationContext // For hierarchical execution naming in loops ExecutionID idwrap.IDWrap // Unique ID for this specific execution of the node @@ -239,36 +240,44 @@ func FilterLoopEntryNodes(edgeMap mflow.EdgesMap, loopTargets []idwrap.IDWrap) [ // When the requested targets already match the existing loop edges, the // original map is returned to avoid unnecessary allocations. func BuildLoopExecutionEdgeMap(edgeMap mflow.EdgesMap, loopNodeID idwrap.IDWrap, loopTargets []idwrap.IDWrap) mflow.EdgesMap { - if len(loopTargets) == 0 { + return BuildHandleExecutionEdgeMap(edgeMap, loopNodeID, mflow.HandleLoop, loopTargets) +} + +// BuildHandleExecutionEdgeMap returns an edge map suitable for executing a +// sub-chain connected via the given handle. It rewrites the handle on nodeID +// to include only the provided targets so duplicate edges to downstream nodes +// do not participate in scheduling decisions. +func BuildHandleExecutionEdgeMap(edgeMap mflow.EdgesMap, nodeID idwrap.IDWrap, handle mflow.EdgeHandle, targets []idwrap.IDWrap) mflow.EdgesMap { + if len(targets) == 0 { return edgeMap } - loopHandles, ok := edgeMap[loopNodeID] + handles, ok := edgeMap[nodeID] if ok { - if current, ok := loopHandles[mflow.HandleLoop]; ok && equalIDSlice(current, loopTargets) { + if current, ok := handles[handle]; ok && equalIDSlice(current, targets) { return edgeMap } } cloned := make(mflow.EdgesMap, len(edgeMap)) - for sourceID, handles := range edgeMap { - handleMap := make(map[mflow.EdgeHandle][]idwrap.IDWrap, len(handles)) - for handle, targets := range handles { - if sourceID == loopNodeID && handle == mflow.HandleLoop { - handleMap[handle] = append([]idwrap.IDWrap(nil), loopTargets...) + for sourceID, srcHandles := range edgeMap { + handleMap := make(map[mflow.EdgeHandle][]idwrap.IDWrap, len(srcHandles)) + for h, t := range srcHandles { + if sourceID == nodeID && h == handle { + handleMap[h] = append([]idwrap.IDWrap(nil), targets...) continue } - handleMap[handle] = append([]idwrap.IDWrap(nil), targets...) + handleMap[h] = append([]idwrap.IDWrap(nil), t...) } cloned[sourceID] = handleMap } - if _, exists := cloned[loopNodeID]; !exists { - cloned[loopNodeID] = map[mflow.EdgeHandle][]idwrap.IDWrap{ - mflow.HandleLoop: append([]idwrap.IDWrap(nil), loopTargets...), + if _, exists := cloned[nodeID]; !exists { + cloned[nodeID] = map[mflow.EdgeHandle][]idwrap.IDWrap{ + handle: append([]idwrap.IDWrap(nil), targets...), } - } else if _, ok := cloned[loopNodeID][mflow.HandleLoop]; !ok { - cloned[loopNodeID][mflow.HandleLoop] = append([]idwrap.IDWrap(nil), loopTargets...) + } else if _, ok := cloned[nodeID][handle]; !ok { + cloned[nodeID][handle] = append([]idwrap.IDWrap(nil), targets...) } return cloned diff --git a/packages/server/pkg/flow/node/nstart/nstart.go b/packages/server/pkg/flow/node/nstart/nstart.go index 66aa616bc..5763090ba 100644 --- a/packages/server/pkg/flow/node/nstart/nstart.go +++ b/packages/server/pkg/flow/node/nstart/nstart.go @@ -41,6 +41,10 @@ func (nr *NodeStart) RunSync(ctx context.Context, req *node.FlowNodeRequest) nod } } +func (nr *NodeStart) IsEntryNode() bool { + return true +} + func (nr *NodeStart) RunAsync(ctx context.Context, req *node.FlowNodeRequest, resultChan chan node.FlowNodeResult) { nextID := mflow.GetNextNodeID(req.EdgeSourceMap, nr.FlowNodeID, mflow.HandleUnspecified) diff --git a/packages/server/pkg/flow/node/nwait/nwait.go b/packages/server/pkg/flow/node/nwait/nwait.go new file mode 100644 index 000000000..4cdf44f4a --- /dev/null +++ b/packages/server/pkg/flow/node/nwait/nwait.go @@ -0,0 +1,51 @@ +//nolint:revive // exported +package nwait + +import ( + "context" + "time" + + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" +) + +type NodeWait struct { + FlowNodeID idwrap.IDWrap + Name string + DurationMs int64 +} + +func New(id idwrap.IDWrap, name string, durationMs int64) *NodeWait { + return &NodeWait{ + FlowNodeID: id, + Name: name, + DurationMs: durationMs, + } +} + +func (n *NodeWait) GetID() idwrap.IDWrap { + return n.FlowNodeID +} + +func (n *NodeWait) GetName() string { + return n.Name +} + +func (n *NodeWait) RunSync(ctx context.Context, req *node.FlowNodeRequest) node.FlowNodeResult { + timer := time.NewTimer(time.Duration(n.DurationMs) * time.Millisecond) + defer timer.Stop() + + select { + case <-ctx.Done(): + return node.FlowNodeResult{Err: ctx.Err()} + case <-timer.C: + } + + nextID := mflow.GetNextNodeID(req.EdgeSourceMap, n.FlowNodeID, mflow.HandleUnspecified) + return node.FlowNodeResult{NextNodeID: nextID} +} + +func (n *NodeWait) RunAsync(ctx context.Context, req *node.FlowNodeRequest, resultChan chan node.FlowNodeResult) { + resultChan <- n.RunSync(ctx, req) +} diff --git a/packages/server/pkg/flow/node/nwsconnection/nwsconnection.go b/packages/server/pkg/flow/node/nwsconnection/nwsconnection.go new file mode 100644 index 000000000..9aa6ba0fc --- /dev/null +++ b/packages/server/pkg/flow/node/nwsconnection/nwsconnection.go @@ -0,0 +1,291 @@ +//nolint:revive // exported +package nwsconnection + +import ( + "context" + "fmt" + "net/http" + + "github.com/the-dev-tools/dev-tools/packages/server/pkg/expression" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/runner" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/runner/flowlocalrunner" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" + "github.com/coder/websocket" +) + +// Compile-time check that NodeWsConnection implements VariableIntrospector. +var _ node.VariableIntrospector = (*NodeWsConnection)(nil) + +// NodeWsConnection is a listener entry node that connects to a WebSocket +// and dispatches HandleWsMessage chains for each incoming message. +type NodeWsConnection struct { + FlowNodeID idwrap.IDWrap + Name string + URL string + Headers map[string]string +} + +func New(id idwrap.IDWrap, name string, url string, headers map[string]string) *NodeWsConnection { + return &NodeWsConnection{ + FlowNodeID: id, + Name: name, + URL: url, + Headers: headers, + } +} + +func (n *NodeWsConnection) GetID() idwrap.IDWrap { + return n.FlowNodeID +} + +func (n *NodeWsConnection) SetID(id idwrap.IDWrap) { + n.FlowNodeID = id +} + +func (n *NodeWsConnection) GetName() string { + return n.Name +} + +// IsEntryNode marks this as a valid flow entry point (no incoming edges). +func (n *NodeWsConnection) IsEntryNode() bool { + return true +} + +// IsLoopCoordinator prevents the runner from applying per-node timeout. +func (n *NodeWsConnection) IsLoopCoordinator() bool { + return true +} + +// GetRequiredVariables implements node.VariableIntrospector. +func (n *NodeWsConnection) GetRequiredVariables() []string { + sources := []string{n.URL} + for _, v := range n.Headers { + sources = append(sources, v) + } + return expression.ExtractVarKeysFromMultiple(sources...) +} + +// GetOutputVariables implements node.VariableIntrospector. +func (n *NodeWsConnection) GetOutputVariables() []string { + return []string{ + "url", + "connected", + "lastMessage", + } +} + +func (n *NodeWsConnection) RunSync(ctx context.Context, req *node.FlowNodeRequest) node.FlowNodeResult { + // Interpolate URL with variables + varMapCopy := node.DeepCopyVarMap(req) + env := newExprEnv(varMapCopy) + url, err := env.InterpolateCtx(ctx, n.URL) + if err != nil { + return node.FlowNodeResult{Err: fmt.Errorf("interpolate url: %w", err)} + } + + // Build HTTP headers + httpHeaders := http.Header{} + for k, v := range n.Headers { + interpolatedVal, err := env.InterpolateCtx(ctx, v) + if err != nil { + return node.FlowNodeResult{Err: fmt.Errorf("interpolate header %s: %w", k, err)} + } + httpHeaders.Set(k, interpolatedVal) + } + + // Dial WebSocket + conn, resp, err := websocket.Dial(ctx, url, &websocket.DialOptions{ + HTTPHeader: httpHeaders, + }) + if resp != nil && resp.Body != nil { + _ = resp.Body.Close() + } + if err != nil { + return node.FlowNodeResult{Err: fmt.Errorf("websocket dial %s: %w", url, err)} + } + + closeConn := func() { + _ = conn.Close(websocket.StatusNormalClosure, "") + } + + // Store connection in VarMap so WsSend nodes can use it + writeVar := func(key string, v any) error { + if req.VariableTracker != nil { + return node.WriteNodeVarWithTracking(req, n.Name, key, v, req.VariableTracker) + } + return node.WriteNodeVar(req, n.Name, key, v) + } + if err := writeVar("url", url); err != nil { + closeConn() + return node.FlowNodeResult{Err: fmt.Errorf("write url var: %w", err)} + } + if err := writeVar("connected", true); err != nil { + closeConn() + return node.FlowNodeResult{Err: fmt.Errorf("write connected var: %w", err)} + } + // Store the actual connection object (internal, not tracked) + if err := node.WriteNodeVar(req, n.Name, "_conn", conn); err != nil { + closeConn() + return node.FlowNodeResult{Err: fmt.Errorf("write conn var: %w", err)} + } + nextID := mflow.GetNextNodeID(req.EdgeSourceMap, n.FlowNodeID, mflow.HandleUnspecified) + + // Check for HandleWsMessage targets — if present, read messages and dispatch child chains + msgTargets := mflow.GetNextNodeID(req.EdgeSourceMap, n.FlowNodeID, mflow.HandleWsMessage) + + // No HandleWsMessage targets — just read and log messages passively + if msgTargets == nil { + go func() { + defer conn.Close(websocket.StatusNormalClosure, "done") //nolint:errcheck // best-effort cleanup + var msgIndex int + for { + select { + case <-ctx.Done(): + return + default: + } + _, msg, err := conn.Read(ctx) + if err != nil { + return + } + msgStr := string(msg) + _ = node.WriteNodeVar(req, n.Name, "lastMessage", msgStr) + + if req.LogPushFunc != nil { + executionID := idwrap.NewMonotonic() + req.LogPushFunc(runner.FlowNodeStatus{ + ExecutionID: executionID, + NodeID: n.FlowNodeID, + Name: fmt.Sprintf("%s Message %d", n.Name, msgIndex+1), + State: mflow.NODE_STATE_SUCCESS, + OutputData: map[string]any{"type": "received", "index": msgIndex, "message": msgStr}, + IterationEvent: true, + IterationIndex: msgIndex, + LoopNodeID: n.FlowNodeID, + }) + } + msgIndex++ + } + }() + return node.FlowNodeResult{NextNodeID: nextID} + } + + msgTargets = node.FilterLoopEntryNodes(req.EdgeSourceMap, msgTargets) + msgEdgeMap := node.BuildHandleExecutionEdgeMap(req.EdgeSourceMap, n.FlowNodeID, mflow.HandleWsMessage, msgTargets) + predecessorMap := flowlocalrunner.BuildPredecessorMap(msgEdgeMap) + pendingTemplate := node.BuildPendingMap(predecessorMap) + + // Read messages in a loop until context cancellation, executing the message handler chain per message + go func() { + defer conn.Close(websocket.StatusNormalClosure, "done") //nolint:errcheck // best-effort cleanup + var msgIndex int + for { + select { + case <-ctx.Done(): + return + default: + } + _, msg, err := conn.Read(ctx) + if err != nil { + return + } + + msgStr := string(msg) + _ = node.WriteNodeVar(req, n.Name, "lastMessage", msgStr) + + executionID := idwrap.NewMonotonic() + + // Build iteration context for this message + var parentPath []int + var parentNodes []idwrap.IDWrap + var parentLabels []runner.IterationLabel + if req.IterationContext != nil { + parentPath = req.IterationContext.IterationPath + parentNodes = req.IterationContext.ParentNodes + parentLabels = node.CloneIterationLabels(req.IterationContext.Labels) + } + labels := make([]runner.IterationLabel, len(parentLabels), len(parentLabels)+1) + copy(labels, parentLabels) + labels = append(labels, runner.IterationLabel{ + NodeID: n.FlowNodeID, + Name: n.Name, + Iteration: msgIndex + 1, + }) + iterContext := &runner.IterationContext{ + IterationPath: append(parentPath, msgIndex), + ParentNodes: append(parentNodes, n.FlowNodeID), + Labels: labels, + } + + executionName := fmt.Sprintf("%s Message %d", n.Name, msgIndex+1) + if req.LogPushFunc != nil { + req.LogPushFunc(runner.FlowNodeStatus{ + ExecutionID: executionID, + NodeID: n.FlowNodeID, + Name: executionName, + State: mflow.NODE_STATE_RUNNING, + OutputData: map[string]any{"type": "received", "index": msgIndex, "message": msgStr}, + IterationEvent: true, + IterationIndex: msgIndex, + LoopNodeID: n.FlowNodeID, + IterationContext: iterContext, + }) + } + + // Execute message handler chain + var iterErr error + for _, targetID := range msgTargets { + childIterCtx := &runner.IterationContext{ + IterationPath: append([]int(nil), iterContext.IterationPath...), + ExecutionIndex: msgIndex, + ParentNodes: append([]idwrap.IDWrap(nil), iterContext.ParentNodes...), + Labels: node.CloneIterationLabels(iterContext.Labels), + } + + childReq := *req + childReq.EdgeSourceMap = msgEdgeMap + childReq.PendingAtmoicMap = node.ClonePendingMap(pendingTemplate) + childReq.IterationContext = childIterCtx + childReq.ExecutionID = idwrap.NewMonotonic() + + if err := flowlocalrunner.RunNodeSync(ctx, targetID, &childReq, req.LogPushFunc, predecessorMap); err != nil { + iterErr = err + break + } + } + + if req.LogPushFunc != nil { + state := mflow.NODE_STATE_SUCCESS + if iterErr != nil { + state = mflow.NODE_STATE_FAILURE + } + req.LogPushFunc(runner.FlowNodeStatus{ + ExecutionID: executionID, + NodeID: n.FlowNodeID, + Name: executionName, + State: state, + Error: iterErr, + OutputData: map[string]any{"type": "received", "index": msgIndex, "message": msgStr}, + IterationEvent: true, + IterationIndex: msgIndex, + LoopNodeID: n.FlowNodeID, + IterationContext: iterContext, + }) + } + + msgIndex++ + } + }() + + return node.FlowNodeResult{NextNodeID: nextID} +} + +func (n *NodeWsConnection) RunAsync(ctx context.Context, req *node.FlowNodeRequest, resultChan chan node.FlowNodeResult) { + resultChan <- n.RunSync(ctx, req) +} + +func newExprEnv(varMap map[string]any) *expression.UnifiedEnv { + return expression.NewUnifiedEnv(varMap) +} diff --git a/packages/server/pkg/flow/node/nwsconnection/nwsconnection_test.go b/packages/server/pkg/flow/node/nwsconnection/nwsconnection_test.go new file mode 100644 index 000000000..3c4aa6290 --- /dev/null +++ b/packages/server/pkg/flow/node/nwsconnection/nwsconnection_test.go @@ -0,0 +1,204 @@ +package nwsconnection + +import ( + "context" + "net/http" + "net/http/httptest" + "strings" + "sync" + "testing" + "time" + + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/runner" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" + "github.com/coder/websocket" +) + +// echoServer creates a test WS server that echoes messages back. +func echoServer(t *testing.T) *httptest.Server { + t.Helper() + return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + conn, err := websocket.Accept(w, r, nil) + if err != nil { + t.Logf("accept error: %v", err) + return + } + defer conn.Close(websocket.StatusNormalClosure, "") + for { + typ, msg, err := conn.Read(r.Context()) + if err != nil { + return + } + if err := conn.Write(r.Context(), typ, msg); err != nil { + return + } + } + })) +} + +// wsURL converts an httptest server URL to a ws:// URL. +func wsURL(s *httptest.Server) string { + return "ws" + strings.TrimPrefix(s.URL, "http") +} + +func newReq(edgeMap mflow.EdgesMap, nodeMap map[idwrap.IDWrap]node.FlowNode) *node.FlowNodeRequest { + return &node.FlowNodeRequest{ + VarMap: make(map[string]any), + ReadWriteLock: &sync.RWMutex{}, + NodeMap: nodeMap, + EdgeSourceMap: edgeMap, + Timeout: 10 * time.Second, + PendingAtmoicMap: make(map[idwrap.IDWrap]uint32), + PendingMapMu: &sync.Mutex{}, + } +} + +func TestNodeWsConnection_Connect(t *testing.T) { + srv := echoServer(t) + defer srv.Close() + + nodeID := idwrap.NewNow() + n := New(nodeID, "MyWS", wsURL(srv), nil) + + req := newReq(mflow.EdgesMap{}, nil) + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + result := n.RunSync(ctx, req) + if result.Err != nil { + t.Fatalf("RunSync error: %v", result.Err) + } + + // Verify url variable + urlVal, err := node.ReadNodeVar(req, "MyWS", "url") + if err != nil { + t.Fatalf("read url var: %v", err) + } + if urlVal != wsURL(srv) { + t.Errorf("url = %v, want %v", urlVal, wsURL(srv)) + } + + // Verify connected variable + connectedVal, err := node.ReadNodeVar(req, "MyWS", "connected") + if err != nil { + t.Fatalf("read connected var: %v", err) + } + if connectedVal != true { + t.Errorf("connected = %v, want true", connectedVal) + } + + // Verify _conn is a *websocket.Conn + connVal, err := node.ReadNodeVar(req, "MyWS", "_conn") + if err != nil { + t.Fatalf("read _conn var: %v", err) + } + if _, ok := connVal.(*websocket.Conn); !ok { + t.Errorf("_conn type = %T, want *websocket.Conn", connVal) + } + + cancel() // Clean up WS connection +} + +func TestNodeWsConnection_PassiveMessageLogging(t *testing.T) { + srv := echoServer(t) + defer srv.Close() + + nodeID := idwrap.NewNow() + n := New(nodeID, "MyWS", wsURL(srv), nil) + + var statuses []runner.FlowNodeStatus + var mu sync.Mutex + logFunc := node.LogPushFunc(func(s runner.FlowNodeStatus) { + mu.Lock() + defer mu.Unlock() + statuses = append(statuses, s) + }) + + req := newReq(mflow.EdgesMap{}, nil) + req.LogPushFunc = logFunc + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + result := n.RunSync(ctx, req) + if result.Err != nil { + t.Fatalf("RunSync error: %v", result.Err) + } + + // Get the connection and send a message to trigger the passive listener + connVal, _ := node.ReadNodeVar(req, "MyWS", "_conn") + conn := connVal.(*websocket.Conn) + + if err := conn.Write(ctx, websocket.MessageText, []byte("hello")); err != nil { + t.Fatalf("write: %v", err) + } + + // Wait for the echo to be read and logged + time.Sleep(200 * time.Millisecond) + + // Verify lastMessage was set + lastMsg, err := node.ReadNodeVar(req, "MyWS", "lastMessage") + if err != nil { + t.Fatalf("read lastMessage: %v", err) + } + if lastMsg != "hello" { + t.Errorf("lastMessage = %v, want hello", lastMsg) + } + + // Verify a status was emitted + mu.Lock() + count := len(statuses) + mu.Unlock() + if count == 0 { + t.Error("expected at least one status event for the echoed message") + } + + cancel() +} + +func TestNodeWsConnection_DialError(t *testing.T) { + nodeID := idwrap.NewNow() + n := New(nodeID, "MyWS", "ws://127.0.0.1:1", nil) // nothing listening + + req := newReq(mflow.EdgesMap{}, nil) + + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + + result := n.RunSync(ctx, req) + if result.Err == nil { + t.Fatal("expected error for bad dial") + } +} + +func TestNodeWsConnection_URLInterpolation(t *testing.T) { + srv := echoServer(t) + defer srv.Close() + + nodeID := idwrap.NewNow() + n := New(nodeID, "MyWS", "{{ baseUrl }}", nil) + + req := newReq(mflow.EdgesMap{}, nil) + req.VarMap["baseUrl"] = wsURL(srv) + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + result := n.RunSync(ctx, req) + if result.Err != nil { + t.Fatalf("RunSync error: %v", result.Err) + } + + urlVal, err := node.ReadNodeVar(req, "MyWS", "url") + if err != nil { + t.Fatalf("read url var: %v", err) + } + if urlVal != wsURL(srv) { + t.Errorf("url = %v, want %v", urlVal, wsURL(srv)) + } + + cancel() +} diff --git a/packages/server/pkg/flow/node/nwssend/nwssend.go b/packages/server/pkg/flow/node/nwssend/nwssend.go new file mode 100644 index 000000000..70c5c91c7 --- /dev/null +++ b/packages/server/pkg/flow/node/nwssend/nwssend.go @@ -0,0 +1,111 @@ +//nolint:revive // exported +package nwssend + +import ( + "context" + "fmt" + + "github.com/the-dev-tools/dev-tools/packages/server/pkg/expression" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" + "github.com/coder/websocket" +) + +// Compile-time check that NodeWsSend implements VariableIntrospector. +var _ node.VariableIntrospector = (*NodeWsSend)(nil) + +// NodeWsSend sends a message to a WebSocket connection established by a WsConnection node. +type NodeWsSend struct { + FlowNodeID idwrap.IDWrap + Name string + WsConnectionNodeName string + Message string +} + +func New(id idwrap.IDWrap, name string, wsConnectionNodeName string, message string) *NodeWsSend { + return &NodeWsSend{ + FlowNodeID: id, + Name: name, + WsConnectionNodeName: wsConnectionNodeName, + Message: message, + } +} + +func (n *NodeWsSend) GetID() idwrap.IDWrap { + return n.FlowNodeID +} + +func (n *NodeWsSend) SetID(id idwrap.IDWrap) { + n.FlowNodeID = id +} + +func (n *NodeWsSend) GetName() string { + return n.Name +} + +// GetRequiredVariables implements node.VariableIntrospector. +func (n *NodeWsSend) GetRequiredVariables() []string { + return expression.ExtractVarKeysFromMultiple(n.Message, n.WsConnectionNodeName) +} + +// GetOutputVariables implements node.VariableIntrospector. +func (n *NodeWsSend) GetOutputVariables() []string { + return []string{ + "type", + "message", + "connectionNode", + } +} + +func (n *NodeWsSend) RunSync(ctx context.Context, req *node.FlowNodeRequest) node.FlowNodeResult { + // Interpolate the message template + varMapCopy := node.DeepCopyVarMap(req) + env := expression.NewUnifiedEnv(varMapCopy) + interpolated, err := env.InterpolateCtx(ctx, n.Message) + if err != nil { + return node.FlowNodeResult{Err: fmt.Errorf("interpolate message: %w", err)} + } + + // Read the WebSocket connection from the WsConnection node's VarMap + connRaw, err := node.ReadNodeVar(req, n.WsConnectionNodeName, "_conn") + if err != nil { + return node.FlowNodeResult{Err: fmt.Errorf("read ws connection from node %q: %w", n.WsConnectionNodeName, err)} + } + + conn, ok := connRaw.(*websocket.Conn) + if !ok { + return node.FlowNodeResult{Err: fmt.Errorf("ws connection from node %q is not a valid WebSocket connection", n.WsConnectionNodeName)} + } + + // Send the message + if err := conn.Write(ctx, websocket.MessageText, []byte(interpolated)); err != nil { + return node.FlowNodeResult{Err: fmt.Errorf("websocket write: %w", err)} + } + + // Write the sent message to output vars + writeVar := func(key string, v any) error { + if req.VariableTracker != nil { + return node.WriteNodeVarWithTracking(req, n.Name, key, v, req.VariableTracker) + } + return node.WriteNodeVar(req, n.Name, key, v) + } + if err := writeVar("type", "sent"); err != nil { + return node.FlowNodeResult{Err: fmt.Errorf("write type var: %w", err)} + } + if err := writeVar("message", interpolated); err != nil { + return node.FlowNodeResult{Err: fmt.Errorf("write message var: %w", err)} + } + if err := writeVar("connectionNode", n.WsConnectionNodeName); err != nil { + return node.FlowNodeResult{Err: fmt.Errorf("write connectionNode var: %w", err)} + } + + nextID := mflow.GetNextNodeID(req.EdgeSourceMap, n.FlowNodeID, mflow.HandleUnspecified) + return node.FlowNodeResult{ + NextNodeID: nextID, + } +} + +func (n *NodeWsSend) RunAsync(ctx context.Context, req *node.FlowNodeRequest, resultChan chan node.FlowNodeResult) { + resultChan <- n.RunSync(ctx, req) +} diff --git a/packages/server/pkg/flow/node/nwssend/nwssend_test.go b/packages/server/pkg/flow/node/nwssend/nwssend_test.go new file mode 100644 index 000000000..c724e8461 --- /dev/null +++ b/packages/server/pkg/flow/node/nwssend/nwssend_test.go @@ -0,0 +1,152 @@ +package nwssend + +import ( + "context" + "net/http" + "net/http/httptest" + "strings" + "sync" + "testing" + "time" + + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" + "github.com/coder/websocket" +) + +// echoServer creates a test WS server that echoes messages back. +func echoServer(t *testing.T) *httptest.Server { + t.Helper() + return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + conn, err := websocket.Accept(w, r, nil) + if err != nil { + return + } + defer conn.Close(websocket.StatusNormalClosure, "") + for { + typ, msg, err := conn.Read(r.Context()) + if err != nil { + return + } + if err := conn.Write(r.Context(), typ, msg); err != nil { + return + } + } + })) +} + +func wsURL(s *httptest.Server) string { + return "ws" + strings.TrimPrefix(s.URL, "http") +} + +func newReq(edgeMap mflow.EdgesMap) *node.FlowNodeRequest { + return &node.FlowNodeRequest{ + VarMap: make(map[string]any), + ReadWriteLock: &sync.RWMutex{}, + EdgeSourceMap: edgeMap, + Timeout: 10 * time.Second, + PendingAtmoicMap: make(map[idwrap.IDWrap]uint32), + PendingMapMu: &sync.Mutex{}, + } +} + +func TestNodeWsSend_Success(t *testing.T) { + srv := echoServer(t) + defer srv.Close() + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + // Establish a real WebSocket connection + conn, _, err := websocket.Dial(ctx, wsURL(srv), nil) + if err != nil { + t.Fatalf("dial: %v", err) + } + defer conn.Close(websocket.StatusNormalClosure, "") + + // Set up the WsSend node + nodeID := idwrap.NewNow() + n := New(nodeID, "SendMsg", "MyWS", "hello world") + + req := newReq(mflow.EdgesMap{}) + // Simulate WsConnection node having stored the connection + _ = node.WriteNodeVar(req, "MyWS", "_conn", conn) + + result := n.RunSync(ctx, req) + if result.Err != nil { + t.Fatalf("RunSync error: %v", result.Err) + } + + // Verify output variables + sentMsg, err := node.ReadNodeVar(req, "SendMsg", "message") + if err != nil { + t.Fatalf("read message: %v", err) + } + if sentMsg != "hello world" { + t.Errorf("message = %v, want hello world", sentMsg) + } + + connNode, err := node.ReadNodeVar(req, "SendMsg", "connectionNode") + if err != nil { + t.Fatalf("read connectionNode: %v", err) + } + if connNode != "MyWS" { + t.Errorf("connectionNode = %v, want MyWS", connNode) + } + + // Read the echo back to confirm message was actually sent + _, msg, err := conn.Read(ctx) + if err != nil { + t.Fatalf("read echo: %v", err) + } + if string(msg) != "hello world" { + t.Errorf("echoed = %v, want hello world", string(msg)) + } +} + +func TestNodeWsSend_Interpolation(t *testing.T) { + srv := echoServer(t) + defer srv.Close() + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + conn, _, err := websocket.Dial(ctx, wsURL(srv), nil) + if err != nil { + t.Fatalf("dial: %v", err) + } + defer conn.Close(websocket.StatusNormalClosure, "") + + nodeID := idwrap.NewNow() + n := New(nodeID, "SendMsg", "MyWS", "hello {{ name }}") + + req := newReq(mflow.EdgesMap{}) + _ = node.WriteNodeVar(req, "MyWS", "_conn", conn) + req.VarMap["name"] = "world" + + result := n.RunSync(ctx, req) + if result.Err != nil { + t.Fatalf("RunSync error: %v", result.Err) + } + + sentMsg, _ := node.ReadNodeVar(req, "SendMsg", "message") + if sentMsg != "hello world" { + t.Errorf("message = %v, want hello world", sentMsg) + } +} + +func TestNodeWsSend_MissingConnection(t *testing.T) { + nodeID := idwrap.NewNow() + n := New(nodeID, "SendMsg", "NonExistent", "hello") + + req := newReq(mflow.EdgesMap{}) + + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + + result := n.RunSync(ctx, req) + if result.Err == nil { + t.Fatal("expected error for missing connection node") + } +} diff --git a/packages/server/pkg/flow/runner/flowlocalrunner/executor.go b/packages/server/pkg/flow/runner/flowlocalrunner/executor.go new file mode 100644 index 000000000..ccd34527f --- /dev/null +++ b/packages/server/pkg/flow/runner/flowlocalrunner/executor.go @@ -0,0 +1,67 @@ +package flowlocalrunner + +import ( + "context" + "sync" + + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/tracking" +) + +// ExecutionOutcome is the raw result from executing a single node, +// including optional tracked variable data. +type ExecutionOutcome struct { + Result node.FlowNodeResult + TrackedInput map[string]any + TrackedOutput map[string]any +} + +// LocalExecutor runs nodes in the current process with optional variable tracking. +// It owns the tracker pool, replacing the previous global variable. +// +// For a remote runner, a RemoteExecutor would serialize the request and dispatch +// to a worker instead of calling RunSync directly. +type LocalExecutor struct { + trackerPool *sync.Pool + trackData bool +} + +// NewLocalExecutor creates an executor with the given data tracking setting. +func NewLocalExecutor(trackData bool) *LocalExecutor { + return &LocalExecutor{ + trackerPool: &sync.Pool{New: func() any { return tracking.NewVariableTracker() }}, + trackData: trackData, + } +} + +// Execute runs a node with optional variable tracking, returning the result +// and any tracked input/output data. +func (e *LocalExecutor) Execute(ctx context.Context, n node.FlowNode, req *node.FlowNodeRequest) ExecutionOutcome { + var tracker *tracking.VariableTracker + if e.trackData { + tracker = e.trackerPool.Get().(*tracking.VariableTracker) + tracker.Reset() + req.VariableTracker = tracker + } else { + req.VariableTracker = nil + } + + result := n.RunSync(ctx, req) + + var trackedInput, trackedOutput map[string]any + if tracker != nil { + trackedOutput = tracker.GetWrittenVarsAsTree() + reads := tracker.GetReadVarsAsTree() + if len(reads) > 0 { + trackedInput = reads + } + tracker.Reset() + e.trackerPool.Put(tracker) + } + + return ExecutionOutcome{ + Result: result, + TrackedInput: trackedInput, + TrackedOutput: trackedOutput, + } +} diff --git a/packages/server/pkg/flow/runner/flowlocalrunner/flowlocalrunner.go b/packages/server/pkg/flow/runner/flowlocalrunner/flowlocalrunner.go index ad658f934..8fae92f62 100644 --- a/packages/server/pkg/flow/runner/flowlocalrunner/flowlocalrunner.go +++ b/packages/server/pkg/flow/runner/flowlocalrunner/flowlocalrunner.go @@ -3,17 +3,17 @@ package flowlocalrunner import ( "context" - "errors" - "fmt" - "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node" - "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/runner" - "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/tracking" - "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" - "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" "log/slog" "runtime" "sync" "time" + + "golang.org/x/sync/errgroup" + + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/runner" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" ) // ExecutionMode controls how FlowLocalRunner schedules nodes. @@ -25,33 +25,42 @@ const ( ExecutionModeMulti ) -type FlowLocalRunner struct { - ID idwrap.IDWrap - FlowID idwrap.IDWrap - FlowNodeMap map[idwrap.IDWrap]node.FlowNode - PendingAtmoicMap map[idwrap.IDWrap]uint32 +// RunConfig bundles the parameters that both strategies need, reducing the +// parameter count of runNodes and the strategy functions. +type RunConfig struct { + Timeout time.Duration + TrackData bool + MaxConcurrency int + Emitter *runner.StatusEmitter + StatusLogFunc node.LogPushFunc + PredecessorMap map[idwrap.IDWrap][]idwrap.IDWrap +} - EdgesMap mflow.EdgesMap - StartNodeID idwrap.IDWrap +type FlowLocalRunner struct { + ID idwrap.IDWrap + FlowID idwrap.IDWrap + FlowNodeMap map[idwrap.IDWrap]node.FlowNode Timeout time.Duration - mode ExecutionMode - selectedMode ExecutionMode + graph *runner.FlowGraph + maxConcurrency int + mode ExecutionMode + selectedMode ExecutionMode + enableDataTracking bool logger *slog.Logger } var _ runner.FlowRunner = (*FlowLocalRunner)(nil) -func CreateFlowRunner(id, flowID, startNodeID idwrap.IDWrap, flowNodeMap map[idwrap.IDWrap]node.FlowNode, edgesMap mflow.EdgesMap, timeout time.Duration, logger *slog.Logger) *FlowLocalRunner { +func CreateFlowRunner(id, flowID idwrap.IDWrap, startNodeIDs []idwrap.IDWrap, flowNodeMap map[idwrap.IDWrap]node.FlowNode, edgesMap mflow.EdgesMap, timeout time.Duration, logger *slog.Logger) *FlowLocalRunner { return &FlowLocalRunner{ ID: id, FlowID: flowID, - StartNodeID: startNodeID, FlowNodeMap: flowNodeMap, - PendingAtmoicMap: make(map[idwrap.IDWrap]uint32), - EdgesMap: edgesMap, Timeout: timeout, + graph: runner.NewFlowGraph(edgesMap, startNodeIDs), + maxConcurrency: goroutineCount, mode: ExecutionModeAuto, selectedMode: ExecutionModeMulti, enableDataTracking: true, @@ -59,51 +68,6 @@ func CreateFlowRunner(id, flowID, startNodeID idwrap.IDWrap, flowNodeMap map[idw } } -type nodeStatusEmitter struct { - channels runner.FlowEventChannels -} - -func newNodeStatusEmitter(channels runner.FlowEventChannels) *nodeStatusEmitter { - return &nodeStatusEmitter{channels: channels} -} - -func (e *nodeStatusEmitter) emit(status runner.FlowNodeStatus) { - targets := runner.FlowNodeEventTargetState - if status.State != mflow.NODE_STATE_RUNNING { - targets |= runner.FlowNodeEventTargetLog - } - e.emitWithTargets(status, targets) -} - -func (e *nodeStatusEmitter) emitWithTargets(status runner.FlowNodeStatus, targets runner.FlowNodeEventTarget) { - if e == nil { - return - } - event := runner.FlowNodeEvent{ - Status: status, - Targets: targets, - } - if event.ShouldSend(runner.FlowNodeEventTargetState) && e.channels.NodeStates != nil { - e.channels.NodeStates <- event.Status - } - if event.ShouldSend(runner.FlowNodeEventTargetLog) && e.channels.NodeLogs != nil { - payload := runner.FlowNodeLogPayload{ - ExecutionID: status.ExecutionID, - NodeID: status.NodeID, - Name: status.Name, - State: status.State, - Error: status.Error, - OutputData: status.OutputData, - RunDuration: status.RunDuration, - IterationContext: status.IterationContext, - IterationEvent: status.IterationEvent, - IterationIndex: status.IterationIndex, - LoopNodeID: status.LoopNodeID, - } - e.channels.NodeLogs <- payload - } -} - // SetExecutionMode overrides the default Auto mode for the next run. func (r *FlowLocalRunner) SetExecutionMode(mode ExecutionMode) { if mode < ExecutionModeAuto || mode > ExecutionModeMulti { @@ -122,326 +86,50 @@ func (r *FlowLocalRunner) SetDataTrackingEnabled(enabled bool) { r.enableDataTracking = enabled } -func selectExecutionMode(nodeMap map[idwrap.IDWrap]node.FlowNode, edgesMap mflow.EdgesMap) ExecutionMode { - nodeCount := len(nodeMap) - if nodeCount == 0 { - return ExecutionModeSingle - } - - const smallFlowThreshold = 6 - - simpleStructure := true - incomingNonLoop := make(map[idwrap.IDWrap]int) - - for sourceID, handles := range edgesMap { - nonLoopTargets := 0 - for handle, targetIDs := range handles { - if len(targetIDs) == 0 { - continue - } - if handle == mflow.HandleLoop { - if len(targetIDs) > 1 { - simpleStructure = false - } - continue - } - - nonLoopTargets += len(targetIDs) - if len(targetIDs) > 1 { - simpleStructure = false - } - for _, targetID := range targetIDs { - incomingNonLoop[targetID]++ - } - } - if nonLoopTargets > 1 { - simpleStructure = false - } - if _, ok := handles[mflow.HandleLoop]; ok && nonLoopTargets > 0 { - // Loop node with additional branch work beyond the loop/then path - if nonLoopTargets > 1 { - simpleStructure = false - } - } - - if _, exists := nodeMap[sourceID]; !exists { - // Node present in edges but missing from map; treat as complex and bail out - simpleStructure = false - } - } - - for targetID, count := range incomingNonLoop { - if count > 1 { - simpleStructure = false - break - } - if _, exists := nodeMap[targetID]; !exists { - simpleStructure = false - } - } - - if nodeCount <= smallFlowThreshold && simpleStructure { - return ExecutionModeSingle - } - - return ExecutionModeMulti -} - func runNodes(ctx context.Context, startNodeID idwrap.IDWrap, req *node.FlowNodeRequest, - statusLogFunc node.LogPushFunc, predecessorMap map[idwrap.IDWrap][]idwrap.IDWrap, - mode ExecutionMode, timeout time.Duration, trackData bool, + mode ExecutionMode, cfg RunConfig, ) error { + executor := NewLocalExecutor(cfg.TrackData) + tracker := runner.NewConvergenceTrackerFromPending(req.PendingAtmoicMap) + switch mode { case ExecutionModeSingle: - return runNodesSingle(ctx, startNodeID, req, statusLogFunc, predecessorMap, timeout, trackData) - case ExecutionModeMulti: - if timeout == 0 { - return runNodesMultiNoTimeout(ctx, startNodeID, req, statusLogFunc, predecessorMap, trackData) - } - return runNodesMultiWithTimeout(ctx, startNodeID, req, statusLogFunc, predecessorMap, timeout, trackData) + return runNodesSingle(ctx, startNodeID, req, cfg, executor, tracker) default: - if timeout == 0 { - return runNodesMultiNoTimeout(ctx, startNodeID, req, statusLogFunc, predecessorMap, trackData) - } - return runNodesMultiWithTimeout(ctx, startNodeID, req, statusLogFunc, predecessorMap, timeout, trackData) - } -} - -func gatherSingleModeInputData(req *node.FlowNodeRequest, predecessorIDs []idwrap.IDWrap) map[string]any { - if len(predecessorIDs) == 0 { - return nil - } - - inputs := make(map[string]any, len(predecessorIDs)) - for _, predID := range predecessorIDs { - predNode, ok := req.NodeMap[predID] - if !ok { - continue - } - predName := predNode.GetName() - if predName == "" { - continue - } - if data, err := node.ReadVarRaw(req, predName); err == nil { - inputs[predName] = node.DeepCopyValue(data) - } - } - - if len(inputs) == 0 { - return nil - } - return inputs -} - -func collectSingleModeOutput(req *node.FlowNodeRequest, nodeName string) any { - if nodeName == "" { - return nil - } - if data, err := node.ReadVarRaw(req, nodeName); err == nil { - return node.DeepCopyValue(data) - } - return nil -} - -func flattenNodeOutput(nodeName string, output any) any { - if nodeName == "" || output == nil { - return output - } - m, ok := output.(map[string]any) - if !ok { - return output - } - nested, ok := m[nodeName] - if !ok { - return output - } - nestedMap, ok := nested.(map[string]any) - if !ok { - return output - } - delete(m, nodeName) - for k, v := range nestedMap { - if _, exists := m[k]; !exists { - m[k] = v - } - } - return m -} - -func sendQueuedCancellationStatuses(queue []idwrap.IDWrap, req *node.FlowNodeRequest, statusLogFunc node.LogPushFunc, cancelErr error) { - for _, nodeID := range queue { - if nodeRef, ok := req.NodeMap[nodeID]; ok { - statusLogFunc(runner.FlowNodeStatus{ - ExecutionID: idwrap.NewMonotonic(), - NodeID: nodeID, - Name: nodeRef.GetName(), - State: mflow.NODE_STATE_CANCELED, - Error: cancelErr, - IterationContext: req.IterationContext, - }) - } + return runNodesMultiEventDriven(ctx, startNodeID, req, cfg, executor, tracker) } } -func runNodesSingle(ctx context.Context, startNodeID idwrap.IDWrap, req *node.FlowNodeRequest, - statusLogFunc node.LogPushFunc, predecessorMap map[idwrap.IDWrap][]idwrap.IDWrap, - timeout time.Duration, trackData bool, -) error { - queue := []idwrap.IDWrap{startNodeID} - - for len(queue) > 0 { - if ctx.Err() != nil { - sendQueuedCancellationStatuses(queue, req, statusLogFunc, ctx.Err()) - return ctx.Err() - } - - nodeID := queue[0] - queue = queue[1:] - - currentNode, ok := req.NodeMap[nodeID] - if !ok { - return fmt.Errorf("node not found: %v", nodeID) - } - - var inputData map[string]any - if trackData { - inputData = gatherSingleModeInputData(req, predecessorMap[nodeID]) - } - - executionID := idwrap.NewMonotonic() - runningStatus := runner.FlowNodeStatus{ - ExecutionID: executionID, - NodeID: nodeID, - Name: currentNode.GetName(), - State: mflow.NODE_STATE_RUNNING, - IterationContext: req.IterationContext, - } - statusLogFunc(runningStatus) - - nodeReq := *req - nodeReq.ExecutionID = executionID - var tracker *tracking.VariableTracker - if trackData { - tracker = trackerPool.Get().(*tracking.VariableTracker) - tracker.Reset() - nodeReq.VariableTracker = tracker - } else { - nodeReq.VariableTracker = nil - } - - nodeCtx := ctx - cancelNodeCtx := func() {} - if timeout > 0 { - nodeCtx, cancelNodeCtx = context.WithTimeout(ctx, timeout) - } - startTime := time.Now() - - result := processNode(nodeCtx, currentNode, &nodeReq) - - var ( - trackedOutput map[string]any - trackedInput map[string]any - ) - if tracker != nil { - trackedOutput = tracker.GetWrittenVarsAsTree() - reads := tracker.GetReadVarsAsTree() - if len(reads) > 0 { - trackedInput = reads - } - tracker.Reset() - trackerPool.Put(tracker) - } - nodeCtxErr := nodeCtx.Err() - cancelNodeCtx() - - status := runner.FlowNodeStatus{ - ExecutionID: executionID, - NodeID: nodeID, - Name: currentNode.GetName(), - IterationContext: req.IterationContext, - RunDuration: time.Since(startTime), - AuxiliaryID: result.AuxiliaryID, - } - - if trackData { - if len(trackedInput) > 0 { - status.InputData = node.DeepCopyValue(trackedInput) - } else if len(inputData) > 0 { - status.InputData = node.DeepCopyValue(inputData) - } - } - - if result.Err != nil { - if runner.IsCancellationError(result.Err) { - status.State = mflow.NODE_STATE_CANCELED - } else { - status.State = mflow.NODE_STATE_FAILURE - } - status.Error = result.Err - if trackData { - if len(trackedOutput) > 0 { - status.OutputData = node.DeepCopyValue(trackedOutput) - } else { - status.OutputData = collectSingleModeOutput(&nodeReq, currentNode.GetName()) - } - } - status.OutputData = flattenNodeOutput(status.Name, status.OutputData) - statusLogFunc(status) - return result.Err - } - - if nodeCtxErr != nil { - status.State = mflow.NODE_STATE_CANCELED - status.Error = nodeCtxErr - if trackData { - if len(trackedOutput) > 0 { - status.OutputData = node.DeepCopyValue(trackedOutput) - } else { - status.OutputData = collectSingleModeOutput(&nodeReq, currentNode.GetName()) - } - } - status.OutputData = flattenNodeOutput(status.Name, status.OutputData) - statusLogFunc(status) - return nodeCtxErr - } - - if !result.SkipFinalStatus { - status.State = mflow.NODE_STATE_SUCCESS - if trackData { - if len(trackedOutput) > 0 { - status.OutputData = node.DeepCopyValue(trackedOutput) - } else { - status.OutputData = collectSingleModeOutput(&nodeReq, currentNode.GetName()) - } - } - status.OutputData = flattenNodeOutput(status.Name, status.OutputData) - statusLogFunc(status) - } - - for _, nextID := range result.NextNodeID { - if remaining, ok := req.PendingAtmoicMap[nextID]; ok && remaining > 1 { - req.PendingAtmoicMap[nextID] = remaining - 1 - continue - } - queue = append(queue, nextID) - } - } - - return nil -} - // RunNodeSync retains the legacy behaviour for packages that directly invoke the runner. func RunNodeSync(ctx context.Context, startNodeID idwrap.IDWrap, req *node.FlowNodeRequest, statusLogFunc node.LogPushFunc, predecessorMap map[idwrap.IDWrap][]idwrap.IDWrap, ) error { - return runNodes(ctx, startNodeID, req, statusLogFunc, predecessorMap, ExecutionModeMulti, 0, true) + emitter := runner.NewStatusEmitter(func(s runner.FlowNodeStatus) { statusLogFunc(s) }) + cfg := RunConfig{ + Timeout: 0, + TrackData: true, + MaxConcurrency: goroutineCount, + Emitter: emitter, + StatusLogFunc: statusLogFunc, + PredecessorMap: predecessorMap, + } + return runNodes(ctx, startNodeID, req, ExecutionModeMulti, cfg) } // RunNodeASync retains the legacy behaviour for packages that directly invoke the runner with timeouts. func RunNodeASync(ctx context.Context, startNodeID idwrap.IDWrap, req *node.FlowNodeRequest, statusLogFunc node.LogPushFunc, predecessorMap map[idwrap.IDWrap][]idwrap.IDWrap, ) error { - return runNodes(ctx, startNodeID, req, statusLogFunc, predecessorMap, ExecutionModeMulti, req.Timeout, true) + emitter := runner.NewStatusEmitter(func(s runner.FlowNodeStatus) { statusLogFunc(s) }) + cfg := RunConfig{ + Timeout: req.Timeout, + TrackData: true, + MaxConcurrency: goroutineCount, + Emitter: emitter, + StatusLogFunc: statusLogFunc, + PredecessorMap: predecessorMap, + } + return runNodes(ctx, startNodeID, req, ExecutionModeMulti, cfg) } func (r *FlowLocalRunner) Run(ctx context.Context, flowNodeStatusChan chan runner.FlowNodeStatus, flowStatusChan chan runner.FlowStatus, baseVars map[string]any) error { @@ -449,6 +137,10 @@ func (r *FlowLocalRunner) Run(ctx context.Context, flowNodeStatusChan chan runne } func (r *FlowLocalRunner) RunWithEvents(ctx context.Context, channels runner.FlowEventChannels, baseVars map[string]any) error { + // Cancel context before closing channels (LIFO order) so background + // goroutines (e.g., WebSocket readers) get the stop signal first. + ctx, cancel := context.WithCancel(ctx) + defer cancel() if channels.NodeStates != nil { defer close(channels.NodeStates) } @@ -459,53 +151,43 @@ func (r *FlowLocalRunner) RunWithEvents(ctx context.Context, channels runner.Flo defer close(channels.FlowStatus) } - nextNodeID := &r.StartNodeID - - flowEdgeDepCounter := make(map[idwrap.IDWrap]uint32) - for _, v := range r.EdgesMap { - for _, targetIDs := range v { - for _, targetID := range targetIDs { - current, ok := flowEdgeDepCounter[targetID] - if !ok { - flowEdgeDepCounter[targetID] = 0 - } - flowEdgeDepCounter[targetID] = current + 1 - } - } - } - - pendingAtmoicMap := make(map[idwrap.IDWrap]uint32) - for k, v := range flowEdgeDepCounter { - if v > 1 { - pendingAtmoicMap[k] = v - } + // Clone convergence counts for per-execution mutable pending map + pendingAtmoicMap := make(map[idwrap.IDWrap]uint32, len(r.graph.ConvergeCounts)) + for k, v := range r.graph.ConvergeCounts { + pendingAtmoicMap[k] = v } if baseVars == nil { baseVars = make(map[string]any) } - statusEmitter := newNodeStatusEmitter(channels) - statusFunc := node.LogPushFunc(func(runner.FlowNodeStatus) {}) + var emitFn func(runner.FlowNodeStatus) if channels.NodeStates != nil || channels.NodeLogs != nil { - statusFunc = node.LogPushFunc(statusEmitter.emit) + emitFn = runner.NewChannelEmitFunc(channels) + } else { + emitFn = func(runner.FlowNodeStatus) {} } + emitter := runner.NewStatusEmitter(emitFn) + statusFunc := node.LogPushFunc(emitFn) + + // Shared mutex for PendingAtmoicMap across concurrent entry chains + pendingMu := &sync.Mutex{} req := &node.FlowNodeRequest{ VarMap: baseVars, ReadWriteLock: &sync.RWMutex{}, NodeMap: r.FlowNodeMap, - EdgeSourceMap: r.EdgesMap, + EdgeSourceMap: r.graph.Edges, LogPushFunc: statusFunc, Timeout: r.Timeout, PendingAtmoicMap: pendingAtmoicMap, + PendingMapMu: pendingMu, Logger: r.logger, } - predecessorMap := BuildPredecessorMap(r.EdgesMap) mode := r.mode if mode == ExecutionModeAuto { - mode = selectExecutionMode(r.FlowNodeMap, r.EdgesMap) + mode = selectExecutionMode(r.FlowNodeMap, r.graph.Edges) } r.selectedMode = mode @@ -513,7 +195,29 @@ func (r *FlowLocalRunner) RunWithEvents(ctx context.Context, channels runner.Flo channels.FlowStatus <- runner.FlowStatusStarting } - err := runNodes(ctx, *nextNodeID, req, statusFunc, predecessorMap, mode, r.Timeout, r.enableDataTracking) + cfg := RunConfig{ + Timeout: r.Timeout, + TrackData: r.enableDataTracking, + MaxConcurrency: r.maxConcurrency, + Emitter: emitter, + StatusLogFunc: statusFunc, + PredecessorMap: r.graph.Predecessors, + } + + var err error + if len(r.graph.StartNodeIDs) == 1 { + // Single entry — fast path, no errgroup overhead + err = runNodes(ctx, r.graph.StartNodeIDs[0], req, mode, cfg) + } else { + // Multiple entries — run each chain concurrently + eg, egCtx := errgroup.WithContext(ctx) + for _, startID := range r.graph.StartNodeIDs { + eg.Go(func() error { + return runNodes(egCtx, startID, req, mode, cfg) + }) + } + err = eg.Wait() + } if channels.FlowStatus != nil { if err != nil { @@ -525,60 +229,6 @@ func (r *FlowLocalRunner) RunWithEvents(ctx context.Context, channels runner.Flo return err } -type processResult struct { - originalID idwrap.IDWrap - executionID idwrap.IDWrap - nextNodes []idwrap.IDWrap - err error - inputData map[string]any - outputData map[string]any // NEW: From tracker.GetWrittenVars() - skipFinalStatus bool // From FlowNodeResult.SkipFinalStatus - AuxiliaryID *idwrap.IDWrap -} - -func processNode(ctx context.Context, n node.FlowNode, req *node.FlowNodeRequest, -) node.FlowNodeResult { - return n.RunSync(ctx, req) -} - -type FlowNodeStatusLocal struct { - StartTime time.Time -} - -type nodeSignal struct { - once sync.Once - ch chan struct{} -} - -func acquireNodeSignal(signals *sync.Map, id idwrap.IDWrap) *nodeSignal { - val, _ := signals.LoadOrStore(id, &nodeSignal{ch: make(chan struct{})}) - return val.(*nodeSignal) -} - -func waitForPredecessors(ctx context.Context, signals, seen *sync.Map, predecessors []idwrap.IDWrap) error { - for _, predID := range predecessors { - if seen != nil { - if _, ok := seen.Load(predID); !ok { - continue - } - } - sig := acquireNodeSignal(signals, predID) - select { - case <-sig.ch: - case <-ctx.Done(): - return ctx.Err() - } - } - return nil -} - -func signalNodeComplete(signals *sync.Map, id idwrap.IDWrap) { - sig := acquireNodeSignal(signals, id) - sig.once.Do(func() { - close(sig.ch) - }) -} - func MaxParallelism() int { maxProcs := runtime.GOMAXPROCS(0) numCPU := runtime.NumCPU() @@ -588,627 +238,18 @@ func MaxParallelism() int { return numCPU } -var ( - goroutineCount int = MaxParallelism() - trackerPool = sync.Pool{New: func() any { return tracking.NewVariableTracker() }} -) +var goroutineCount = MaxParallelism() -func BuildPredecessorMap(edgesMap mflow.EdgesMap) map[idwrap.IDWrap][]idwrap.IDWrap { - predecessors := make(map[idwrap.IDWrap][]idwrap.IDWrap, len(edgesMap)) - for sourceID, edges := range edgesMap { - for _, targets := range edges { - for _, targetID := range targets { - predecessors[targetID] = append(predecessors[targetID], sourceID) - } - } - } - return predecessors +// SetGoroutineCountForTesting overrides the goroutine count for testing. +// Returns a cleanup function that restores the original value. +func SetGoroutineCountForTesting(n int) func() { + old := goroutineCount + goroutineCount = n + return func() { goroutineCount = old } } -func runNodesMultiNoTimeout(ctx context.Context, startNodeID idwrap.IDWrap, req *node.FlowNodeRequest, - statusLogFunc node.LogPushFunc, - predecessorMap map[idwrap.IDWrap][]idwrap.IDWrap, - trackData bool, -) error { - queue := []idwrap.IDWrap{startNodeID} - - var status runner.FlowNodeStatus - var processCount int - // Mutex to protect PendingAtmoicMap from concurrent access - var pendingMapMutex sync.Mutex - // Track nodes that have been sent RUNNING status but haven't completed - // Map from executionID to the full status for proper state transitions - runningNodes := make(map[idwrap.IDWrap]runner.FlowNodeStatus) - runningNodesMutex := sync.Mutex{} - // Track start times for duration calculation - nodeStartTimes := make(map[idwrap.IDWrap]time.Time) - - // Cleanup function to send CANCELED status for all running/queued nodes - sendCanceledStatuses := func(cancelErr error) { - // Send CANCELED status for any nodes still in RUNNING state - runningNodesMutex.Lock() - for execID, runningStatus := range runningNodes { - // Calculate actual duration if we have a start time - duration := time.Duration(0) - if startTime, ok := nodeStartTimes[execID]; ok { - duration = time.Since(startTime) - } - - canceledStatus := runner.FlowNodeStatus{ - ExecutionID: execID, - NodeID: runningStatus.NodeID, - Name: runningStatus.Name, - State: mflow.NODE_STATE_CANCELED, - Error: cancelErr, - IterationContext: runningStatus.IterationContext, - RunDuration: duration, - } - statusLogFunc(canceledStatus) - } - // Clear the maps after sending all canceled statuses - runningNodes = make(map[idwrap.IDWrap]runner.FlowNodeStatus) - nodeStartTimes = make(map[idwrap.IDWrap]time.Time) - runningNodesMutex.Unlock() - - // Send CANCELED status for any nodes still in the queue - for _, nodeID := range queue { - if node, ok := req.NodeMap[nodeID]; ok { - canceledStatus := runner.FlowNodeStatus{ - ExecutionID: idwrap.NewMonotonic(), - NodeID: nodeID, - Name: node.GetName(), - State: mflow.NODE_STATE_CANCELED, - Error: cancelErr, - IterationContext: req.IterationContext, - } - statusLogFunc(canceledStatus) - } - } - } - - // Ensure we send canceled statuses on any return path - defer func() { - if ctx.Err() != nil { - sendCanceledStatuses(ctx.Err()) - } - }() - - nodeSignals := &sync.Map{} - seenNodes := &sync.Map{} - seenNodes.Store(startNodeID, struct{}{}) - - for queueLen := len(queue); queueLen != 0; queueLen = len(queue) { - // Check if context was cancelled before processing next batch - if ctx.Err() != nil { - return ctx.Err() - } - - processCount = min(goroutineCount, queueLen) - - var wg sync.WaitGroup - resultChan := make(chan processResult, processCount) - - nodeStateMap := make(map[idwrap.IDWrap]FlowNodeStatusLocal, processCount) - - subqueue := queue[:processCount] - - FlowNodeCancelCtx, FlowNodeCancelCtxCancel := context.WithCancel(ctx) - defer FlowNodeCancelCtxCancel() - var batchErr error - for _, flowNodeID := range subqueue { - currentNode, ok := req.NodeMap[flowNodeID] - if !ok { - batchErr = fmt.Errorf("node not found: %v", flowNodeID) - FlowNodeCancelCtxCancel() - break - } - nodeStateMap[flowNodeID] = FlowNodeStatusLocal{StartTime: time.Now()} - seenNodes.Store(flowNodeID, struct{}{}) - wg.Add(1) - go func(nodeID idwrap.IDWrap) { - defer wg.Done() - - if predecessors := predecessorMap[nodeID]; len(predecessors) > 0 { - if err := waitForPredecessors(FlowNodeCancelCtx, nodeSignals, seenNodes, predecessors); err != nil { - resultChan <- processResult{ - originalID: currentNode.GetID(), - executionID: idwrap.IDWrap{}, - err: err, - } - return - } - } - - // Generate execution ID right before processing - executionID := idwrap.NewMonotonic() - - // Log RUNNING status with execution ID - runningStatus := runner.FlowNodeStatus{ - ExecutionID: executionID, - NodeID: nodeID, - Name: currentNode.GetName(), - State: mflow.NODE_STATE_RUNNING, - Error: nil, - IterationContext: req.IterationContext, - } - statusLogFunc(runningStatus) - - // Track this node as running with its start time - runningNodesMutex.Lock() - runningNodes[executionID] = runningStatus - nodeStartTimes[executionID] = time.Now() - runningNodesMutex.Unlock() - - // Create a copy of the request for this execution to avoid race conditions - // This ensures each goroutine has its own tracker and execution ID - nodeReq := *req // Shallow copy of the request struct - - var tracker *tracking.VariableTracker - if trackData { - tracker = trackerPool.Get().(*tracking.VariableTracker) - tracker.Reset() - nodeReq.VariableTracker = tracker - } - - // Set the execution ID in the copied request - nodeReq.ExecutionID = executionID - - result := processNode(FlowNodeCancelCtx, currentNode, &nodeReq) - - // Capture tracked data as tree structures when enabled - var ( - outputData map[string]any - inputData map[string]any - ) - if tracker != nil { - outputData = tracker.GetWrittenVarsAsTree() - trackedReads := tracker.GetReadVarsAsTree() - if len(trackedReads) > 0 { - inputData = trackedReads - } - tracker.Reset() - trackerPool.Put(tracker) - } - - resultChan <- processResult{ - originalID: currentNode.GetID(), - executionID: executionID, - nextNodes: result.NextNodeID, - err: result.Err, - inputData: inputData, - outputData: outputData, - skipFinalStatus: result.SkipFinalStatus, - AuxiliaryID: result.AuxiliaryID, - } - }(flowNodeID) - } - - wg.Wait() - - close(resultChan) - - if batchErr != nil { - // Drain any results from goroutines that ran before the error - for range resultChan { - } - return batchErr - } - - var lastNodeError error - for result := range resultChan { - status.NodeID = result.originalID - status.ExecutionID = result.executionID - currentNode := req.NodeMap[result.originalID] - status.Name = currentNode.GetName() - status.IterationContext = req.IterationContext - nodeState := nodeStateMap[status.NodeID] - status.RunDuration = time.Since(nodeState.StartTime) - status.InputData = nil - status.OutputData = nil - status.AuxiliaryID = result.AuxiliaryID - signalNodeComplete(nodeSignals, result.originalID) - - // Remove from running nodes since we're processing its completion - runningNodesMutex.Lock() - delete(runningNodes, result.executionID) - delete(nodeStartTimes, result.executionID) - runningNodesMutex.Unlock() - - // Prefer node-specific result error over global cancellation status. - // If the node returned an error, report it first; only mark as canceled - // due to global context cancellation when there is no node error. - if result.err != nil { - if runner.IsCancellationError(result.err) { - status.State = mflow.NODE_STATE_CANCELED - } else { - status.State = mflow.NODE_STATE_FAILURE - } - status.Error = result.err - if trackData { - if result.outputData != nil { - status.OutputData = node.DeepCopyValue(result.outputData) - } else { - status.OutputData = collectSingleModeOutput(req, status.Name) - } - if result.inputData != nil { - status.InputData = node.DeepCopyValue(result.inputData) - } - } - status.OutputData = flattenNodeOutput(status.Name, status.OutputData) - statusLogFunc(status) - lastNodeError = result.err - // Trigger cancellation for remaining nodes after reporting this failure - FlowNodeCancelCtxCancel() - continue - } - - if FlowNodeCancelCtx.Err() != nil { - status.State = mflow.NODE_STATE_CANCELED - status.Error = FlowNodeCancelCtx.Err() - if trackData { - // Capture tracked input/output data even for canceled nodes - // This ensures we show what data was read/written before cancellation - if result.inputData != nil { - status.InputData = node.DeepCopyValue(result.inputData) - } - if result.outputData != nil { - status.OutputData = node.DeepCopyValue(result.outputData) - } - } - status.OutputData = flattenNodeOutput(status.Name, status.OutputData) - statusLogFunc(status) - // Remove from running nodes since we've sent the CANCELED status - runningNodesMutex.Lock() - delete(runningNodes, result.executionID) - delete(nodeStartTimes, result.executionID) - runningNodesMutex.Unlock() - continue - } - - // All nodes should report SUCCESS when they complete successfully - // Loop nodes handle their own iteration tracking internally - // FOR/FOREACH nodes set skipFinalStatus to avoid creating empty main execution - if !result.skipFinalStatus { - status.State = mflow.NODE_STATE_SUCCESS - status.Error = nil - if trackData { - // Use the tracked output data which has the proper tree structure - if result.outputData != nil { - status.OutputData = node.DeepCopyValue(result.outputData) - } - // Deep copy input data as well - if result.inputData != nil { - status.InputData = node.DeepCopyValue(result.inputData) - } - } - status.OutputData = flattenNodeOutput(status.Name, status.OutputData) - statusLogFunc(status) - } - - for _, id := range result.nextNodes { - pendingMapMutex.Lock() - i, ok := req.PendingAtmoicMap[id] - if !ok || i == 1 { - pendingMapMutex.Unlock() - queue = append(queue, id) - seenNodes.Store(id, struct{}{}) - } else { - req.PendingAtmoicMap[id] = i - 1 - pendingMapMutex.Unlock() - } - } - } - - if lastNodeError != nil { - return lastNodeError - } - - // Check if flow was canceled - the defer will handle sending CANCELED statuses - if FlowNodeCancelCtx.Err() != nil { - return FlowNodeCancelCtx.Err() - } - - // remove from queue - queue = queue[processCount:] - } - - return nil -} - -// RunNodeASync runs nodes with timeout handling -func runNodesMultiWithTimeout(ctx context.Context, startNodeID idwrap.IDWrap, req *node.FlowNodeRequest, - statusLogFunc node.LogPushFunc, - predecessorMap map[idwrap.IDWrap][]idwrap.IDWrap, - timeout time.Duration, - trackData bool, -) error { - if timeout <= 0 { - return runNodesMultiNoTimeout(ctx, startNodeID, req, statusLogFunc, predecessorMap, trackData) - } - - queue := []idwrap.IDWrap{startNodeID} - - var status runner.FlowNodeStatus - var processCount int - var pendingMapMutex sync.Mutex - runningNodes := make(map[idwrap.IDWrap]runner.FlowNodeStatus) - runningNodesMutex := sync.Mutex{} - nodeStartTimes := make(map[idwrap.IDWrap]time.Time) - - sendCanceledStatuses := func(cancelErr error) { - runningNodesMutex.Lock() - for execID, runningStatus := range runningNodes { - duration := time.Duration(0) - if startTime, ok := nodeStartTimes[execID]; ok { - duration = time.Since(startTime) - } - statusLogFunc(runner.FlowNodeStatus{ - ExecutionID: execID, - NodeID: runningStatus.NodeID, - Name: runningStatus.Name, - State: mflow.NODE_STATE_CANCELED, - Error: cancelErr, - IterationContext: runningStatus.IterationContext, - RunDuration: duration, - }) - } - runningNodes = make(map[idwrap.IDWrap]runner.FlowNodeStatus) - nodeStartTimes = make(map[idwrap.IDWrap]time.Time) - runningNodesMutex.Unlock() - - for _, nodeID := range queue { - if nodeRef, ok := req.NodeMap[nodeID]; ok { - statusLogFunc(runner.FlowNodeStatus{ - ExecutionID: idwrap.NewMonotonic(), - NodeID: nodeID, - Name: nodeRef.GetName(), - State: mflow.NODE_STATE_CANCELED, - Error: cancelErr, - IterationContext: req.IterationContext, - }) - } - } - } - - defer func() { - if ctx.Err() != nil { - sendCanceledStatuses(ctx.Err()) - } - }() - - nodeSignals := &sync.Map{} - seenNodes := &sync.Map{} - seenNodes.Store(startNodeID, struct{}{}) - - for queueLen := len(queue); queueLen != 0; queueLen = len(queue) { - if ctx.Err() != nil { - return ctx.Err() - } - - processCount = min(goroutineCount, queueLen) - - var wg sync.WaitGroup - resultChan := make(chan processResult, processCount) - timeStart := make(map[idwrap.IDWrap]time.Time, processCount) - - batch := queue[:processCount] - flowCtx, flowCancel := context.WithCancel(ctx) - defer flowCancel() - - var batchErr error - for _, nodeID := range batch { - currentNode, ok := req.NodeMap[nodeID] - if !ok { - batchErr = fmt.Errorf("node not found: %v", nodeID) - flowCancel() - break - } - - timeStart[nodeID] = time.Now() - seenNodes.Store(nodeID, struct{}{}) - - wg.Add(1) - go func(nodeID idwrap.IDWrap, flowNode node.FlowNode) { - defer wg.Done() - - if predecessors := predecessorMap[nodeID]; len(predecessors) > 0 { - if err := waitForPredecessors(flowCtx, nodeSignals, seenNodes, predecessors); err != nil { - resultChan <- processResult{originalID: flowNode.GetID(), err: err} - return - } - } - - executionID := idwrap.NewMonotonic() - - runningStatus := runner.FlowNodeStatus{ - ExecutionID: executionID, - NodeID: nodeID, - Name: flowNode.GetName(), - State: mflow.NODE_STATE_RUNNING, - Error: nil, - IterationContext: req.IterationContext, - } - statusLogFunc(runningStatus) - - runningNodesMutex.Lock() - runningNodes[executionID] = runningStatus - nodeStartTimes[executionID] = time.Now() - runningNodesMutex.Unlock() - - nodeReq := *req - - var tracker *tracking.VariableTracker - if trackData { - tracker = trackerPool.Get().(*tracking.VariableTracker) - tracker.Reset() - nodeReq.VariableTracker = tracker - } - - nodeReq.ExecutionID = executionID - - nodeCtx := flowCtx - var cancelNode context.CancelFunc - if timeout > 0 { - if _, isLoop := flowNode.(node.LoopCoordinator); !isLoop { - nodeCtx, cancelNode = context.WithTimeout(flowCtx, timeout) - } - } - if cancelNode != nil { - defer cancelNode() - } - - result := processNode(nodeCtx, flowNode, &nodeReq) - - var ( - outputData map[string]any - inputData map[string]any - ) - if tracker != nil { - outputData = tracker.GetWrittenVarsAsTree() - trackedReads := tracker.GetReadVarsAsTree() - if len(trackedReads) > 0 { - inputData = trackedReads - } - tracker.Reset() - trackerPool.Put(tracker) - } - - if result.Err == nil && errors.Is(nodeCtx.Err(), context.DeadlineExceeded) { - result.Err = nodeCtx.Err() - } - - resultChan <- processResult{ - originalID: flowNode.GetID(), - executionID: executionID, - nextNodes: result.NextNodeID, - err: result.Err, - inputData: inputData, - outputData: outputData, - skipFinalStatus: result.SkipFinalStatus, - AuxiliaryID: result.AuxiliaryID, - } - }(nodeID, currentNode) - } - - wg.Wait() - close(resultChan) - - if batchErr != nil { - for range resultChan { - } - return batchErr - } - - queue = queue[processCount:] - - var lastNodeError error - timedOut := false - - for result := range resultChan { - status.NodeID = result.originalID - status.ExecutionID = result.executionID - currentNode := req.NodeMap[result.originalID] - status.Name = currentNode.GetName() - status.IterationContext = req.IterationContext - status.RunDuration = time.Since(timeStart[status.NodeID]) - status.InputData = nil - status.OutputData = nil - status.AuxiliaryID = result.AuxiliaryID - _, isLoop := currentNode.(node.LoopCoordinator) - - signalNodeComplete(nodeSignals, result.originalID) - - runningNodesMutex.Lock() - delete(runningNodes, result.executionID) - delete(nodeStartTimes, result.executionID) - runningNodesMutex.Unlock() - - if result.err != nil { - if errors.Is(result.err, context.DeadlineExceeded) { - timedOut = true - } - if runner.IsCancellationError(result.err) { - status.State = mflow.NODE_STATE_CANCELED - } else { - status.State = mflow.NODE_STATE_FAILURE - } - status.Error = result.err - if trackData { - if result.outputData != nil { - status.OutputData = node.DeepCopyValue(result.outputData) - } else { - status.OutputData = collectSingleModeOutput(req, status.Name) - } - if result.inputData != nil { - status.InputData = node.DeepCopyValue(result.inputData) - } - } - status.OutputData = flattenNodeOutput(status.Name, status.OutputData) - statusLogFunc(status) - lastNodeError = result.err - continue - } - - if flowCtx.Err() != nil && !isLoop { - status.State = mflow.NODE_STATE_CANCELED - status.Error = flowCtx.Err() - if trackData { - if result.inputData != nil { - status.InputData = node.DeepCopyValue(result.inputData) - } - if result.outputData != nil { - status.OutputData = node.DeepCopyValue(result.outputData) - } - } - status.OutputData = flattenNodeOutput(status.Name, status.OutputData) - statusLogFunc(status) - timedOut = true - continue - } - - if !result.skipFinalStatus { - status.State = mflow.NODE_STATE_SUCCESS - status.Error = nil - if trackData { - if result.outputData != nil { - status.OutputData = node.DeepCopyValue(result.outputData) - } - if result.inputData != nil { - status.InputData = node.DeepCopyValue(result.inputData) - } - } - status.OutputData = flattenNodeOutput(status.Name, status.OutputData) - statusLogFunc(status) - } - - for _, id := range result.nextNodes { - pendingMapMutex.Lock() - i, ok := req.PendingAtmoicMap[id] - if !ok || i == 1 { - pendingMapMutex.Unlock() - queue = append(queue, id) - seenNodes.Store(id, struct{}{}) - } else { - req.PendingAtmoicMap[id] = i - 1 - pendingMapMutex.Unlock() - } - } - } - - if lastNodeError != nil { - return lastNodeError - } - - if cancelErr := flowCtx.Err(); cancelErr != nil { - if !timedOut { - return cancelErr - } - } - - if timedOut { - return context.DeadlineExceeded - } - } - - return nil +// BuildPredecessorMap forwards to runner.BuildPredecessorMap. +// Kept for backward compatibility with node packages (nfor, nforeach, nwsconnection, nai). +func BuildPredecessorMap(edgesMap mflow.EdgesMap) map[idwrap.IDWrap][]idwrap.IDWrap { + return runner.BuildPredecessorMap(edgesMap) } diff --git a/packages/server/pkg/flow/runner/flowlocalrunner/flowlocalrunner_inputdata_test.go b/packages/server/pkg/flow/runner/flowlocalrunner/flowlocalrunner_inputdata_test.go index a3e6f7f4e..6a93ed48e 100644 --- a/packages/server/pkg/flow/runner/flowlocalrunner/flowlocalrunner_inputdata_test.go +++ b/packages/server/pkg/flow/runner/flowlocalrunner/flowlocalrunner_inputdata_test.go @@ -88,7 +88,7 @@ func TestFlowLocalRunnerEmitsInputDataForTrackedReads(t *testing.T) { runnerID := idwrap.NewNow() flowID := idwrap.NewNow() - fr := CreateFlowRunner(runnerID, flowID, startID, nodeMap, edgesMap, 0, nil) + fr := CreateFlowRunner(runnerID, flowID, []idwrap.IDWrap{startID}, nodeMap, edgesMap, 0, nil) nodeStates := make(chan runner.FlowNodeStatus, 10) flowStatus := make(chan runner.FlowStatus, 2) @@ -225,7 +225,7 @@ func TestFlowLocalRunnerRequestNodeEmitsInputData(t *testing.T) { runnerID := idwrap.NewNow() flowID := idwrap.NewNow() - fr := CreateFlowRunner(runnerID, flowID, startID, nodeMap, edgesMap, 0, nil) + fr := CreateFlowRunner(runnerID, flowID, []idwrap.IDWrap{startID}, nodeMap, edgesMap, 0, nil) nodeStates := make(chan runner.FlowNodeStatus, 10) flowStatus := make(chan runner.FlowStatus, 2) @@ -372,7 +372,7 @@ func TestFlowLocalRunnerRequestNodeEmitsInputDataForBodyOnlyVariables(t *testing runnerID := idwrap.NewNow() flowID := idwrap.NewNow() - fr := CreateFlowRunner(runnerID, flowID, startID, nodeMap, edgesMap, 0, nil) + fr := CreateFlowRunner(runnerID, flowID, []idwrap.IDWrap{startID}, nodeMap, edgesMap, 0, nil) nodeStates := make(chan runner.FlowNodeStatus, 10) flowStatus := make(chan runner.FlowStatus, 2) diff --git a/packages/server/pkg/flow/runner/flowlocalrunner/flowlocalrunner_test.go b/packages/server/pkg/flow/runner/flowlocalrunner/flowlocalrunner_test.go index 77fe05a58..14017c74c 100644 --- a/packages/server/pkg/flow/runner/flowlocalrunner/flowlocalrunner_test.go +++ b/packages/server/pkg/flow/runner/flowlocalrunner/flowlocalrunner_test.go @@ -275,7 +275,7 @@ func TestFlowLocalRunnerEmitsLogEvents(t *testing.T) { }, } - flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), startID, nodeMap, edgesMap, 0, nil) + flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), []idwrap.IDWrap{startID}, nodeMap, edgesMap, 0, nil) stateChan := make(chan runner.FlowNodeStatus, 8) logChan := make(chan runner.FlowNodeLogPayload, 8) @@ -343,7 +343,7 @@ func TestFlowLocalRunnerMultiFailureIncludesOutputData(t *testing.T) { }, } - flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), startID, nodeMap, edgesMap, 0, nil) + flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), []idwrap.IDWrap{startID}, nodeMap, edgesMap, 0, nil) flowRunner.SetExecutionMode(flowlocalrunner.ExecutionModeMulti) stateChan := make(chan runner.FlowNodeStatus, 8) @@ -539,7 +539,7 @@ func TestLoopNodeEmitsFinalSuccessStatus(t *testing.T) { nodeID: loopNode, } edgesMap := make(mflow.EdgesMap) - flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), nodeID, nodeMap, edgesMap, 0, nil) + flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), []idwrap.IDWrap{nodeID}, nodeMap, edgesMap, 0, nil) statusChan := make(chan runner.FlowNodeStatus, 8) flowStatusChan := make(chan runner.FlowStatus, 2) @@ -590,7 +590,7 @@ func BenchmarkFlowRunnerForLoopWithMockRequest(b *testing.B) { }, } - flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), loopID, nodeMap, edgesMap, 0, nil) + flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), []idwrap.IDWrap{loopID}, nodeMap, edgesMap, 0, nil) b.ResetTimer() for i := 0; i < b.N; i++ { @@ -615,7 +615,7 @@ func TestFlowLocalRunnerSingleModeSequential(t *testing.T) { } runnerID := idwrap.NewNow() - flowRunner := flowlocalrunner.CreateFlowRunner(runnerID, idwrap.NewNow(), startID, nodeMap, edgesMap, 0, nil) + flowRunner := flowlocalrunner.CreateFlowRunner(runnerID, idwrap.NewNow(), []idwrap.IDWrap{startID}, nodeMap, edgesMap, 0, nil) flowRunner.SetExecutionMode(flowlocalrunner.ExecutionModeSingle) statusChan := make(chan runner.FlowNodeStatus, 16) @@ -690,7 +690,7 @@ func TestFlowLocalRunnerMultiModeConcurrentExecution(t *testing.T) { rightNode.GetID(): map[mflow.EdgeHandle][]idwrap.IDWrap{}, } - flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), startID, nodeMap, edgesMap, 0, nil) + flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), []idwrap.IDWrap{startID}, nodeMap, edgesMap, 0, nil) flowRunner.SetExecutionMode(flowlocalrunner.ExecutionModeMulti) statusChan := make(chan runner.FlowNodeStatus, 16) @@ -738,7 +738,7 @@ func TestFlowLocalRunnerMultiModeConcurrentExecution(t *testing.T) { func TestFlowLocalRunnerAutoModeSelection(t *testing.T) { linearStart, linearNodeMap, linearEdges, _ := buildLinearStubFlow(3, false) - linearRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), linearStart, linearNodeMap, linearEdges, 0, nil) + linearRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), []idwrap.IDWrap{linearStart}, linearNodeMap, linearEdges, 0, nil) statusChan := make(chan runner.FlowNodeStatus, 8) flowStatusChan := make(chan runner.FlowStatus, 4) @@ -755,7 +755,7 @@ func TestFlowLocalRunnerAutoModeSelection(t *testing.T) { } branchStart, branchNodes, branchEdges := buildBranchingStubFlow() - branchRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), branchStart, branchNodes, branchEdges, 0, nil) + branchRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), []idwrap.IDWrap{branchStart}, branchNodes, branchEdges, 0, nil) statusChan = make(chan runner.FlowNodeStatus, 8) flowStatusChan = make(chan runner.FlowStatus, 4) @@ -786,7 +786,7 @@ func TestFlowLocalRunnerAutoModeSelection(t *testing.T) { bodyID: map[mflow.EdgeHandle][]idwrap.IDWrap{}, } - loopRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), loopID, loopNodes, loopEdges, 0, nil) + loopRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), []idwrap.IDWrap{loopID}, loopNodes, loopEdges, 0, nil) statusChan = make(chan runner.FlowNodeStatus, 8) flowStatusChan = make(chan runner.FlowStatus, 4) if err := loopRunner.Run(context.Background(), statusChan, flowStatusChan, nil); err != nil { @@ -823,7 +823,7 @@ func TestFlowLocalRunnerAutoModeSelection(t *testing.T) { bodyBID: map[mflow.EdgeHandle][]idwrap.IDWrap{}, } - complexRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), loopID2, complexNodes, complexEdges, 0, nil) + complexRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), []idwrap.IDWrap{loopID2}, complexNodes, complexEdges, 0, nil) statusChan = make(chan runner.FlowNodeStatus, 8) flowStatusChan = make(chan runner.FlowStatus, 4) if err := complexRunner.Run(context.Background(), statusChan, flowStatusChan, nil); err != nil { @@ -841,7 +841,7 @@ func TestFlowLocalRunnerAutoModeSelection(t *testing.T) { func TestFlowLocalRunnerModeOverride(t *testing.T) { startID, nodeMap, edgesMap, _ := buildLinearStubFlow(2, false) - flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), startID, nodeMap, edgesMap, 0, nil) + flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), []idwrap.IDWrap{startID}, nodeMap, edgesMap, 0, nil) flowRunner.SetExecutionMode(flowlocalrunner.ExecutionModeMulti) statusChan := make(chan runner.FlowNodeStatus, 8) @@ -880,7 +880,7 @@ func TestLoopCoordinatorPerNodeTimeout(t *testing.T) { bodyID: map[mflow.EdgeHandle][]idwrap.IDWrap{}, } - flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), loopID, nodeMap, edgesMap, perNodeTimeout, nil) + flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), []idwrap.IDWrap{loopID}, nodeMap, edgesMap, perNodeTimeout, nil) flowRunner.SetExecutionMode(flowlocalrunner.ExecutionModeMulti) stateChan := make(chan runner.FlowNodeStatus, 64) @@ -933,7 +933,7 @@ func benchmarkBlockingFlow(b *testing.B, mode flowlocalrunner.ExecutionMode, wid edgesMap[startID][mflow.HandleUnspecified] = append([]idwrap.IDWrap(nil), branchIDs...) startNode.next = append([]idwrap.IDWrap(nil), branchIDs...) - flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), startID, nodeMap, edgesMap, 0, nil) + flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), []idwrap.IDWrap{startID}, nodeMap, edgesMap, 0, nil) flowRunner.SetExecutionMode(mode) statusChan := make(chan runner.FlowNodeStatus, width*4) @@ -978,7 +978,7 @@ func runExecutionModeBenchmark(b *testing.B, startID idwrap.IDWrap, nodeMap map[ b.ResetTimer() for i := 0; i < b.N; i++ { - flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), startID, nodeMap, edgesMap, 0, nil) + flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), []idwrap.IDWrap{startID}, nodeMap, edgesMap, 0, nil) flowRunner.SetExecutionMode(mode) statusChan := make(chan runner.FlowNodeStatus, len(nodeMap)*4) @@ -1041,3 +1041,338 @@ func BenchmarkFlowLocalRunnerLoopFlow(b *testing.B) { runExecutionModeBenchmark(b, startID, nodeMap, edgesMap, flowlocalrunner.ExecutionModeAuto) }) } + +// TestEventDrivenIndependentBranches verifies that independent branches don't +// block each other. When START → [FAST, SLOW] and FAST → FAST_CHILD, FAST_CHILD +// should start executing while SLOW is still running. +func TestEventDrivenIndependentBranches(t *testing.T) { + slowRelease := make(chan struct{}) + slowNode := newBlockingNode("slow", slowRelease) + + fastID := idwrap.NewNow() + fastChildID := idwrap.NewNow() + fastChild := newBlockingNode("fast_child", nil) // completes immediately + + startID := idwrap.NewNow() + startNode := &stubNode{ + id: startID, + name: "start", + next: []idwrap.IDWrap{fastID, slowNode.GetID()}, + } + fastNode := &stubNode{ + id: fastID, + name: "fast", + next: []idwrap.IDWrap{fastChildID}, + } + + nodeMap := map[idwrap.IDWrap]node.FlowNode{ + startID: startNode, + fastID: fastNode, + slowNode.GetID(): slowNode, + fastChildID: fastChild, + } + edgesMap := mflow.EdgesMap{ + startID: {mflow.HandleUnspecified: []idwrap.IDWrap{fastID, slowNode.GetID()}}, + fastID: {mflow.HandleUnspecified: []idwrap.IDWrap{fastChildID}}, + slowNode.GetID(): {}, + fastChildID: {}, + } + + flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), []idwrap.IDWrap{startID}, nodeMap, edgesMap, 0, nil) + flowRunner.SetExecutionMode(flowlocalrunner.ExecutionModeMulti) + + statusChan := make(chan runner.FlowNodeStatus, 32) + flowStatusChan := make(chan runner.FlowStatus, 4) + errCh := make(chan error, 1) + + go func() { + errCh <- flowRunner.Run(context.Background(), statusChan, flowStatusChan, nil) + }() + + // Wait for fast_child to start — this proves it didn't wait for slow + waitForStart(t, fastChild.started, "fast_child") + + // At this point, slow should still be running (it's blocked) + waitForStart(t, slowNode.started, "slow") + + // Release slow so the flow can complete + close(slowRelease) + + if err := <-errCh; err != nil { + t.Fatalf("flow runner returned error: %v", err) + } + + for range statusChan { + } + for range flowStatusChan { + } +} + +// blockingStubNode combines blocking behavior with next-node return. +type blockingStubNode struct { + id idwrap.IDWrap + name string + release <-chan struct{} + started chan struct{} + once sync.Once + next []idwrap.IDWrap +} + +func newBlockingStubNode(name string, release <-chan struct{}, next []idwrap.IDWrap) *blockingStubNode { + return &blockingStubNode{ + id: idwrap.NewNow(), + name: name, + release: release, + started: make(chan struct{}), + next: next, + } +} + +func (b *blockingStubNode) GetID() idwrap.IDWrap { return b.id } +func (b *blockingStubNode) GetName() string { return b.name } + +func (b *blockingStubNode) RunSync(ctx context.Context, _ *node.FlowNodeRequest) node.FlowNodeResult { + b.once.Do(func() { close(b.started) }) + if b.release != nil { + select { + case <-b.release: + case <-ctx.Done(): + return node.FlowNodeResult{Err: ctx.Err()} + } + } + return node.FlowNodeResult{NextNodeID: append([]idwrap.IDWrap(nil), b.next...)} +} + +func (b *blockingStubNode) RunAsync(ctx context.Context, req *node.FlowNodeRequest, resultChan chan node.FlowNodeResult) { + resultChan <- b.RunSync(ctx, req) +} + +// TestEventDrivenDiamondConvergence verifies that converge points still wait for +// all predecessors. In START → [A, B] → JOIN, JOIN only executes after both +// A and B complete. +func TestEventDrivenDiamondConvergence(t *testing.T) { + joinID := idwrap.NewNow() + + releaseA := make(chan struct{}) + releaseB := make(chan struct{}) + nodeA := newBlockingStubNode("a", releaseA, []idwrap.IDWrap{joinID}) + nodeB := newBlockingStubNode("b", releaseB, []idwrap.IDWrap{joinID}) + + joinNode := newBlockingStubNode("join", nil, nil) + // Override the auto-generated ID to use our pre-declared joinID + joinNode.id = joinID + + startID := idwrap.NewNow() + startNode := &stubNode{ + id: startID, + name: "start", + next: []idwrap.IDWrap{nodeA.GetID(), nodeB.GetID()}, + } + + nodeMap := map[idwrap.IDWrap]node.FlowNode{ + startID: startNode, + nodeA.GetID(): nodeA, + nodeB.GetID(): nodeB, + joinID: joinNode, + } + edgesMap := mflow.EdgesMap{ + startID: {mflow.HandleUnspecified: []idwrap.IDWrap{nodeA.GetID(), nodeB.GetID()}}, + nodeA.GetID(): {mflow.HandleUnspecified: []idwrap.IDWrap{joinID}}, + nodeB.GetID(): {mflow.HandleUnspecified: []idwrap.IDWrap{joinID}}, + joinID: {}, + } + + flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), []idwrap.IDWrap{startID}, nodeMap, edgesMap, 0, nil) + flowRunner.SetExecutionMode(flowlocalrunner.ExecutionModeMulti) + + statusChan := make(chan runner.FlowNodeStatus, 32) + flowStatusChan := make(chan runner.FlowStatus, 4) + errCh := make(chan error, 1) + + go func() { + errCh <- flowRunner.Run(context.Background(), statusChan, flowStatusChan, nil) + }() + + // Wait for A and B to start + waitForStart(t, nodeA.started, "a") + waitForStart(t, nodeB.started, "b") + + // Release B first — JOIN should NOT start yet (A is still blocked) + close(releaseB) + time.Sleep(50 * time.Millisecond) + + select { + case <-joinNode.started: + t.Fatal("join started before all predecessors completed") + default: + // Good — join hasn't started yet + } + + // Release A — NOW join should start + close(releaseA) + waitForStart(t, joinNode.started, "join") + + if err := <-errCh; err != nil { + t.Fatalf("flow runner returned error: %v", err) + } + + for range statusChan { + } + for range flowStatusChan { + } +} + +// TestEventDrivenErrorCancelsOtherBranches verifies that when one branch fails, +// other in-flight branches are canceled. +func TestEventDrivenErrorCancelsOtherBranches(t *testing.T) { + slowRelease := make(chan struct{}) + slowNode := newBlockingNode("slow", slowRelease) + defer close(slowRelease) + + failID := idwrap.NewNow() + failNode := newFailingNode(failID, "fail", nil, errors.New("boom")) + + startID := idwrap.NewNow() + startNode := &stubNode{ + id: startID, + name: "start", + next: []idwrap.IDWrap{failID, slowNode.GetID()}, + } + + nodeMap := map[idwrap.IDWrap]node.FlowNode{ + startID: startNode, + failID: failNode, + slowNode.GetID(): slowNode, + } + edgesMap := mflow.EdgesMap{ + startID: {mflow.HandleUnspecified: []idwrap.IDWrap{failID, slowNode.GetID()}}, + failID: {}, + slowNode.GetID(): {}, + } + + flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), []idwrap.IDWrap{startID}, nodeMap, edgesMap, 0, nil) + flowRunner.SetExecutionMode(flowlocalrunner.ExecutionModeMulti) + + statusChan := make(chan runner.FlowNodeStatus, 32) + flowStatusChan := make(chan runner.FlowStatus, 4) + + err := flowRunner.Run(context.Background(), statusChan, flowStatusChan, nil) + require.Error(t, err) + + statuses := drainStates(statusChan) + _ = drainFlowStatus(flowStatusChan) + + // Verify the failing node reported FAILURE + foundFailure := false + foundCanceled := false + for _, s := range statuses { + if s.NodeID == failID && s.State == mflow.NODE_STATE_FAILURE { + foundFailure = true + } + if s.NodeID == slowNode.GetID() && s.State == mflow.NODE_STATE_CANCELED { + foundCanceled = true + } + } + + require.True(t, foundFailure, "expected FAILURE status for fail node, statuses: %+v", statuses) + require.True(t, foundCanceled, "expected CANCELED status for slow node, statuses: %+v", statuses) +} + +// concurrencyTrackingNode is a FlowNode that tracks concurrent execution. +type concurrencyTrackingNode struct { + id idwrap.IDWrap + nodeName string + mu *sync.Mutex + activeConcur *int + maxConcur *int +} + +func (n *concurrencyTrackingNode) GetID() idwrap.IDWrap { return n.id } +func (n *concurrencyTrackingNode) GetName() string { return n.nodeName } + +func (n *concurrencyTrackingNode) RunSync(_ context.Context, _ *node.FlowNodeRequest) node.FlowNodeResult { + n.mu.Lock() + *n.activeConcur++ + if *n.activeConcur > *n.maxConcur { + *n.maxConcur = *n.activeConcur + } + n.mu.Unlock() + + // Small delay to increase the window for concurrent overlap + time.Sleep(5 * time.Millisecond) + + n.mu.Lock() + *n.activeConcur-- + n.mu.Unlock() + + return node.FlowNodeResult{} +} + +func (n *concurrencyTrackingNode) RunAsync(ctx context.Context, req *node.FlowNodeRequest, resultChan chan node.FlowNodeResult) { + resultChan <- n.RunSync(ctx, req) +} + +// TestEventDrivenSemaphoreBoundsConcurrency verifies that the semaphore limits +// how many nodes are actively processing at any time. +func TestEventDrivenSemaphoreBoundsConcurrency(t *testing.T) { + cleanup := flowlocalrunner.SetGoroutineCountForTesting(1) + defer cleanup() + + var mu sync.Mutex + maxConcurrent := 0 + activeConcurrent := 0 + + newTrackingNode := func(name string) *concurrencyTrackingNode { + return &concurrencyTrackingNode{ + id: idwrap.NewNow(), + nodeName: name, + mu: &mu, + activeConcur: &activeConcurrent, + maxConcur: &maxConcurrent, + } + } + + tn1 := newTrackingNode("worker-0") + tn2 := newTrackingNode("worker-1") + tn3 := newTrackingNode("worker-2") + + startID := idwrap.NewNow() + startNode := &stubNode{ + id: startID, + name: "start", + next: []idwrap.IDWrap{tn1.id, tn2.id, tn3.id}, + } + + nodeMap := map[idwrap.IDWrap]node.FlowNode{ + startID: startNode, + tn1.id: tn1, + tn2.id: tn2, + tn3.id: tn3, + } + edgesMap := mflow.EdgesMap{ + startID: {mflow.HandleUnspecified: []idwrap.IDWrap{tn1.id, tn2.id, tn3.id}}, + tn1.id: {}, + tn2.id: {}, + tn3.id: {}, + } + + flowRunner := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), idwrap.NewNow(), []idwrap.IDWrap{startID}, nodeMap, edgesMap, 0, nil) + flowRunner.SetExecutionMode(flowlocalrunner.ExecutionModeMulti) + + statusChan := make(chan runner.FlowNodeStatus, 32) + flowStatusChan := make(chan runner.FlowStatus, 4) + + err := flowRunner.Run(context.Background(), statusChan, flowStatusChan, nil) + require.Nil(t, err) + + for range statusChan { + } + for range flowStatusChan { + } + + mu.Lock() + finalMax := maxConcurrent + mu.Unlock() + + require.LessOrEqual(t, finalMax, 1, "expected max concurrent processing to be 1 (semaphore bound), got %d", finalMax) +} diff --git a/packages/server/pkg/flow/runner/flowlocalrunner/helpers.go b/packages/server/pkg/flow/runner/flowlocalrunner/helpers.go new file mode 100644 index 000000000..9f9c3275f --- /dev/null +++ b/packages/server/pkg/flow/runner/flowlocalrunner/helpers.go @@ -0,0 +1,91 @@ +package flowlocalrunner + +import ( + "context" + "errors" + + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/runner" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" +) + +// buildTerminalStatus consolidates state classification, data attachment, and +// output flattening into a single function. Both strategies call this instead +// of duplicating ~50 lines each. +// +// base must have ExecutionID, NodeID, Name, IterationContext, RunDuration, +// and AuxiliaryID pre-filled. This function fills State, Error, InputData, +// and OutputData. +func buildTerminalStatus( + base runner.FlowNodeStatus, + nodeErr error, + timedOut bool, + trackedInput, trackedOutput map[string]any, + req *node.FlowNodeRequest, + trackData bool, +) runner.FlowNodeStatus { + status := base + + if nodeErr != nil { + switch { + case timedOut || errors.Is(nodeErr, context.DeadlineExceeded): + status.State = mflow.NODE_STATE_FAILURE + case runner.IsCancellationError(nodeErr): + status.State = mflow.NODE_STATE_CANCELED + default: + status.State = mflow.NODE_STATE_FAILURE + } + status.Error = nodeErr + } else { + status.State = mflow.NODE_STATE_SUCCESS + } + + if trackData { + if len(trackedOutput) > 0 { + status.OutputData = node.DeepCopyValue(trackedOutput) + } else { + status.OutputData = collectSingleModeOutput(req, status.Name) + } + if len(trackedInput) > 0 { + status.InputData = node.DeepCopyValue(trackedInput) + } + } + status.OutputData = flattenNodeOutput(status.Name, status.OutputData) + + return status +} + +func collectSingleModeOutput(req *node.FlowNodeRequest, nodeName string) any { + if nodeName == "" { + return nil + } + if data, err := node.ReadVarRaw(req, nodeName); err == nil { + return node.DeepCopyValue(data) + } + return nil +} + +func flattenNodeOutput(nodeName string, output any) any { + if nodeName == "" || output == nil { + return output + } + m, ok := output.(map[string]any) + if !ok { + return output + } + nested, ok := m[nodeName] + if !ok { + return output + } + nestedMap, ok := nested.(map[string]any) + if !ok { + return output + } + delete(m, nodeName) + for k, v := range nestedMap { + if _, exists := m[k]; !exists { + m[k] = v + } + } + return m +} diff --git a/packages/server/pkg/flow/runner/flowlocalrunner/mode_select.go b/packages/server/pkg/flow/runner/flowlocalrunner/mode_select.go new file mode 100644 index 000000000..874be0498 --- /dev/null +++ b/packages/server/pkg/flow/runner/flowlocalrunner/mode_select.go @@ -0,0 +1,72 @@ +package flowlocalrunner + +import ( + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" +) + +func selectExecutionMode(nodeMap map[idwrap.IDWrap]node.FlowNode, edgesMap mflow.EdgesMap) ExecutionMode { + nodeCount := len(nodeMap) + if nodeCount == 0 { + return ExecutionModeSingle + } + + const smallFlowThreshold = 6 + + simpleStructure := true + incomingNonLoop := make(map[idwrap.IDWrap]int) + + for sourceID, handles := range edgesMap { + nonLoopTargets := 0 + for handle, targetIDs := range handles { + if len(targetIDs) == 0 { + continue + } + if handle == mflow.HandleLoop { + if len(targetIDs) > 1 { + simpleStructure = false + } + continue + } + + nonLoopTargets += len(targetIDs) + if len(targetIDs) > 1 { + simpleStructure = false + } + for _, targetID := range targetIDs { + incomingNonLoop[targetID]++ + } + } + if nonLoopTargets > 1 { + simpleStructure = false + } + if _, ok := handles[mflow.HandleLoop]; ok && nonLoopTargets > 0 { + // Loop node with additional branch work beyond the loop/then path + if nonLoopTargets > 1 { + simpleStructure = false + } + } + + if _, exists := nodeMap[sourceID]; !exists { + // Node present in edges but missing from map; treat as complex and bail out + simpleStructure = false + } + } + + for targetID, count := range incomingNonLoop { + if count > 1 { + simpleStructure = false + break + } + if _, exists := nodeMap[targetID]; !exists { + simpleStructure = false + } + } + + if nodeCount <= smallFlowThreshold && simpleStructure { + return ExecutionModeSingle + } + + return ExecutionModeMulti +} diff --git a/packages/server/pkg/flow/runner/flowlocalrunner/strategy_multi.go b/packages/server/pkg/flow/runner/flowlocalrunner/strategy_multi.go new file mode 100644 index 000000000..4997eec0e --- /dev/null +++ b/packages/server/pkg/flow/runner/flowlocalrunner/strategy_multi.go @@ -0,0 +1,281 @@ +package flowlocalrunner + +import ( + "context" + "errors" + "fmt" + "sync" + "sync/atomic" + "time" + + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/runner" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" +) + +type processResult struct { + originalID idwrap.IDWrap + executionID idwrap.IDWrap + nextNodes []idwrap.IDWrap + err error + inputData map[string]any + outputData map[string]any + skipFinalStatus bool // From FlowNodeResult.SkipFinalStatus + AuxiliaryID *idwrap.IDWrap + startTime time.Time // When the node started executing + timedOut bool // Whether the node hit a per-node deadline +} + +type nodeSignal struct { + once sync.Once + ch chan struct{} +} + +func acquireNodeSignal(signals *sync.Map, id idwrap.IDWrap) *nodeSignal { + val, _ := signals.LoadOrStore(id, &nodeSignal{ch: make(chan struct{})}) + return val.(*nodeSignal) +} + +func waitForPredecessors(ctx context.Context, signals, seen *sync.Map, predecessors []idwrap.IDWrap) error { + for _, predID := range predecessors { + if seen != nil { + if _, ok := seen.Load(predID); !ok { + continue + } + } + sig := acquireNodeSignal(signals, predID) + select { + case <-sig.ch: + case <-ctx.Done(): + return ctx.Err() + } + } + return nil +} + +func signalNodeComplete(signals *sync.Map, id idwrap.IDWrap) { + sig := acquireNodeSignal(signals, id) + sig.once.Do(func() { + close(sig.ch) + }) +} + +// runNodesMultiEventDriven executes nodes concurrently using an event-driven model. +// Unlike the previous batch model that waited for all nodes in a batch to complete, +// this dispatches successors immediately when a node finishes. Only converge points +// (nodes with multiple incoming edges) wait for all predecessors. +func runNodesMultiEventDriven(ctx context.Context, startNodeID idwrap.IDWrap, req *node.FlowNodeRequest, + cfg RunConfig, executor *LocalExecutor, tracker *runner.ConvergenceTracker, +) error { + nodeSignals := &sync.Map{} + seenNodes := &sync.Map{} + + // Semaphore for bounded processing concurrency + sem := make(chan struct{}, cfg.MaxConcurrency) + resultChan := make(chan processResult, cfg.MaxConcurrency) + + // Cancellation context for the entire execution + flowCtx, flowCancel := context.WithCancel(ctx) + defer flowCancel() + + var outstanding int64 + + // launchNode spawns a goroutine to execute a node. It never blocks the caller. + launchNode := func(nodeID idwrap.IDWrap) { + currentNode, ok := req.NodeMap[nodeID] + if !ok { + atomic.AddInt64(&outstanding, 1) + go func() { + resultChan <- processResult{ + originalID: nodeID, + err: fmt.Errorf("node not found: %v", nodeID), + } + }() + return + } + + seenNodes.Store(nodeID, struct{}{}) + atomic.AddInt64(&outstanding, 1) + + go func() { + // Phase 1: Wait for predecessors OUTSIDE the semaphore. + // This prevents deadlocks where goroutines hold semaphore slots + // while waiting for predecessors that need slots to finish. + if predecessors := cfg.PredecessorMap[nodeID]; len(predecessors) > 0 { + if err := waitForPredecessors(flowCtx, nodeSignals, seenNodes, predecessors); err != nil { + resultChan <- processResult{ + originalID: currentNode.GetID(), + err: err, + } + return + } + } + + // Phase 2: Acquire semaphore to bound active processing concurrency. + select { + case sem <- struct{}{}: + case <-flowCtx.Done(): + resultChan <- processResult{ + originalID: currentNode.GetID(), + err: flowCtx.Err(), + } + return + } + defer func() { <-sem }() + + // Generate execution ID right before processing + executionID := idwrap.NewMonotonic() + startTime := time.Now() + + // Atomically register + emit RUNNING (fixes race with cancellation) + cfg.Emitter.EmitRunning(runner.NodeExecution{ + ExecutionID: executionID, + NodeID: nodeID, + Name: currentNode.GetName(), + StartTime: startTime, + IterCtx: req.IterationContext, + }) + + // Create per-node request copy + nodeReq := *req + nodeReq.ExecutionID = executionID + + // Per-node timeout (skip for LoopCoordinator nodes) + nodeCtx := flowCtx + var cancelNode context.CancelFunc + if cfg.Timeout > 0 { + if _, isLoop := currentNode.(node.LoopCoordinator); !isLoop { + nodeCtx, cancelNode = context.WithTimeout(flowCtx, cfg.Timeout) + } + } + if cancelNode != nil { + defer cancelNode() + } + + // Execute the node with variable tracking + outcome := executor.Execute(nodeCtx, currentNode, &nodeReq) + inputData := outcome.TrackedInput + outputData := outcome.TrackedOutput + result := outcome.Result + + // Check for node-level timeout + nodeTimedOut := false + if result.Err == nil && nodeCtx.Err() != nil && errors.Is(nodeCtx.Err(), context.DeadlineExceeded) { + result.Err = nodeCtx.Err() + nodeTimedOut = true + } + + resultChan <- processResult{ + originalID: currentNode.GetID(), + executionID: executionID, + nextNodes: result.NextNodeID, + err: result.Err, + inputData: inputData, + outputData: outputData, + skipFinalStatus: result.SkipFinalStatus, + AuxiliaryID: result.AuxiliaryID, + startTime: startTime, + timedOut: nodeTimedOut, + } + }() + } + + defer func() { + if ctx.Err() != nil { + cfg.Emitter.CancelAllRunning(ctx.Err()) + } + }() + + // Launch start node + launchNode(startNodeID) + + // Main event loop: process results as they arrive + var firstErr error + + for atomic.LoadInt64(&outstanding) > 0 { + select { + case result := <-resultChan: + atomic.AddInt64(&outstanding, -1) + + currentNode := req.NodeMap[result.originalID] + nodeName := "" + if currentNode != nil { + nodeName = currentNode.GetName() + } + + // Signal that this node completed (unblocks nodes waiting for it) + signalNodeComplete(nodeSignals, result.originalID) + + // Build base status (shared across all terminal paths) + base := runner.FlowNodeStatus{ + NodeID: result.originalID, + ExecutionID: result.executionID, + Name: nodeName, + IterationContext: req.IterationContext, + RunDuration: time.Since(result.startTime), + AuxiliaryID: result.AuxiliaryID, + } + + // ERROR PATH + if result.err != nil { + status := buildTerminalStatus(base, result.err, result.timedOut, result.inputData, result.outputData, req, cfg.TrackData) + cfg.Emitter.EmitTerminal(result.executionID, status, false) + + if firstErr == nil { + firstErr = result.err + } + // Cancel all other in-flight work + flowCancel() + continue + } + + // Check if flow was already canceled (by another node's failure) + if flowCtx.Err() != nil { + isLoop := false + if currentNode != nil { + _, isLoop = currentNode.(node.LoopCoordinator) + } + if !isLoop { + status := buildTerminalStatus(base, flowCtx.Err(), false, result.inputData, result.outputData, req, cfg.TrackData) + cfg.Emitter.EmitTerminal(result.executionID, status, false) + continue + } + // LoopCoordinator exemption: fall through to success path. + // EmitTerminal handles deregistration — calling Deregister here + // would clear wasRunning and suppress the success emission. + } + + // SUCCESS PATH + status := buildTerminalStatus(base, nil, false, result.inputData, result.outputData, req, cfg.TrackData) + cfg.Emitter.EmitTerminal(result.executionID, status, result.skipFinalStatus) + + // Dispatch ready successors immediately + if firstErr == nil { + for _, nextID := range result.nextNodes { + if !tracker.Arrive(nextID) { + continue + } + launchNode(nextID) + } + } + + case <-ctx.Done(): + flowCancel() + // Send CANCELED status for all currently running nodes + // BEFORE draining, since drain removes goroutines from tracking. + cfg.Emitter.CancelAllRunning(ctx.Err()) + // Drain remaining results so goroutines can exit + for atomic.LoadInt64(&outstanding) > 0 { + result := <-resultChan + atomic.AddInt64(&outstanding, -1) + signalNodeComplete(nodeSignals, result.originalID) + } + if firstErr != nil { + return firstErr + } + return ctx.Err() + } + } + + return firstErr +} diff --git a/packages/server/pkg/flow/runner/flowlocalrunner/strategy_single.go b/packages/server/pkg/flow/runner/flowlocalrunner/strategy_single.go new file mode 100644 index 000000000..acd830b69 --- /dev/null +++ b/packages/server/pkg/flow/runner/flowlocalrunner/strategy_single.go @@ -0,0 +1,106 @@ +package flowlocalrunner + +import ( + "context" + "fmt" + "time" + + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/node" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/flow/runner" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" +) + +func sendQueuedCancellationStatuses(queue []idwrap.IDWrap, req *node.FlowNodeRequest, statusLogFunc node.LogPushFunc, cancelErr error) { + for _, nodeID := range queue { + if nodeRef, ok := req.NodeMap[nodeID]; ok { + statusLogFunc(runner.FlowNodeStatus{ + ExecutionID: idwrap.NewMonotonic(), + NodeID: nodeID, + Name: nodeRef.GetName(), + State: mflow.NODE_STATE_CANCELED, + Error: cancelErr, + IterationContext: req.IterationContext, + }) + } + } +} + +func runNodesSingle(ctx context.Context, startNodeID idwrap.IDWrap, req *node.FlowNodeRequest, + cfg RunConfig, executor *LocalExecutor, tracker *runner.ConvergenceTracker, +) error { + queue := []idwrap.IDWrap{startNodeID} + + for len(queue) > 0 { + if ctx.Err() != nil { + sendQueuedCancellationStatuses(queue, req, cfg.StatusLogFunc, ctx.Err()) + return ctx.Err() + } + + nodeID := queue[0] + queue = queue[1:] + + currentNode, ok := req.NodeMap[nodeID] + if !ok { + return fmt.Errorf("node not found: %v", nodeID) + } + + executionID := idwrap.NewMonotonic() + cfg.StatusLogFunc(runner.FlowNodeStatus{ + ExecutionID: executionID, + NodeID: nodeID, + Name: currentNode.GetName(), + State: mflow.NODE_STATE_RUNNING, + IterationContext: req.IterationContext, + }) + + nodeReq := *req + nodeReq.ExecutionID = executionID + + nodeCtx := ctx + cancelNodeCtx := func() {} + if cfg.Timeout > 0 { + nodeCtx, cancelNodeCtx = context.WithTimeout(ctx, cfg.Timeout) + } + startTime := time.Now() + + outcome := executor.Execute(nodeCtx, currentNode, &nodeReq) + nodeCtxErr := nodeCtx.Err() + cancelNodeCtx() + + // Merge node error with context timeout + nodeErr := outcome.Result.Err + if nodeErr == nil && nodeCtxErr != nil { + nodeErr = nodeCtxErr + } + + base := runner.FlowNodeStatus{ + ExecutionID: executionID, + NodeID: nodeID, + Name: currentNode.GetName(), + IterationContext: req.IterationContext, + RunDuration: time.Since(startTime), + AuxiliaryID: outcome.Result.AuxiliaryID, + } + + if nodeErr != nil { + status := buildTerminalStatus(base, nodeErr, false, outcome.TrackedInput, outcome.TrackedOutput, req, cfg.TrackData) + cfg.StatusLogFunc(status) + return nodeErr + } + + if !outcome.Result.SkipFinalStatus { + status := buildTerminalStatus(base, nil, false, outcome.TrackedInput, outcome.TrackedOutput, req, cfg.TrackData) + cfg.StatusLogFunc(status) + } + + for _, nextID := range outcome.Result.NextNodeID { + if !tracker.Arrive(nextID) { + continue + } + queue = append(queue, nextID) + } + } + + return nil +} diff --git a/packages/server/pkg/flow/runner/graph.go b/packages/server/pkg/flow/runner/graph.go new file mode 100644 index 000000000..f49798346 --- /dev/null +++ b/packages/server/pkg/flow/runner/graph.go @@ -0,0 +1,126 @@ +package runner + +import ( + "sync" + + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" +) + +// FlowGraph is an immutable representation of a flow's DAG topology. +// Constructed once before execution begins, then shared across all components. +// It holds no node implementations (no node.FlowNode) to avoid import cycles. +type FlowGraph struct { + Edges mflow.EdgesMap + StartNodeIDs []idwrap.IDWrap + Predecessors map[idwrap.IDWrap][]idwrap.IDWrap + ConvergeCounts map[idwrap.IDWrap]uint32 +} + +// NewFlowGraph constructs an immutable graph from edges and start nodes. +// It precomputes predecessor maps and convergence counts. +func NewFlowGraph(edges mflow.EdgesMap, startNodeIDs []idwrap.IDWrap) *FlowGraph { + predecessors := BuildPredecessorMap(edges) + convergeCounts := make(map[idwrap.IDWrap]uint32) + for nodeID, preds := range predecessors { + if count := uint32(len(preds)); count > 1 { //nolint:gosec // G115 + convergeCounts[nodeID] = count + } + } + return &FlowGraph{ + Edges: edges, + StartNodeIDs: startNodeIDs, + Predecessors: predecessors, + ConvergeCounts: convergeCounts, + } +} + +// NewFlowGraphFromPredecessors constructs a FlowGraph when the predecessor map +// is already computed (e.g., inside RunNodeSync where loop nodes pre-build it). +func NewFlowGraphFromPredecessors( + edges mflow.EdgesMap, + startNodeID idwrap.IDWrap, + predecessors map[idwrap.IDWrap][]idwrap.IDWrap, +) *FlowGraph { + convergeCounts := make(map[idwrap.IDWrap]uint32) + for nodeID, preds := range predecessors { + if count := uint32(len(preds)); count > 1 { //nolint:gosec // G115 + convergeCounts[nodeID] = count + } + } + return &FlowGraph{ + Edges: edges, + StartNodeIDs: []idwrap.IDWrap{startNodeID}, + Predecessors: predecessors, + ConvergeCounts: convergeCounts, + } +} + +// NewConvergenceTracker creates a fresh mutable tracker for one execution. +func (g *FlowGraph) NewConvergenceTracker() *ConvergenceTracker { + pending := make(map[idwrap.IDWrap]uint32, len(g.ConvergeCounts)) + for nodeID, count := range g.ConvergeCounts { + pending[nodeID] = count + } + return &ConvergenceTracker{pending: pending} +} + +// NewConvergenceTrackerFromPending creates a tracker from a pre-built pending +// map (e.g. from FlowNodeRequest.PendingAtmoicMap). It copies the map to avoid +// aliasing the original. +func NewConvergenceTrackerFromPending(pending map[idwrap.IDWrap]uint32) *ConvergenceTracker { + clone := make(map[idwrap.IDWrap]uint32, len(pending)) + for k, v := range pending { + clone[k] = v + } + return &ConvergenceTracker{pending: clone} +} + +// BuildPredecessorMap computes which nodes precede each node in the graph. +func BuildPredecessorMap(edges mflow.EdgesMap) map[idwrap.IDWrap][]idwrap.IDWrap { + predecessors := make(map[idwrap.IDWrap][]idwrap.IDWrap, len(edges)) + for sourceID, handles := range edges { + for _, targets := range handles { + for _, targetID := range targets { + predecessors[targetID] = append(predecessors[targetID], sourceID) + } + } + } + return predecessors +} + +// ConvergenceTracker tracks how many predecessors have completed for +// convergence (join) nodes. It is the mutable counterpart to FlowGraph's +// immutable ConvergeCounts. +type ConvergenceTracker struct { + mu sync.Mutex + pending map[idwrap.IDWrap]uint32 +} + +// Arrive records that one predecessor of nodeID has completed. +// Returns true when all predecessors have arrived (the node is ready). +func (ct *ConvergenceTracker) Arrive(nodeID idwrap.IDWrap) bool { + ct.mu.Lock() + defer ct.mu.Unlock() + remaining, ok := ct.pending[nodeID] + if !ok { + return true // not a convergence point + } + if remaining <= 1 { + delete(ct.pending, nodeID) + return true + } + ct.pending[nodeID] = remaining - 1 + return false +} + +// Clone creates an independent copy for loop iteration isolation. +func (ct *ConvergenceTracker) Clone() *ConvergenceTracker { + ct.mu.Lock() + defer ct.mu.Unlock() + clone := make(map[idwrap.IDWrap]uint32, len(ct.pending)) + for k, v := range ct.pending { + clone[k] = v + } + return &ConvergenceTracker{pending: clone} +} diff --git a/packages/server/pkg/flow/runner/runner.go b/packages/server/pkg/flow/runner/runner.go index e1e946eaf..a947cd23a 100644 --- a/packages/server/pkg/flow/runner/runner.go +++ b/packages/server/pkg/flow/runner/runner.go @@ -70,15 +70,6 @@ type FlowNodeStatus struct { AuxiliaryID *idwrap.IDWrap } -func NewFlowNodeStatus(nodeID idwrap.IDWrap, status mflow.NodeState, output []byte) FlowNodeStatus { - return FlowNodeStatus{ - NodeID: nodeID, - State: status, - OutputData: output, - Error: nil, - } -} - type FlowNodeEventTarget uint8 const ( diff --git a/packages/server/pkg/flow/runner/status.go b/packages/server/pkg/flow/runner/status.go new file mode 100644 index 000000000..9d12b2516 --- /dev/null +++ b/packages/server/pkg/flow/runner/status.go @@ -0,0 +1,160 @@ +package runner + +import ( + "sync" + "time" + + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" +) + +// NodeExecution identifies a single node execution for status tracking. +type NodeExecution struct { + ExecutionID idwrap.IDWrap + NodeID idwrap.IDWrap + Name string + StartTime time.Time + IterCtx *IterationContext +} + +// StatusEmitter tracks running nodes and emits status events. +// It delegates the actual event delivery to an emit function, making it +// usable with both channel-based delivery (RunWithEvents) and callback-based +// delivery (RunNodeSync from loop nodes). +// +// For a remote runner, the same StatusEmitter works — only the emitFn changes. +type StatusEmitter struct { + emitFn func(FlowNodeStatus) + + mu sync.Mutex + running map[idwrap.IDWrap]runningEntry +} + +type runningEntry struct { + nodeID idwrap.IDWrap + name string + startTime time.Time + iterCtx *IterationContext +} + +// NewStatusEmitter creates an emitter that delegates to the given function. +func NewStatusEmitter(emitFn func(FlowNodeStatus)) *StatusEmitter { + return &StatusEmitter{ + emitFn: emitFn, + running: make(map[idwrap.IDWrap]runningEntry), + } +} + +// Emit sends a status event. This is used as the LogPushFunc callback for nodes. +func (se *StatusEmitter) Emit(status FlowNodeStatus) { + se.emitFn(status) +} + +// EmitRunning atomically registers a node as running and emits RUNNING status. +// This eliminates the race where cancellation could miss a node between +// status emission and registration. +func (se *StatusEmitter) EmitRunning(exec NodeExecution) { + se.mu.Lock() + se.running[exec.ExecutionID] = runningEntry{ + nodeID: exec.NodeID, + name: exec.Name, + startTime: exec.StartTime, + iterCtx: exec.IterCtx, + } + se.mu.Unlock() + + se.emitFn(FlowNodeStatus{ + ExecutionID: exec.ExecutionID, + NodeID: exec.NodeID, + Name: exec.Name, + State: mflow.NODE_STATE_RUNNING, + IterationContext: exec.IterCtx, + }) +} + +// EmitTerminal deregisters the node and emits a pre-built terminal status. +// The wasRunning guard prevents double emission: if CancelAllRunning already +// processed this node (cleared from running map), emission is skipped. +func (se *StatusEmitter) EmitTerminal(executionID idwrap.IDWrap, status FlowNodeStatus, skip bool) { + se.mu.Lock() + _, wasRunning := se.running[executionID] + delete(se.running, executionID) + se.mu.Unlock() + + if skip || !wasRunning { + return + } + se.emitFn(status) +} + +// Deregister removes a node from running tracking without emitting a status. +// Used when the caller handles status emission itself (e.g., with custom state +// logic for errors, timeouts, or loop coordinators). +func (se *StatusEmitter) Deregister(executionID idwrap.IDWrap) { + se.mu.Lock() + delete(se.running, executionID) + se.mu.Unlock() +} + +// CancelAllRunning emits CANCELED for every node currently tracked as RUNNING. +// Called during context cancellation cleanup. +func (se *StatusEmitter) CancelAllRunning(cancelErr error) { + se.mu.Lock() + entries := make(map[idwrap.IDWrap]runningEntry, len(se.running)) + for k, v := range se.running { + entries[k] = v + } + se.running = make(map[idwrap.IDWrap]runningEntry) + se.mu.Unlock() + + for execID, entry := range entries { + se.emitFn(FlowNodeStatus{ + ExecutionID: execID, + NodeID: entry.nodeID, + Name: entry.name, + State: mflow.NODE_STATE_CANCELED, + Error: cancelErr, + RunDuration: time.Since(entry.startTime), + IterationContext: entry.iterCtx, + }) + } +} + +// NewChannelEmitFunc creates an emit function that routes status events to +// FlowEventChannels. RUNNING events go to NodeStates only; terminal events +// go to both NodeStates and NodeLogs. +// Safe to call after channels are closed (recovers from send-on-closed-channel). +func NewChannelEmitFunc(channels FlowEventChannels) func(FlowNodeStatus) { + return func(status FlowNodeStatus) { + // Background goroutines (e.g., WebSocket message readers) may try to emit + // after RunWithEvents closes channels. Recover rather than crashing. + defer func() { recover() }() //nolint:errcheck // intentional panic recovery + + targets := FlowNodeEventTargetState + if status.State != mflow.NODE_STATE_RUNNING { + targets |= FlowNodeEventTargetLog + } + event := FlowNodeEvent{ + Status: status, + Targets: targets, + } + if event.ShouldSend(FlowNodeEventTargetState) && channels.NodeStates != nil { + channels.NodeStates <- event.Status + } + if event.ShouldSend(FlowNodeEventTargetLog) && channels.NodeLogs != nil { + channels.NodeLogs <- FlowNodeLogPayload{ + ExecutionID: status.ExecutionID, + NodeID: status.NodeID, + Name: status.Name, + State: status.State, + Error: status.Error, + OutputData: status.OutputData, + RunDuration: status.RunDuration, + IterationContext: status.IterationContext, + IterationEvent: status.IterationEvent, + IterationIndex: status.IterationIndex, + LoopNodeID: status.LoopNodeID, + } + } + } +} diff --git a/packages/server/pkg/flow/simulation/mockflows.go b/packages/server/pkg/flow/simulation/mockflows.go index e04d8b840..383c9632f 100644 --- a/packages/server/pkg/flow/simulation/mockflows.go +++ b/packages/server/pkg/flow/simulation/mockflows.go @@ -19,10 +19,11 @@ type MockFlowParams struct { // MockFlowResult contains the three data structures FlowLocalRunner needs type MockFlowResult struct { - Nodes map[idwrap.IDWrap]node.FlowNode - Edges []mflow.Edge - EdgesMap mflow.EdgesMap - StartNodeID idwrap.IDWrap + Nodes map[idwrap.IDWrap]node.FlowNode + Edges []mflow.Edge + EdgesMap mflow.EdgesMap + StartNodeID idwrap.IDWrap + StartNodeIDs []idwrap.IDWrap } // CreateMockFlow creates a simple linear mock flow for testing @@ -109,9 +110,10 @@ func CreateMockFlow(params MockFlowParams) MockFlowResult { edgesMap := mflow.NewEdgesMap(edges) return MockFlowResult{ - Nodes: nodes, - Edges: edges, - EdgesMap: edgesMap, - StartNodeID: startNodeID, + Nodes: nodes, + Edges: edges, + EdgesMap: edgesMap, + StartNodeID: startNodeID, + StartNodeIDs: []idwrap.IDWrap{startNodeID}, } } diff --git a/packages/server/pkg/flow/simulation/mockflows_test.go b/packages/server/pkg/flow/simulation/mockflows_test.go index 4ed2215ca..c145d1fda 100644 --- a/packages/server/pkg/flow/simulation/mockflows_test.go +++ b/packages/server/pkg/flow/simulation/mockflows_test.go @@ -246,7 +246,7 @@ func TestCreateMockFlow_IntegrationWithFlowLocalRunner(t *testing.T) { flowRunner := flowlocalrunner.CreateFlowRunner( idwrap.NewNow(), flowID, - result.StartNodeID, + result.StartNodeIDs, result.Nodes, result.EdgesMap, 5*time.Second, // 5 second timeout @@ -334,7 +334,7 @@ func TestCreateMockFlow_Performance_BasicLoad(t *testing.T) { flowRunner := flowlocalrunner.CreateFlowRunner( idwrap.NewNow(), flowID, - result.StartNodeID, + result.StartNodeIDs, result.Nodes, result.EdgesMap, 10*time.Second, // Generous timeout @@ -455,7 +455,7 @@ func TestCreateMockFlow_ExecutionModeSelection(t *testing.T) { flowRunner := flowlocalrunner.CreateFlowRunner( idwrap.NewNow(), flowID, - result.StartNodeID, + result.StartNodeIDs, result.Nodes, result.EdgesMap, 5*time.Second, @@ -521,7 +521,7 @@ func TestCreateMockFlow_TimeoutBehavior(t *testing.T) { flowRunner := flowlocalrunner.CreateFlowRunner( idwrap.NewNow(), flowID, - result.StartNodeID, + result.StartNodeIDs, result.Nodes, result.EdgesMap, timeout, @@ -676,7 +676,7 @@ func BenchmarkFlowExecution_Small(b *testing.B) { flowRunner := flowlocalrunner.CreateFlowRunner( idwrap.NewNow(), flowID, - result.StartNodeID, + result.StartNodeIDs, result.Nodes, result.EdgesMap, 5*time.Second, @@ -713,7 +713,7 @@ func BenchmarkFlowExecution_Medium(b *testing.B) { flowRunner := flowlocalrunner.CreateFlowRunner( idwrap.NewNow(), flowID, - result.StartNodeID, + result.StartNodeIDs, result.Nodes, result.EdgesMap, 10*time.Second, @@ -750,7 +750,7 @@ func BenchmarkFlowExecution_Large(b *testing.B) { flowRunner := flowlocalrunner.CreateFlowRunner( idwrap.NewNow(), flowID, - result.StartNodeID, + result.StartNodeIDs, result.Nodes, result.EdgesMap, 30*time.Second, diff --git a/packages/server/pkg/ioworkspace/exporter.go b/packages/server/pkg/ioworkspace/exporter.go index 014ac5fa5..bc8fb2bb4 100644 --- a/packages/server/pkg/ioworkspace/exporter.go +++ b/packages/server/pkg/ioworkspace/exporter.go @@ -15,6 +15,7 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sflow" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sgraphql" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/shttp" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/swebsocket" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sworkspace" ) @@ -228,6 +229,11 @@ func (s *IOWorkspaceService) exportFlows(ctx context.Context, opts ExportOptions nodeAIProviderService := sflow.NewNodeAiProviderService(s.queries) nodeMemoryService := sflow.NewNodeMemoryService(s.queries) nodeGraphQLService := sflow.NewNodeGraphQLService(s.queries) + nodeWsConnectionService := sflow.NewNodeWsConnectionService(s.queries) + nodeWsSendService := sflow.NewNodeWsSendService(s.queries) + nodeWaitService := sflow.NewNodeWaitService(s.queries) + websocketService := swebsocket.New(s.queries, s.logger) + websocketHeaderService := swebsocket.NewWebSocketHeaderService(s.queries) var flowIDs []idwrap.IDWrap @@ -281,7 +287,7 @@ func (s *IOWorkspaceService) exportFlows(ctx context.Context, opts ExportOptions // Export node implementations based on node types for _, node := range nodes { - if err := s.exportNodeImplementation(ctx, node, bundle, nodeRequestService, nodeIfService, nodeForService, nodeForEachService, nodeJSService, nodeAIService, nodeAIProviderService, nodeMemoryService, nodeGraphQLService); err != nil { + if err := s.exportNodeImplementation(ctx, node, bundle, nodeRequestService, nodeIfService, nodeForService, nodeForEachService, nodeJSService, nodeAIService, nodeAIProviderService, nodeMemoryService, nodeGraphQLService, nodeWsConnectionService, nodeWsSendService, nodeWaitService, websocketService, websocketHeaderService); err != nil { return fmt.Errorf("failed to export node implementation for node %s: %w", node.ID.String(), err) } } @@ -299,7 +305,10 @@ func (s *IOWorkspaceService) exportFlows(ctx context.Context, opts ExportOptions "ai_nodes", len(bundle.FlowAINodes), "ai_provider_nodes", len(bundle.FlowAIProviderNodes), "ai_memory_nodes", len(bundle.FlowAIMemoryNodes), - "graphql_nodes", len(bundle.FlowGraphQLNodes)) + "graphql_nodes", len(bundle.FlowGraphQLNodes), + "ws_connection_nodes", len(bundle.FlowWsConnectionNodes), + "ws_send_nodes", len(bundle.FlowWsSendNodes), + "wait_nodes", len(bundle.FlowWaitNodes)) return nil } @@ -352,8 +361,15 @@ func (s *IOWorkspaceService) exportNodeImplementation( nodeAIProviderService sflow.NodeAiProviderService, nodeMemoryService sflow.NodeMemoryService, nodeGraphQLService sflow.NodeGraphQLService, + nodeWsConnectionService sflow.NodeWsConnectionService, + nodeWsSendService sflow.NodeWsSendService, + nodeWaitService sflow.NodeWaitService, + websocketService swebsocket.WebSocketService, + websocketHeaderService swebsocket.WebSocketHeaderService, ) error { switch node.NodeKind { + case mflow.NODE_KIND_MANUAL_START: + // No type-specific data for ManualStart case mflow.NODE_KIND_REQUEST: nodeRequest, err := nodeRequestService.GetNodeRequest(ctx, node.ID) if err != nil { @@ -434,6 +450,48 @@ func (s *IOWorkspaceService) exportNodeImplementation( if nodeGraphQL != nil { bundle.FlowGraphQLNodes = append(bundle.FlowGraphQLNodes, *nodeGraphQL) } + + case mflow.NODE_KIND_WS_CONNECTION: + nodeWsConn, err := nodeWsConnectionService.GetNodeWsConnection(ctx, node.ID) + if err != nil { + return fmt.Errorf("failed to get ws connection node: %w", err) + } + if nodeWsConn != nil { + bundle.FlowWsConnectionNodes = append(bundle.FlowWsConnectionNodes, *nodeWsConn) + // Also fetch and store the WebSocket entity and headers + if nodeWsConn.WebSocketID != nil { + wsEntity, err := websocketService.Get(ctx, *nodeWsConn.WebSocketID) + if err != nil && !errors.Is(err, sql.ErrNoRows) { + return fmt.Errorf("failed to get websocket entity: %w", err) + } + if wsEntity != nil { + bundle.WebSockets = append(bundle.WebSockets, *wsEntity) + } + wsHeaders, err := websocketHeaderService.GetByWebSocketID(ctx, *nodeWsConn.WebSocketID) + if err != nil && !errors.Is(err, sql.ErrNoRows) { + return fmt.Errorf("failed to get websocket headers: %w", err) + } + bundle.WebSocketHeaders = append(bundle.WebSocketHeaders, wsHeaders...) + } + } + + case mflow.NODE_KIND_WS_SEND: + nodeWsSend, err := nodeWsSendService.GetNodeWsSend(ctx, node.ID) + if err != nil { + return fmt.Errorf("failed to get ws send node: %w", err) + } + if nodeWsSend != nil { + bundle.FlowWsSendNodes = append(bundle.FlowWsSendNodes, *nodeWsSend) + } + + case mflow.NODE_KIND_WAIT: + nodeWait, err := nodeWaitService.GetNodeWait(ctx, node.ID) + if err != nil { + return fmt.Errorf("failed to get wait node: %w", err) + } + if nodeWait != nil { + bundle.FlowWaitNodes = append(bundle.FlowWaitNodes, *nodeWait) + } } return nil diff --git a/packages/server/pkg/ioworkspace/importer.go b/packages/server/pkg/ioworkspace/importer.go index e64d3360e..a34135cf5 100644 --- a/packages/server/pkg/ioworkspace/importer.go +++ b/packages/server/pkg/ioworkspace/importer.go @@ -11,6 +11,7 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sflow" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sgraphql" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/shttp" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/swebsocket" ) // ImportResult contains statistics and mappings from the import operation. @@ -36,8 +37,13 @@ type ImportResult struct { FlowAINodesCreated int FlowAIProviderNodesCreated int FlowAIMemoryNodesCreated int - FlowGraphQLNodesCreated int - GraphQLRequestsCreated int + FlowGraphQLNodesCreated int + FlowWsConnectionNodesCreated int + FlowWsSendNodesCreated int + FlowWaitNodesCreated int + WebSocketsCreated int + WebSocketHeadersCreated int + GraphQLRequestsCreated int GraphQLHeadersCreated int GraphQLAssertsCreated int EnvironmentsCreated int @@ -49,6 +55,7 @@ type ImportResult struct { NodeIDMap map[idwrap.IDWrap]idwrap.IDWrap FileIDMap map[idwrap.IDWrap]idwrap.IDWrap EnvironmentIDMap map[idwrap.IDWrap]idwrap.IDWrap + WebSocketIDMap map[idwrap.IDWrap]idwrap.IDWrap } // Import imports a WorkspaceBundle into the database using the provided options. @@ -66,6 +73,7 @@ func (s *IOWorkspaceService) Import(ctx context.Context, tx *sql.Tx, bundle *Wor NodeIDMap: make(map[idwrap.IDWrap]idwrap.IDWrap), FileIDMap: make(map[idwrap.IDWrap]idwrap.IDWrap), EnvironmentIDMap: make(map[idwrap.IDWrap]idwrap.IDWrap), + WebSocketIDMap: make(map[idwrap.IDWrap]idwrap.IDWrap), } // Create service instances with transaction support @@ -91,11 +99,17 @@ func (s *IOWorkspaceService) Import(ctx context.Context, tx *sql.Tx, bundle *Wor nodeAIProviderService := sflow.NewNodeAiProviderService(s.queries).TX(tx) nodeMemoryService := sflow.NewNodeMemoryService(s.queries).TX(tx) nodeGraphQLService := sflow.NewNodeGraphQLService(s.queries).TX(tx) + nodeWsConnectionService := sflow.NewNodeWsConnectionService(s.queries).TX(tx) + nodeWsSendService := sflow.NewNodeWsSendService(s.queries).TX(tx) + nodeWaitService := sflow.NewNodeWaitService(s.queries).TX(tx) graphqlService := sgraphql.New(s.queries, nil).TX(tx) graphqlHeaderService := sgraphql.NewGraphQLHeaderService(s.queries).TX(tx) graphqlAssertService := sgraphql.NewGraphQLAssertService(s.queries).TX(tx) + websocketService := swebsocket.New(s.queries, nil).TX(tx) + websocketHeaderService := swebsocket.NewWebSocketHeaderService(s.queries).TX(tx) + fileService := sfile.New(s.queries, nil).TX(tx) envService := senv.NewEnvironmentService(s.queries, nil).TX(tx) varService := senv.NewVariableService(s.queries, nil).TX(tx) @@ -120,6 +134,12 @@ func (s *IOWorkspaceService) Import(ctx context.Context, tx *sql.Tx, bundle *Wor } } + if opts.ImportHTTP && len(bundle.WebSockets) > 0 { + if err := s.importWebSockets(ctx, websocketService, bundle, opts, result); err != nil { + return nil, fmt.Errorf("failed to import WebSocket requests: %w", err) + } + } + if opts.CreateFiles && len(bundle.Files) > 0 { if err := s.importFiles(ctx, fileService, bundle, opts, result); err != nil { return nil, fmt.Errorf("failed to import files: %w", err) @@ -159,6 +179,12 @@ func (s *IOWorkspaceService) Import(ctx context.Context, tx *sql.Tx, bundle *Wor } } + if opts.ImportHTTP && len(bundle.WebSocketHeaders) > 0 { + if err := s.importWebSocketHeaders(ctx, websocketHeaderService, bundle, opts, result); err != nil { + return nil, fmt.Errorf("failed to import WebSocket headers: %w", err) + } + } + if opts.ImportHTTP { if len(bundle.HTTPHeaders) > 0 { if err := s.importHTTPHeaders(ctx, httpHeaderService, bundle, opts, result); err != nil { @@ -265,6 +291,24 @@ func (s *IOWorkspaceService) Import(ctx context.Context, tx *sql.Tx, bundle *Wor return nil, fmt.Errorf("failed to import flow GraphQL nodes: %w", err) } } + + if len(bundle.FlowWsConnectionNodes) > 0 { + if err := s.importFlowWsConnectionNodes(ctx, nodeWsConnectionService, bundle, opts, result); err != nil { + return nil, fmt.Errorf("failed to import flow WS connection nodes: %w", err) + } + } + + if len(bundle.FlowWsSendNodes) > 0 { + if err := s.importFlowWsSendNodes(ctx, nodeWsSendService, bundle, opts, result); err != nil { + return nil, fmt.Errorf("failed to import flow WS send nodes: %w", err) + } + } + + if len(bundle.FlowWaitNodes) > 0 { + if err := s.importFlowWaitNodes(ctx, nodeWaitService, bundle, opts, result); err != nil { + return nil, fmt.Errorf("failed to import flow wait nodes: %w", err) + } + } } return result, nil diff --git a/packages/server/pkg/ioworkspace/importer_flow.go b/packages/server/pkg/ioworkspace/importer_flow.go index c8602a7a7..4840ff801 100644 --- a/packages/server/pkg/ioworkspace/importer_flow.go +++ b/packages/server/pkg/ioworkspace/importer_flow.go @@ -8,6 +8,7 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sflow" "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/sgraphql" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/service/swebsocket" ) // importFlows imports flows from the bundle. @@ -355,3 +356,100 @@ func (s *IOWorkspaceService) importFlowGraphQLNodes(ctx context.Context, nodeGra } return nil } + +// importFlowWsConnectionNodes imports flow WS connection nodes from the bundle. +func (s *IOWorkspaceService) importFlowWsConnectionNodes(ctx context.Context, nodeWsConnectionService sflow.NodeWsConnectionService, bundle *WorkspaceBundle, _ ImportOptions, result *ImportResult) error { + for _, wsNode := range bundle.FlowWsConnectionNodes { + if newNodeID, ok := result.NodeIDMap[wsNode.FlowNodeID]; ok { + wsNode.FlowNodeID = newNodeID + } + + // Remap WebSocket ID + if wsNode.WebSocketID != nil { + if newWSID, ok := result.WebSocketIDMap[*wsNode.WebSocketID]; ok { + wsNode.WebSocketID = &newWSID + } + } + + if err := nodeWsConnectionService.CreateNodeWsConnection(ctx, wsNode); err != nil { + return fmt.Errorf("failed to create flow WS connection node: %w", err) + } + + result.FlowWsConnectionNodesCreated++ + } + return nil +} + +// importFlowWsSendNodes imports flow WS send nodes from the bundle. +func (s *IOWorkspaceService) importFlowWsSendNodes(ctx context.Context, nodeWsSendService sflow.NodeWsSendService, bundle *WorkspaceBundle, _ ImportOptions, result *ImportResult) error { + for _, wsNode := range bundle.FlowWsSendNodes { + if newNodeID, ok := result.NodeIDMap[wsNode.FlowNodeID]; ok { + wsNode.FlowNodeID = newNodeID + } + + if err := nodeWsSendService.CreateNodeWsSend(ctx, wsNode); err != nil { + return fmt.Errorf("failed to create flow WS send node: %w", err) + } + + result.FlowWsSendNodesCreated++ + } + return nil +} + +// importFlowWaitNodes imports flow wait nodes from the bundle. +func (s *IOWorkspaceService) importFlowWaitNodes(ctx context.Context, nodeWaitService sflow.NodeWaitService, bundle *WorkspaceBundle, _ ImportOptions, result *ImportResult) error { + for _, waitNode := range bundle.FlowWaitNodes { + if newNodeID, ok := result.NodeIDMap[waitNode.FlowNodeID]; ok { + waitNode.FlowNodeID = newNodeID + } + + if err := nodeWaitService.CreateNodeWait(ctx, waitNode); err != nil { + return fmt.Errorf("failed to create flow wait node: %w", err) + } + + result.FlowWaitNodesCreated++ + } + return nil +} + +// importWebSockets imports WebSocket entities from the bundle. +func (s *IOWorkspaceService) importWebSockets(ctx context.Context, wsService swebsocket.WebSocketService, bundle *WorkspaceBundle, opts ImportOptions, result *ImportResult) error { + for _, ws := range bundle.WebSockets { + oldID := ws.ID + + if !opts.PreserveIDs { + ws.ID = idwrap.NewNow() + } + ws.WorkspaceID = opts.WorkspaceID + + if err := wsService.Create(ctx, &ws); err != nil { + return fmt.Errorf("failed to create WebSocket %s: %w", ws.Name, err) + } + + result.WebSocketIDMap[oldID] = ws.ID + result.WebSocketsCreated++ + } + return nil +} + +// importWebSocketHeaders imports WebSocket headers from the bundle. +func (s *IOWorkspaceService) importWebSocketHeaders(ctx context.Context, wsHeaderService swebsocket.WebSocketHeaderService, bundle *WorkspaceBundle, opts ImportOptions, result *ImportResult) error { + for _, h := range bundle.WebSocketHeaders { + // Generate new ID if not preserving + if !opts.PreserveIDs { + h.ID = idwrap.NewNow() + } + + // Remap parent WebSocket ID + if newWSID, ok := result.WebSocketIDMap[h.WebSocketID]; ok { + h.WebSocketID = newWSID + } + + if err := wsHeaderService.Create(ctx, h); err != nil { + return fmt.Errorf("failed to create WebSocket header: %w", err) + } + + result.WebSocketHeadersCreated++ + } + return nil +} diff --git a/packages/server/pkg/ioworkspace/types.go b/packages/server/pkg/ioworkspace/types.go index b8eb6747f..ff2328af1 100644 --- a/packages/server/pkg/ioworkspace/types.go +++ b/packages/server/pkg/ioworkspace/types.go @@ -8,6 +8,7 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mgraphql" "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mhttp" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mwebsocket" "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mworkspace" ) @@ -32,6 +33,10 @@ type WorkspaceBundle struct { GraphQLHeaders []mgraphql.GraphQLHeader GraphQLAsserts []mgraphql.GraphQLAssert + // WebSocket requests and associated data + WebSockets []mwebsocket.WebSocket + WebSocketHeaders []mwebsocket.WebSocketHeader + // File organization Files []mfile.File @@ -50,7 +55,10 @@ type WorkspaceBundle struct { FlowAINodes []mflow.NodeAI FlowAIProviderNodes []mflow.NodeAiProvider FlowAIMemoryNodes []mflow.NodeMemory - FlowGraphQLNodes []mflow.NodeGraphQL + FlowGraphQLNodes []mflow.NodeGraphQL + FlowWsConnectionNodes []mflow.NodeWsConnection + FlowWsSendNodes []mflow.NodeWsSend + FlowWaitNodes []mflow.NodeWait // Environments and variables Environments []menv.Env @@ -73,6 +81,8 @@ func (wb *WorkspaceBundle) CountEntities() map[string]int { "http_asserts": len(wb.HTTPAsserts), "graphql_requests": len(wb.GraphQLRequests), "graphql_headers": len(wb.GraphQLHeaders), + "websockets": len(wb.WebSockets), + "websocket_headers": len(wb.WebSocketHeaders), "files": len(wb.Files), "flows": len(wb.Flows), "flow_variables": len(wb.FlowVariables), @@ -86,8 +96,11 @@ func (wb *WorkspaceBundle) CountEntities() map[string]int { "flow_ai_nodes": len(wb.FlowAINodes), "flow_ai_provider_nodes": len(wb.FlowAIProviderNodes), "flow_ai_memory_nodes": len(wb.FlowAIMemoryNodes), - "flow_graphql_nodes": len(wb.FlowGraphQLNodes), - "environments": len(wb.Environments), + "flow_graphql_nodes": len(wb.FlowGraphQLNodes), + "flow_ws_connection_nodes": len(wb.FlowWsConnectionNodes), + "flow_ws_send_nodes": len(wb.FlowWsSendNodes), + "flow_wait_nodes": len(wb.FlowWaitNodes), + "environments": len(wb.Environments), "environment_vars": len(wb.EnvironmentVars), "credentials": len(wb.Credentials), } diff --git a/packages/server/pkg/model/mfile/mfile.go b/packages/server/pkg/model/mfile/mfile.go index 5d0920615..dbd15f66e 100644 --- a/packages/server/pkg/model/mfile/mfile.go +++ b/packages/server/pkg/model/mfile/mfile.go @@ -18,7 +18,8 @@ const ( ContentTypeHTTPDelta ContentType = 2 // http delta (draft/overlay) ContentTypeFlow ContentType = 3 // flow ContentTypeCredential ContentType = 4 // credential - ContentTypeGraphQL ContentType = 5 // graphql + ContentTypeGraphQL ContentType = 5 // graphql + ContentTypeWebSocket ContentType = 6 // websocket ) // String returns the string representation of ContentType @@ -36,6 +37,8 @@ func (ct ContentType) String() string { return "credential" case ContentTypeGraphQL: return "graphql" + case ContentTypeWebSocket: + return "websocket" default: return "unknown" } @@ -95,6 +98,11 @@ func (f File) IsGraphQL() bool { return f.ContentType == ContentTypeGraphQL } +// IsWebSocket returns true if the file contains a WebSocket connection +func (f File) IsWebSocket() bool { + return f.ContentType == ContentTypeWebSocket +} + // IsRoot returns true if the file has no parent folder func (f File) IsRoot() bool { return f.ParentID == nil @@ -140,6 +148,8 @@ func ContentTypeFromString(s string) ContentType { return ContentTypeCredential case "graphql": return ContentTypeGraphQL + case "websocket": + return ContentTypeWebSocket default: return ContentTypeUnknown } @@ -147,7 +157,7 @@ func ContentTypeFromString(s string) ContentType { // IsValidContentType checks if the content type is valid func IsValidContentType(kind ContentType) bool { - return kind == ContentTypeFolder || kind == ContentTypeFlow || kind == ContentTypeHTTP || kind == ContentTypeHTTPDelta || kind == ContentTypeCredential || kind == ContentTypeGraphQL + return kind == ContentTypeFolder || kind == ContentTypeFlow || kind == ContentTypeHTTP || kind == ContentTypeHTTPDelta || kind == ContentTypeCredential || kind == ContentTypeGraphQL || kind == ContentTypeWebSocket } // IDEquals checks if two IDWrap values are equal diff --git a/packages/server/pkg/model/mflow/edge.go b/packages/server/pkg/model/mflow/edge.go index 37b68d5e4..2cb2efd26 100644 --- a/packages/server/pkg/model/mflow/edge.go +++ b/packages/server/pkg/model/mflow/edge.go @@ -23,6 +23,7 @@ const ( HandleAiProvider HandleAiMemory HandleAiTools + HandleWsMessage HandleLength ) diff --git a/packages/server/pkg/model/mflow/node.go b/packages/server/pkg/model/mflow/node.go index 8218e74ae..35ed7dd76 100644 --- a/packages/server/pkg/model/mflow/node.go +++ b/packages/server/pkg/model/mflow/node.go @@ -5,7 +5,7 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" ) -type NodeKind = int32 +type NodeKind int32 const ( NODE_KIND_UNSPECIFIED NodeKind = 0 @@ -18,7 +18,11 @@ const ( NODE_KIND_AI NodeKind = 7 NODE_KIND_AI_PROVIDER NodeKind = 8 NODE_KIND_AI_MEMORY NodeKind = 9 - NODE_KIND_GRAPHQL NodeKind = 10 + NODE_KIND_GRAPHQL NodeKind = 10 + NODE_KIND_WS_CONNECTION NodeKind = 11 + NODE_KIND_WS_SEND NodeKind = 12 + NODE_KIND_WAIT NodeKind = 13 + // NODE_KIND_WEBHOOK NodeKind = 14 // reserved for future trigger entry ) type NodeState = int8 diff --git a/packages/server/pkg/model/mflow/node_types.go b/packages/server/pkg/model/mflow/node_types.go index 747306b76..7dfb3f7bc 100644 --- a/packages/server/pkg/model/mflow/node_types.go +++ b/packages/server/pkg/model/mflow/node_types.go @@ -256,7 +256,27 @@ type NodeMemory struct { // --- GraphQL Node --- type NodeGraphQL struct { - FlowNodeID idwrap.IDWrap - GraphQLID *idwrap.IDWrap - DeltaGraphQLID *idwrap.IDWrap + FlowNodeID idwrap.IDWrap + GraphQLID *idwrap.IDWrap + DeltaGraphQLID *idwrap.IDWrap +} + +// --- WebSocket Nodes --- + +type NodeWsConnection struct { + FlowNodeID idwrap.IDWrap + WebSocketID *idwrap.IDWrap +} + +type NodeWsSend struct { + FlowNodeID idwrap.IDWrap + WsConnectionNodeName string + Message string +} + +// --- Wait Node --- + +type NodeWait struct { + FlowNodeID idwrap.IDWrap + DurationMs int64 } diff --git a/packages/server/pkg/model/mwebsocket/mwebsocket.go b/packages/server/pkg/model/mwebsocket/mwebsocket.go new file mode 100644 index 000000000..990f1b622 --- /dev/null +++ b/packages/server/pkg/model/mwebsocket/mwebsocket.go @@ -0,0 +1,29 @@ +package mwebsocket + +import ( + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" +) + +type WebSocket struct { + ID idwrap.IDWrap `json:"id"` + WorkspaceID idwrap.IDWrap `json:"workspace_id"` + FolderID *idwrap.IDWrap `json:"folder_id,omitempty"` + Name string `json:"name"` + Url string `json:"url"` + Description string `json:"description"` + LastRunAt *int64 `json:"last_run_at,omitempty"` + CreatedAt int64 `json:"created_at"` + UpdatedAt int64 `json:"updated_at"` +} + +type WebSocketHeader struct { + ID idwrap.IDWrap `json:"id"` + WebSocketID idwrap.IDWrap `json:"websocket_id"` + Key string `json:"key"` + Value string `json:"value"` + Enabled bool `json:"enabled"` + Description string `json:"description"` + DisplayOrder float32 `json:"order"` + CreatedAt int64 `json:"created_at"` + UpdatedAt int64 `json:"updated_at"` +} diff --git a/packages/server/pkg/mutation/delete_file.go b/packages/server/pkg/mutation/delete_file.go index 7d5c7819b..2ae8b8ca5 100644 --- a/packages/server/pkg/mutation/delete_file.go +++ b/packages/server/pkg/mutation/delete_file.go @@ -59,6 +59,11 @@ func (c *Context) DeleteFile(ctx context.Context, file FileDeleteItem) error { }); err != nil { return err } + case mfile.ContentTypeWebSocket: + // WebSocket - cascade via FK ON DELETE CASCADE in DB + if err := c.q.DeleteWebSocket(ctx, *file.ContentID); err != nil { + return err + } case mfile.ContentTypeFolder: // Content deletion handled by recursion above (folders don't have separate content tables) } diff --git a/packages/server/pkg/mutation/event.go b/packages/server/pkg/mutation/event.go index a89acfe1c..6e69e7377 100644 --- a/packages/server/pkg/mutation/event.go +++ b/packages/server/pkg/mutation/event.go @@ -39,6 +39,9 @@ const ( EntityFlowNodeAiProvider EntityFlowNodeMemory EntityFlowNodeGraphQL + EntityFlowNodeWsConnection + EntityFlowNodeWsSend + EntityFlowNodeWait EntityFlowEdge EntityFlowVariable EntityFlowTag diff --git a/packages/server/pkg/mutation/insert_flow.go b/packages/server/pkg/mutation/insert_flow.go deleted file mode 100644 index 65828ab66..000000000 --- a/packages/server/pkg/mutation/insert_flow.go +++ /dev/null @@ -1,337 +0,0 @@ -package mutation - -import ( - "context" - - "github.com/the-dev-tools/dev-tools/packages/db/pkg/sqlc/gen" - "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" -) - -// FlowNodeInsertItem represents a flow node to insert. -type FlowNodeInsertItem struct { - ID idwrap.IDWrap - FlowID idwrap.IDWrap - WorkspaceID idwrap.IDWrap - Name string - NodeKind int32 - PositionX float64 - PositionY float64 -} - -// InsertFlowNode inserts a flow node and tracks the event. -func (c *Context) InsertFlowNode(ctx context.Context, item FlowNodeInsertItem) error { - err := c.q.CreateFlowNode(ctx, gen.CreateFlowNodeParams{ - ID: item.ID, - FlowID: item.FlowID, - Name: item.Name, - NodeKind: item.NodeKind, - PositionX: item.PositionX, - PositionY: item.PositionY, - }) - if err != nil { - return err - } - c.track(Event{ - Entity: EntityFlowNode, - Op: OpInsert, - ID: item.ID, - WorkspaceID: item.WorkspaceID, - ParentID: item.FlowID, - }) - return nil -} - -// InsertFlowNodeBatch inserts multiple flow nodes. -func (c *Context) InsertFlowNodeBatch(ctx context.Context, items []FlowNodeInsertItem) error { - for _, item := range items { - if err := c.InsertFlowNode(ctx, item); err != nil { - return err - } - } - return nil -} - -// FlowEdgeInsertItem represents a flow edge to insert. -type FlowEdgeInsertItem struct { - ID idwrap.IDWrap - FlowID idwrap.IDWrap - WorkspaceID idwrap.IDWrap - SourceID idwrap.IDWrap - TargetID idwrap.IDWrap - SourceHandle int32 -} - -// InsertFlowEdge inserts a flow edge and tracks the event. -func (c *Context) InsertFlowEdge(ctx context.Context, item FlowEdgeInsertItem) error { - err := c.q.CreateFlowEdge(ctx, gen.CreateFlowEdgeParams{ - ID: item.ID, - FlowID: item.FlowID, - SourceID: item.SourceID, - TargetID: item.TargetID, - SourceHandle: item.SourceHandle, - }) - if err != nil { - return err - } - c.track(Event{ - Entity: EntityFlowEdge, - Op: OpInsert, - ID: item.ID, - WorkspaceID: item.WorkspaceID, - ParentID: item.FlowID, - }) - return nil -} - -// InsertFlowEdgeBatch inserts multiple flow edges. -func (c *Context) InsertFlowEdgeBatch(ctx context.Context, items []FlowEdgeInsertItem) error { - for _, item := range items { - if err := c.InsertFlowEdge(ctx, item); err != nil { - return err - } - } - return nil -} - -// FlowVariableInsertItem represents a flow variable to insert. -type FlowVariableInsertItem struct { - ID idwrap.IDWrap - FlowID idwrap.IDWrap - WorkspaceID idwrap.IDWrap - Key string - Value string - Enabled bool - Description string - DisplayOrder float64 -} - -// InsertFlowVariable inserts a flow variable and tracks the event. -func (c *Context) InsertFlowVariable(ctx context.Context, item FlowVariableInsertItem) error { - err := c.q.CreateFlowVariable(ctx, gen.CreateFlowVariableParams{ - ID: item.ID, - FlowID: item.FlowID, - Key: item.Key, - Value: item.Value, - Enabled: item.Enabled, - Description: item.Description, - DisplayOrder: item.DisplayOrder, - }) - if err != nil { - return err - } - c.track(Event{ - Entity: EntityFlowVariable, - Op: OpInsert, - ID: item.ID, - WorkspaceID: item.WorkspaceID, - ParentID: item.FlowID, - }) - return nil -} - -// InsertFlowVariableBatch inserts multiple flow variables. -func (c *Context) InsertFlowVariableBatch(ctx context.Context, items []FlowVariableInsertItem) error { - for _, item := range items { - if err := c.InsertFlowVariable(ctx, item); err != nil { - return err - } - } - return nil -} - -// FlowNodeJSInsertItem represents a flow node JS to insert. -type FlowNodeJSInsertItem struct { - FlowNodeID idwrap.IDWrap - FlowID idwrap.IDWrap - WorkspaceID idwrap.IDWrap - Code []byte - CodeCompressType int8 -} - -// InsertFlowNodeJS inserts a flow node JS and tracks the event. -func (c *Context) InsertFlowNodeJS(ctx context.Context, item FlowNodeJSInsertItem) error { - err := c.q.CreateFlowNodeJs(ctx, gen.CreateFlowNodeJsParams{ - FlowNodeID: item.FlowNodeID, - Code: item.Code, - CodeCompressType: item.CodeCompressType, - }) - if err != nil { - return err - } - c.track(Event{ - Entity: EntityFlowNodeJS, - Op: OpInsert, - ID: item.FlowNodeID, - WorkspaceID: item.WorkspaceID, - ParentID: item.FlowID, - }) - return nil -} - -// InsertFlowNodeJSBatch inserts multiple flow node JS records. -func (c *Context) InsertFlowNodeJSBatch(ctx context.Context, items []FlowNodeJSInsertItem) error { - for _, item := range items { - if err := c.InsertFlowNodeJS(ctx, item); err != nil { - return err - } - } - return nil -} - -// FlowNodeHTTPInsertItem represents a flow node HTTP to insert. -type FlowNodeHTTPInsertItem struct { - FlowNodeID idwrap.IDWrap - FlowID idwrap.IDWrap - WorkspaceID idwrap.IDWrap - HttpID idwrap.IDWrap - DeltaHttpID []byte -} - -// InsertFlowNodeHTTP inserts a flow node HTTP and tracks the event. -func (c *Context) InsertFlowNodeHTTP(ctx context.Context, item FlowNodeHTTPInsertItem) error { - err := c.q.CreateFlowNodeHTTP(ctx, gen.CreateFlowNodeHTTPParams{ - FlowNodeID: item.FlowNodeID, - HttpID: item.HttpID, - DeltaHttpID: item.DeltaHttpID, - }) - if err != nil { - return err - } - c.track(Event{ - Entity: EntityFlowNodeHTTP, - Op: OpInsert, - ID: item.FlowNodeID, - WorkspaceID: item.WorkspaceID, - ParentID: item.FlowID, - }) - return nil -} - -// InsertFlowNodeHTTPBatch inserts multiple flow node HTTP records. -func (c *Context) InsertFlowNodeHTTPBatch(ctx context.Context, items []FlowNodeHTTPInsertItem) error { - for _, item := range items { - if err := c.InsertFlowNodeHTTP(ctx, item); err != nil { - return err - } - } - return nil -} - -// FlowNodeForInsertItem represents a flow node for-loop to insert. -type FlowNodeForInsertItem struct { - FlowNodeID idwrap.IDWrap - FlowID idwrap.IDWrap - WorkspaceID idwrap.IDWrap - IterCount int64 - ErrorHandling int8 - Expression string -} - -// InsertFlowNodeFor inserts a flow node for-loop and tracks the event. -func (c *Context) InsertFlowNodeFor(ctx context.Context, item FlowNodeForInsertItem) error { - err := c.q.CreateFlowNodeFor(ctx, gen.CreateFlowNodeForParams{ - FlowNodeID: item.FlowNodeID, - IterCount: item.IterCount, - ErrorHandling: item.ErrorHandling, - Expression: item.Expression, - }) - if err != nil { - return err - } - c.track(Event{ - Entity: EntityFlowNodeFor, - Op: OpInsert, - ID: item.FlowNodeID, - WorkspaceID: item.WorkspaceID, - ParentID: item.FlowID, - }) - return nil -} - -// InsertFlowNodeForBatch inserts multiple flow node for-loop records. -func (c *Context) InsertFlowNodeForBatch(ctx context.Context, items []FlowNodeForInsertItem) error { - for _, item := range items { - if err := c.InsertFlowNodeFor(ctx, item); err != nil { - return err - } - } - return nil -} - -// FlowNodeForEachInsertItem represents a flow node for-each to insert. -type FlowNodeForEachInsertItem struct { - FlowNodeID idwrap.IDWrap - FlowID idwrap.IDWrap - WorkspaceID idwrap.IDWrap - IterExpression string - ErrorHandling int8 - Expression string -} - -// InsertFlowNodeForEach inserts a flow node for-each and tracks the event. -func (c *Context) InsertFlowNodeForEach(ctx context.Context, item FlowNodeForEachInsertItem) error { - err := c.q.CreateFlowNodeForEach(ctx, gen.CreateFlowNodeForEachParams{ - FlowNodeID: item.FlowNodeID, - IterExpression: item.IterExpression, - ErrorHandling: item.ErrorHandling, - Expression: item.Expression, - }) - if err != nil { - return err - } - c.track(Event{ - Entity: EntityFlowNodeForEach, - Op: OpInsert, - ID: item.FlowNodeID, - WorkspaceID: item.WorkspaceID, - ParentID: item.FlowID, - }) - return nil -} - -// InsertFlowNodeForEachBatch inserts multiple flow node for-each records. -func (c *Context) InsertFlowNodeForEachBatch(ctx context.Context, items []FlowNodeForEachInsertItem) error { - for _, item := range items { - if err := c.InsertFlowNodeForEach(ctx, item); err != nil { - return err - } - } - return nil -} - -// FlowNodeConditionInsertItem represents a flow node condition to insert. -type FlowNodeConditionInsertItem struct { - FlowNodeID idwrap.IDWrap - FlowID idwrap.IDWrap - WorkspaceID idwrap.IDWrap - Expression string -} - -// InsertFlowNodeCondition inserts a flow node condition and tracks the event. -func (c *Context) InsertFlowNodeCondition(ctx context.Context, item FlowNodeConditionInsertItem) error { - err := c.q.CreateFlowNodeCondition(ctx, gen.CreateFlowNodeConditionParams{ - FlowNodeID: item.FlowNodeID, - Expression: item.Expression, - }) - if err != nil { - return err - } - c.track(Event{ - Entity: EntityFlowNodeCondition, - Op: OpInsert, - ID: item.FlowNodeID, - WorkspaceID: item.WorkspaceID, - ParentID: item.FlowID, - }) - return nil -} - -// InsertFlowNodeConditionBatch inserts multiple flow node condition records. -func (c *Context) InsertFlowNodeConditionBatch(ctx context.Context, items []FlowNodeConditionInsertItem) error { - for _, item := range items { - if err := c.InsertFlowNodeCondition(ctx, item); err != nil { - return err - } - } - return nil -} diff --git a/packages/server/pkg/mutation/update_flow.go b/packages/server/pkg/mutation/update_flow.go deleted file mode 100644 index e028a68b8..000000000 --- a/packages/server/pkg/mutation/update_flow.go +++ /dev/null @@ -1,383 +0,0 @@ -package mutation - -import ( - "context" - - "github.com/the-dev-tools/dev-tools/packages/db/pkg/sqlc/gen" - "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" -) - -// FlowNodeUpdateItem represents a flow node to update. -type FlowNodeUpdateItem struct { - ID idwrap.IDWrap - FlowID idwrap.IDWrap - WorkspaceID idwrap.IDWrap - Name string - PositionX float64 - PositionY float64 -} - -// FlowNodePatch represents optional fields for partial update. -type FlowNodePatch struct { - Name *string - PositionX *float64 - PositionY *float64 -} - -// UpdateFlowNode updates a flow node and tracks the event. -func (c *Context) UpdateFlowNode(ctx context.Context, item FlowNodeUpdateItem) error { - err := c.q.UpdateFlowNode(ctx, gen.UpdateFlowNodeParams{ - ID: item.ID, - Name: item.Name, - PositionX: item.PositionX, - PositionY: item.PositionY, - }) - if err != nil { - return err - } - c.track(Event{ - Entity: EntityFlowNode, - Op: OpUpdate, - ID: item.ID, - WorkspaceID: item.WorkspaceID, - ParentID: item.FlowID, - }) - return nil -} - -// UpdateFlowNodeBatch updates multiple flow nodes. -func (c *Context) UpdateFlowNodeBatch(ctx context.Context, items []FlowNodeUpdateItem) error { - for _, item := range items { - if err := c.UpdateFlowNode(ctx, item); err != nil { - return err - } - } - return nil -} - -// FlowEdgeUpdateItem represents a flow edge to update. -type FlowEdgeUpdateItem struct { - ID idwrap.IDWrap - FlowID idwrap.IDWrap - WorkspaceID idwrap.IDWrap - SourceID idwrap.IDWrap - TargetID idwrap.IDWrap - SourceHandle int32 -} - -// FlowEdgePatch represents optional fields for partial update. -type FlowEdgePatch struct { - SourceID *idwrap.IDWrap - TargetID *idwrap.IDWrap - SourceHandle *int32 -} - -// UpdateFlowEdge updates a flow edge and tracks the event. -func (c *Context) UpdateFlowEdge(ctx context.Context, item FlowEdgeUpdateItem) error { - err := c.q.UpdateFlowEdge(ctx, gen.UpdateFlowEdgeParams{ - ID: item.ID, - SourceID: item.SourceID, - TargetID: item.TargetID, - SourceHandle: item.SourceHandle, - }) - if err != nil { - return err - } - c.track(Event{ - Entity: EntityFlowEdge, - Op: OpUpdate, - ID: item.ID, - WorkspaceID: item.WorkspaceID, - ParentID: item.FlowID, - }) - return nil -} - -// UpdateFlowEdgeBatch updates multiple flow edges. -func (c *Context) UpdateFlowEdgeBatch(ctx context.Context, items []FlowEdgeUpdateItem) error { - for _, item := range items { - if err := c.UpdateFlowEdge(ctx, item); err != nil { - return err - } - } - return nil -} - -// FlowVariableUpdateItem represents a flow variable to update. -type FlowVariableUpdateItem struct { - ID idwrap.IDWrap - FlowID idwrap.IDWrap - WorkspaceID idwrap.IDWrap - Key string - Value string - Enabled bool - Description string -} - -// FlowVariablePatch represents optional fields for partial update. -type FlowVariablePatch struct { - Key *string - Value *string - Enabled *bool - Description *string -} - -// UpdateFlowVariable updates a flow variable and tracks the event. -func (c *Context) UpdateFlowVariable(ctx context.Context, item FlowVariableUpdateItem) error { - err := c.q.UpdateFlowVariable(ctx, gen.UpdateFlowVariableParams{ - ID: item.ID, - Key: item.Key, - Value: item.Value, - Enabled: item.Enabled, - Description: item.Description, - }) - if err != nil { - return err - } - c.track(Event{ - Entity: EntityFlowVariable, - Op: OpUpdate, - ID: item.ID, - WorkspaceID: item.WorkspaceID, - ParentID: item.FlowID, - }) - return nil -} - -// UpdateFlowVariableBatch updates multiple flow variables. -func (c *Context) UpdateFlowVariableBatch(ctx context.Context, items []FlowVariableUpdateItem) error { - for _, item := range items { - if err := c.UpdateFlowVariable(ctx, item); err != nil { - return err - } - } - return nil -} - -// FlowNodeJSUpdateItem represents a flow node JS to update. -type FlowNodeJSUpdateItem struct { - FlowNodeID idwrap.IDWrap - FlowID idwrap.IDWrap - WorkspaceID idwrap.IDWrap - Code []byte - CodeCompressType int8 -} - -// FlowNodeJSPatch represents optional fields for partial update. -type FlowNodeJSPatch struct { - Code []byte - CodeCompressType *int8 -} - -// UpdateFlowNodeJS updates a flow node JS and tracks the event. -func (c *Context) UpdateFlowNodeJS(ctx context.Context, item FlowNodeJSUpdateItem) error { - err := c.q.UpdateFlowNodeJs(ctx, gen.UpdateFlowNodeJsParams{ - FlowNodeID: item.FlowNodeID, - Code: item.Code, - CodeCompressType: item.CodeCompressType, - }) - if err != nil { - return err - } - c.track(Event{ - Entity: EntityFlowNodeJS, - Op: OpUpdate, - ID: item.FlowNodeID, - WorkspaceID: item.WorkspaceID, - ParentID: item.FlowID, - }) - return nil -} - -// UpdateFlowNodeJSBatch updates multiple flow node JS records. -func (c *Context) UpdateFlowNodeJSBatch(ctx context.Context, items []FlowNodeJSUpdateItem) error { - for _, item := range items { - if err := c.UpdateFlowNodeJS(ctx, item); err != nil { - return err - } - } - return nil -} - -// FlowNodeHTTPUpdateItem represents a flow node HTTP to update. -type FlowNodeHTTPUpdateItem struct { - FlowNodeID idwrap.IDWrap - FlowID idwrap.IDWrap - WorkspaceID idwrap.IDWrap - HttpID idwrap.IDWrap - DeltaHttpID []byte -} - -// FlowNodeHTTPPatch represents optional fields for partial update. -type FlowNodeHTTPPatch struct { - HttpID *idwrap.IDWrap - DeltaHttpID []byte -} - -// UpdateFlowNodeHTTP updates a flow node HTTP and tracks the event. -func (c *Context) UpdateFlowNodeHTTP(ctx context.Context, item FlowNodeHTTPUpdateItem) error { - err := c.q.UpdateFlowNodeHTTP(ctx, gen.UpdateFlowNodeHTTPParams{ - FlowNodeID: item.FlowNodeID, - HttpID: item.HttpID, - DeltaHttpID: item.DeltaHttpID, - }) - if err != nil { - return err - } - c.track(Event{ - Entity: EntityFlowNodeHTTP, - Op: OpUpdate, - ID: item.FlowNodeID, - WorkspaceID: item.WorkspaceID, - ParentID: item.FlowID, - }) - return nil -} - -// UpdateFlowNodeHTTPBatch updates multiple flow node HTTP records. -func (c *Context) UpdateFlowNodeHTTPBatch(ctx context.Context, items []FlowNodeHTTPUpdateItem) error { - for _, item := range items { - if err := c.UpdateFlowNodeHTTP(ctx, item); err != nil { - return err - } - } - return nil -} - -// FlowNodeForUpdateItem represents a flow node for-loop to update. -type FlowNodeForUpdateItem struct { - FlowNodeID idwrap.IDWrap - FlowID idwrap.IDWrap - WorkspaceID idwrap.IDWrap - IterCount int64 - ErrorHandling int8 - Expression string -} - -// FlowNodeForPatch represents optional fields for partial update. -type FlowNodeForPatch struct { - IterCount *int64 - ErrorHandling *int8 - Expression *string -} - -// UpdateFlowNodeFor updates a flow node for-loop and tracks the event. -func (c *Context) UpdateFlowNodeFor(ctx context.Context, item FlowNodeForUpdateItem) error { - err := c.q.UpdateFlowNodeFor(ctx, gen.UpdateFlowNodeForParams{ - FlowNodeID: item.FlowNodeID, - IterCount: item.IterCount, - ErrorHandling: item.ErrorHandling, - Expression: item.Expression, - }) - if err != nil { - return err - } - c.track(Event{ - Entity: EntityFlowNodeFor, - Op: OpUpdate, - ID: item.FlowNodeID, - WorkspaceID: item.WorkspaceID, - ParentID: item.FlowID, - }) - return nil -} - -// UpdateFlowNodeForBatch updates multiple flow node for-loop records. -func (c *Context) UpdateFlowNodeForBatch(ctx context.Context, items []FlowNodeForUpdateItem) error { - for _, item := range items { - if err := c.UpdateFlowNodeFor(ctx, item); err != nil { - return err - } - } - return nil -} - -// FlowNodeForEachUpdateItem represents a flow node for-each to update. -type FlowNodeForEachUpdateItem struct { - FlowNodeID idwrap.IDWrap - FlowID idwrap.IDWrap - WorkspaceID idwrap.IDWrap - IterExpression string - ErrorHandling int8 - Expression string -} - -// FlowNodeForEachPatch represents optional fields for partial update. -type FlowNodeForEachPatch struct { - IterExpression *string - ErrorHandling *int8 - Expression *string -} - -// UpdateFlowNodeForEach updates a flow node for-each and tracks the event. -func (c *Context) UpdateFlowNodeForEach(ctx context.Context, item FlowNodeForEachUpdateItem) error { - err := c.q.UpdateFlowNodeForEach(ctx, gen.UpdateFlowNodeForEachParams{ - FlowNodeID: item.FlowNodeID, - IterExpression: item.IterExpression, - ErrorHandling: item.ErrorHandling, - Expression: item.Expression, - }) - if err != nil { - return err - } - c.track(Event{ - Entity: EntityFlowNodeForEach, - Op: OpUpdate, - ID: item.FlowNodeID, - WorkspaceID: item.WorkspaceID, - ParentID: item.FlowID, - }) - return nil -} - -// UpdateFlowNodeForEachBatch updates multiple flow node for-each records. -func (c *Context) UpdateFlowNodeForEachBatch(ctx context.Context, items []FlowNodeForEachUpdateItem) error { - for _, item := range items { - if err := c.UpdateFlowNodeForEach(ctx, item); err != nil { - return err - } - } - return nil -} - -// FlowNodeConditionUpdateItem represents a flow node condition to update. -type FlowNodeConditionUpdateItem struct { - FlowNodeID idwrap.IDWrap - FlowID idwrap.IDWrap - WorkspaceID idwrap.IDWrap - Expression string -} - -// FlowNodeConditionPatch represents optional fields for partial update. -type FlowNodeConditionPatch struct { - Expression *string -} - -// UpdateFlowNodeCondition updates a flow node condition and tracks the event. -func (c *Context) UpdateFlowNodeCondition(ctx context.Context, item FlowNodeConditionUpdateItem) error { - err := c.q.UpdateFlowNodeCondition(ctx, gen.UpdateFlowNodeConditionParams{ - FlowNodeID: item.FlowNodeID, - Expression: item.Expression, - }) - if err != nil { - return err - } - c.track(Event{ - Entity: EntityFlowNodeCondition, - Op: OpUpdate, - ID: item.FlowNodeID, - WorkspaceID: item.WorkspaceID, - ParentID: item.FlowID, - }) - return nil -} - -// UpdateFlowNodeConditionBatch updates multiple flow node condition records. -func (c *Context) UpdateFlowNodeConditionBatch(ctx context.Context, items []FlowNodeConditionUpdateItem) error { - for _, item := range items { - if err := c.UpdateFlowNodeCondition(ctx, item); err != nil { - return err - } - } - return nil -} diff --git a/packages/server/pkg/service/sflow/node_mapper.go b/packages/server/pkg/service/sflow/node_mapper.go index 84c09203f..d792c2124 100644 --- a/packages/server/pkg/service/sflow/node_mapper.go +++ b/packages/server/pkg/service/sflow/node_mapper.go @@ -10,7 +10,7 @@ func ConvertNodeToDB(n mflow.Node) *gen.FlowNode { ID: n.ID, FlowID: n.FlowID, Name: n.Name, - NodeKind: n.NodeKind, + NodeKind: int32(n.NodeKind), PositionX: n.PositionX, PositionY: n.PositionY, State: n.State, @@ -22,7 +22,7 @@ func ConvertNodeToModel(n gen.FlowNode) *mflow.Node { ID: n.ID, FlowID: n.FlowID, Name: n.Name, - NodeKind: n.NodeKind, + NodeKind: mflow.NodeKind(n.NodeKind), PositionX: n.PositionX, PositionY: n.PositionY, State: n.State, diff --git a/packages/server/pkg/service/sflow/node_wait.go b/packages/server/pkg/service/sflow/node_wait.go new file mode 100644 index 000000000..7932e6b9a --- /dev/null +++ b/packages/server/pkg/service/sflow/node_wait.go @@ -0,0 +1,51 @@ +//nolint:revive // exported +package sflow + +import ( + "context" + "database/sql" + + "github.com/the-dev-tools/dev-tools/packages/db/pkg/sqlc/gen" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" +) + +var ErrNoNodeWaitFound = sql.ErrNoRows + +type NodeWaitService struct { + reader *NodeWaitReader + queries *gen.Queries +} + +func NewNodeWaitService(queries *gen.Queries) NodeWaitService { + return NodeWaitService{ + reader: NewNodeWaitReaderFromQueries(queries), + queries: queries, + } +} + +func (s NodeWaitService) TX(tx *sql.Tx) NodeWaitService { + newQueries := s.queries.WithTx(tx) + return NodeWaitService{ + reader: NewNodeWaitReaderFromQueries(newQueries), + queries: newQueries, + } +} + +func (s NodeWaitService) GetNodeWait(ctx context.Context, id idwrap.IDWrap) (*mflow.NodeWait, error) { + return s.reader.GetNodeWait(ctx, id) +} + +func (s NodeWaitService) CreateNodeWait(ctx context.Context, mn mflow.NodeWait) error { + return NewNodeWaitWriterFromQueries(s.queries).CreateNodeWait(ctx, mn) +} + +func (s NodeWaitService) UpdateNodeWait(ctx context.Context, mn mflow.NodeWait) error { + return NewNodeWaitWriterFromQueries(s.queries).UpdateNodeWait(ctx, mn) +} + +func (s NodeWaitService) DeleteNodeWait(ctx context.Context, id idwrap.IDWrap) error { + return NewNodeWaitWriterFromQueries(s.queries).DeleteNodeWait(ctx, id) +} + +func (s NodeWaitService) Reader() *NodeWaitReader { return s.reader } diff --git a/packages/server/pkg/service/sflow/node_wait_mapper.go b/packages/server/pkg/service/sflow/node_wait_mapper.go new file mode 100644 index 000000000..e88201b1e --- /dev/null +++ b/packages/server/pkg/service/sflow/node_wait_mapper.go @@ -0,0 +1,20 @@ +package sflow + +import ( + "github.com/the-dev-tools/dev-tools/packages/db/pkg/sqlc/gen" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" +) + +func ConvertDBToNodeWait(nw gen.FlowNodeWait) *mflow.NodeWait { + return &mflow.NodeWait{ + FlowNodeID: nw.FlowNodeID, + DurationMs: nw.DurationMs, + } +} + +func ConvertNodeWaitToDB(mn mflow.NodeWait) gen.FlowNodeWait { + return gen.FlowNodeWait{ + FlowNodeID: mn.FlowNodeID, + DurationMs: mn.DurationMs, + } +} diff --git a/packages/server/pkg/service/sflow/node_wait_reader.go b/packages/server/pkg/service/sflow/node_wait_reader.go new file mode 100644 index 000000000..b28462fa6 --- /dev/null +++ b/packages/server/pkg/service/sflow/node_wait_reader.go @@ -0,0 +1,34 @@ +package sflow + +import ( + "context" + "database/sql" + "errors" + + "github.com/the-dev-tools/dev-tools/packages/db/pkg/sqlc/gen" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" +) + +type NodeWaitReader struct { + queries *gen.Queries +} + +func NewNodeWaitReader(db *sql.DB) *NodeWaitReader { + return &NodeWaitReader{queries: gen.New(db)} +} + +func NewNodeWaitReaderFromQueries(queries *gen.Queries) *NodeWaitReader { + return &NodeWaitReader{queries: queries} +} + +func (r *NodeWaitReader) GetNodeWait(ctx context.Context, id idwrap.IDWrap) (*mflow.NodeWait, error) { + nodeWait, err := r.queries.GetFlowNodeWait(ctx, id) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, nil + } + return nil, err + } + return ConvertDBToNodeWait(nodeWait), nil +} diff --git a/packages/server/pkg/service/sflow/node_wait_writer.go b/packages/server/pkg/service/sflow/node_wait_writer.go new file mode 100644 index 000000000..304dd9bcc --- /dev/null +++ b/packages/server/pkg/service/sflow/node_wait_writer.go @@ -0,0 +1,38 @@ +package sflow + +import ( + "context" + + "github.com/the-dev-tools/dev-tools/packages/db/pkg/sqlc/gen" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" +) + +type NodeWaitWriter struct { + queries *gen.Queries +} + +func NewNodeWaitWriter(tx gen.DBTX) *NodeWaitWriter { + return &NodeWaitWriter{queries: gen.New(tx)} +} + +func NewNodeWaitWriterFromQueries(queries *gen.Queries) *NodeWaitWriter { + return &NodeWaitWriter{queries: queries} +} + +func (w *NodeWaitWriter) CreateNodeWait(ctx context.Context, mn mflow.NodeWait) error { + nodeWait := ConvertNodeWaitToDB(mn) + return w.queries.CreateFlowNodeWait(ctx, gen.CreateFlowNodeWaitParams(nodeWait)) +} + +func (w *NodeWaitWriter) UpdateNodeWait(ctx context.Context, mn mflow.NodeWait) error { + nodeWait := ConvertNodeWaitToDB(mn) + return w.queries.UpdateFlowNodeWait(ctx, gen.UpdateFlowNodeWaitParams{ + DurationMs: nodeWait.DurationMs, + FlowNodeID: nodeWait.FlowNodeID, + }) +} + +func (w *NodeWaitWriter) DeleteNodeWait(ctx context.Context, id idwrap.IDWrap) error { + return w.queries.DeleteFlowNodeWait(ctx, id) +} diff --git a/packages/server/pkg/service/sflow/node_writer.go b/packages/server/pkg/service/sflow/node_writer.go index e4ab597cf..96adaff4f 100644 --- a/packages/server/pkg/service/sflow/node_writer.go +++ b/packages/server/pkg/service/sflow/node_writer.go @@ -62,61 +62,61 @@ func (w *NodeWriter) CreateNodeBulk(ctx context.Context, nodes []mflow.Node) err ID: batch[0].ID, FlowID: batch[0].FlowID, Name: batch[0].Name, - NodeKind: batch[0].NodeKind, + NodeKind: int32(batch[0].NodeKind), PositionX: batch[0].PositionX, PositionY: batch[0].PositionY, ID_2: batch[1].ID, FlowID_2: batch[1].FlowID, Name_2: batch[1].Name, - NodeKind_2: batch[1].NodeKind, + NodeKind_2: int32(batch[1].NodeKind), PositionX_2: batch[1].PositionX, PositionY_2: batch[1].PositionY, ID_3: batch[2].ID, FlowID_3: batch[2].FlowID, Name_3: batch[2].Name, - NodeKind_3: batch[2].NodeKind, + NodeKind_3: int32(batch[2].NodeKind), PositionX_3: batch[2].PositionX, PositionY_3: batch[2].PositionY, ID_4: batch[3].ID, FlowID_4: batch[3].FlowID, Name_4: batch[3].Name, - NodeKind_4: batch[3].NodeKind, + NodeKind_4: int32(batch[3].NodeKind), PositionX_4: batch[3].PositionX, PositionY_4: batch[3].PositionY, ID_5: batch[4].ID, FlowID_5: batch[4].FlowID, Name_5: batch[4].Name, - NodeKind_5: batch[4].NodeKind, + NodeKind_5: int32(batch[4].NodeKind), PositionX_5: batch[4].PositionX, PositionY_5: batch[4].PositionY, ID_6: batch[5].ID, FlowID_6: batch[5].FlowID, Name_6: batch[5].Name, - NodeKind_6: batch[5].NodeKind, + NodeKind_6: int32(batch[5].NodeKind), PositionX_6: batch[5].PositionX, PositionY_6: batch[5].PositionY, ID_7: batch[6].ID, FlowID_7: batch[6].FlowID, Name_7: batch[6].Name, - NodeKind_7: batch[6].NodeKind, + NodeKind_7: int32(batch[6].NodeKind), PositionX_7: batch[6].PositionX, PositionY_7: batch[6].PositionY, ID_8: batch[7].ID, FlowID_8: batch[7].FlowID, Name_8: batch[7].Name, - NodeKind_8: batch[7].NodeKind, + NodeKind_8: int32(batch[7].NodeKind), PositionX_8: batch[7].PositionX, PositionY_8: batch[7].PositionY, ID_9: batch[8].ID, FlowID_9: batch[8].FlowID, Name_9: batch[8].Name, - NodeKind_9: batch[8].NodeKind, + NodeKind_9: int32(batch[8].NodeKind), PositionX_9: batch[8].PositionX, PositionY_9: batch[8].PositionY, ID_10: batch[9].ID, FlowID_10: batch[9].FlowID, Name_10: batch[9].Name, - NodeKind_10: batch[9].NodeKind, + NodeKind_10: int32(batch[9].NodeKind), PositionX_10: batch[9].PositionX, PositionY_10: batch[9].PositionY, } diff --git a/packages/server/pkg/service/sflow/node_ws_connection.go b/packages/server/pkg/service/sflow/node_ws_connection.go new file mode 100644 index 000000000..63caeae3f --- /dev/null +++ b/packages/server/pkg/service/sflow/node_ws_connection.go @@ -0,0 +1,49 @@ +//nolint:revive // exported +package sflow + +import ( + "context" + "database/sql" + + "github.com/the-dev-tools/dev-tools/packages/db/pkg/sqlc/gen" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" +) + +type NodeWsConnectionService struct { + reader *NodeWsConnectionReader + queries *gen.Queries +} + +func NewNodeWsConnectionService(queries *gen.Queries) NodeWsConnectionService { + return NodeWsConnectionService{ + reader: NewNodeWsConnectionReaderFromQueries(queries), + queries: queries, + } +} + +func (s NodeWsConnectionService) TX(tx *sql.Tx) NodeWsConnectionService { + newQueries := s.queries.WithTx(tx) + return NodeWsConnectionService{ + reader: NewNodeWsConnectionReaderFromQueries(newQueries), + queries: newQueries, + } +} + +func (s NodeWsConnectionService) GetNodeWsConnection(ctx context.Context, id idwrap.IDWrap) (*mflow.NodeWsConnection, error) { + return s.reader.GetNodeWsConnection(ctx, id) +} + +func (s NodeWsConnectionService) CreateNodeWsConnection(ctx context.Context, n mflow.NodeWsConnection) error { + return NewNodeWsConnectionWriterFromQueries(s.queries).CreateNodeWsConnection(ctx, n) +} + +func (s NodeWsConnectionService) UpdateNodeWsConnection(ctx context.Context, n mflow.NodeWsConnection) error { + return NewNodeWsConnectionWriterFromQueries(s.queries).UpdateNodeWsConnection(ctx, n) +} + +func (s NodeWsConnectionService) DeleteNodeWsConnection(ctx context.Context, id idwrap.IDWrap) error { + return NewNodeWsConnectionWriterFromQueries(s.queries).DeleteNodeWsConnection(ctx, id) +} + +func (s NodeWsConnectionService) Reader() *NodeWsConnectionReader { return s.reader } diff --git a/packages/server/pkg/service/sflow/node_ws_connection_mapper.go b/packages/server/pkg/service/sflow/node_ws_connection_mapper.go new file mode 100644 index 000000000..c3104731d --- /dev/null +++ b/packages/server/pkg/service/sflow/node_ws_connection_mapper.go @@ -0,0 +1,24 @@ +package sflow + +import ( + "github.com/the-dev-tools/dev-tools/packages/db/pkg/sqlc/gen" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" +) + +func ConvertToDBNodeWsConnection(n mflow.NodeWsConnection) (gen.FlowNodeWsConnection, bool) { + if n.WebSocketID == nil || isZeroID(*n.WebSocketID) { + return gen.FlowNodeWsConnection{}, false + } + + return gen.FlowNodeWsConnection{ + FlowNodeID: n.FlowNodeID, + WebsocketID: n.WebSocketID, + }, true +} + +func ConvertToModelNodeWsConnection(n gen.FlowNodeWsConnection) *mflow.NodeWsConnection { + return &mflow.NodeWsConnection{ + FlowNodeID: n.FlowNodeID, + WebSocketID: n.WebsocketID, + } +} diff --git a/packages/server/pkg/service/sflow/node_ws_connection_reader.go b/packages/server/pkg/service/sflow/node_ws_connection_reader.go new file mode 100644 index 000000000..374b71881 --- /dev/null +++ b/packages/server/pkg/service/sflow/node_ws_connection_reader.go @@ -0,0 +1,30 @@ +package sflow + +import ( + "context" + "database/sql" + "errors" + + "github.com/the-dev-tools/dev-tools/packages/db/pkg/sqlc/gen" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" +) + +type NodeWsConnectionReader struct { + queries *gen.Queries +} + +func NewNodeWsConnectionReaderFromQueries(queries *gen.Queries) *NodeWsConnectionReader { + return &NodeWsConnectionReader{queries: queries} +} + +func (r *NodeWsConnectionReader) GetNodeWsConnection(ctx context.Context, id idwrap.IDWrap) (*mflow.NodeWsConnection, error) { + nodeWsConn, err := r.queries.GetFlowNodeWsConnection(ctx, id) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, nil + } + return nil, err + } + return ConvertToModelNodeWsConnection(nodeWsConn), nil +} diff --git a/packages/server/pkg/service/sflow/node_ws_connection_writer.go b/packages/server/pkg/service/sflow/node_ws_connection_writer.go new file mode 100644 index 000000000..fb8b629e4 --- /dev/null +++ b/packages/server/pkg/service/sflow/node_ws_connection_writer.go @@ -0,0 +1,46 @@ +package sflow + +import ( + "context" + "database/sql" + "errors" + + "github.com/the-dev-tools/dev-tools/packages/db/pkg/sqlc/gen" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" +) + +type NodeWsConnectionWriter struct { + queries *gen.Queries +} + +func NewNodeWsConnectionWriter(tx gen.DBTX) *NodeWsConnectionWriter { + return &NodeWsConnectionWriter{queries: gen.New(tx)} +} + +func NewNodeWsConnectionWriterFromQueries(queries *gen.Queries) *NodeWsConnectionWriter { + return &NodeWsConnectionWriter{queries: queries} +} + +func (w *NodeWsConnectionWriter) CreateNodeWsConnection(ctx context.Context, n mflow.NodeWsConnection) error { + dbModel, ok := ConvertToDBNodeWsConnection(n) + if !ok { + return nil + } + return w.queries.CreateFlowNodeWsConnection(ctx, gen.CreateFlowNodeWsConnectionParams(dbModel)) +} + +func (w *NodeWsConnectionWriter) UpdateNodeWsConnection(ctx context.Context, n mflow.NodeWsConnection) error { + dbModel, ok := ConvertToDBNodeWsConnection(n) + if !ok { + if err := w.queries.DeleteFlowNodeWsConnection(ctx, n.FlowNodeID); err != nil && !errors.Is(err, sql.ErrNoRows) { + return err + } + return nil + } + return w.queries.UpdateFlowNodeWsConnection(ctx, gen.UpdateFlowNodeWsConnectionParams(dbModel)) +} + +func (w *NodeWsConnectionWriter) DeleteNodeWsConnection(ctx context.Context, id idwrap.IDWrap) error { + return w.queries.DeleteFlowNodeWsConnection(ctx, id) +} diff --git a/packages/server/pkg/service/sflow/node_ws_send.go b/packages/server/pkg/service/sflow/node_ws_send.go new file mode 100644 index 000000000..f68c318c5 --- /dev/null +++ b/packages/server/pkg/service/sflow/node_ws_send.go @@ -0,0 +1,49 @@ +//nolint:revive // exported +package sflow + +import ( + "context" + "database/sql" + + "github.com/the-dev-tools/dev-tools/packages/db/pkg/sqlc/gen" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" +) + +type NodeWsSendService struct { + reader *NodeWsSendReader + queries *gen.Queries +} + +func NewNodeWsSendService(queries *gen.Queries) NodeWsSendService { + return NodeWsSendService{ + reader: NewNodeWsSendReaderFromQueries(queries), + queries: queries, + } +} + +func (s NodeWsSendService) TX(tx *sql.Tx) NodeWsSendService { + newQueries := s.queries.WithTx(tx) + return NodeWsSendService{ + reader: NewNodeWsSendReaderFromQueries(newQueries), + queries: newQueries, + } +} + +func (s NodeWsSendService) GetNodeWsSend(ctx context.Context, id idwrap.IDWrap) (*mflow.NodeWsSend, error) { + return s.reader.GetNodeWsSend(ctx, id) +} + +func (s NodeWsSendService) CreateNodeWsSend(ctx context.Context, n mflow.NodeWsSend) error { + return NewNodeWsSendWriterFromQueries(s.queries).CreateNodeWsSend(ctx, n) +} + +func (s NodeWsSendService) UpdateNodeWsSend(ctx context.Context, n mflow.NodeWsSend) error { + return NewNodeWsSendWriterFromQueries(s.queries).UpdateNodeWsSend(ctx, n) +} + +func (s NodeWsSendService) DeleteNodeWsSend(ctx context.Context, id idwrap.IDWrap) error { + return NewNodeWsSendWriterFromQueries(s.queries).DeleteNodeWsSend(ctx, id) +} + +func (s NodeWsSendService) Reader() *NodeWsSendReader { return s.reader } diff --git a/packages/server/pkg/service/sflow/node_ws_send_mapper.go b/packages/server/pkg/service/sflow/node_ws_send_mapper.go new file mode 100644 index 000000000..2be4a8f75 --- /dev/null +++ b/packages/server/pkg/service/sflow/node_ws_send_mapper.go @@ -0,0 +1,22 @@ +package sflow + +import ( + "github.com/the-dev-tools/dev-tools/packages/db/pkg/sqlc/gen" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" +) + +func ConvertToDBNodeWsSend(n mflow.NodeWsSend) gen.FlowNodeWsSend { + return gen.FlowNodeWsSend{ + FlowNodeID: n.FlowNodeID, + WsConnectionNodeName: n.WsConnectionNodeName, + Message: n.Message, + } +} + +func ConvertToModelNodeWsSend(n gen.FlowNodeWsSend) *mflow.NodeWsSend { + return &mflow.NodeWsSend{ + FlowNodeID: n.FlowNodeID, + WsConnectionNodeName: n.WsConnectionNodeName, + Message: n.Message, + } +} diff --git a/packages/server/pkg/service/sflow/node_ws_send_reader.go b/packages/server/pkg/service/sflow/node_ws_send_reader.go new file mode 100644 index 000000000..d519855b7 --- /dev/null +++ b/packages/server/pkg/service/sflow/node_ws_send_reader.go @@ -0,0 +1,30 @@ +package sflow + +import ( + "context" + "database/sql" + "errors" + + "github.com/the-dev-tools/dev-tools/packages/db/pkg/sqlc/gen" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" +) + +type NodeWsSendReader struct { + queries *gen.Queries +} + +func NewNodeWsSendReaderFromQueries(queries *gen.Queries) *NodeWsSendReader { + return &NodeWsSendReader{queries: queries} +} + +func (r *NodeWsSendReader) GetNodeWsSend(ctx context.Context, id idwrap.IDWrap) (*mflow.NodeWsSend, error) { + nodeWsSend, err := r.queries.GetFlowNodeWsSend(ctx, id) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, nil + } + return nil, err + } + return ConvertToModelNodeWsSend(nodeWsSend), nil +} diff --git a/packages/server/pkg/service/sflow/node_ws_send_writer.go b/packages/server/pkg/service/sflow/node_ws_send_writer.go new file mode 100644 index 000000000..a52319344 --- /dev/null +++ b/packages/server/pkg/service/sflow/node_ws_send_writer.go @@ -0,0 +1,35 @@ +package sflow + +import ( + "context" + + "github.com/the-dev-tools/dev-tools/packages/db/pkg/sqlc/gen" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" +) + +type NodeWsSendWriter struct { + queries *gen.Queries +} + +func NewNodeWsSendWriter(tx gen.DBTX) *NodeWsSendWriter { + return &NodeWsSendWriter{queries: gen.New(tx)} +} + +func NewNodeWsSendWriterFromQueries(queries *gen.Queries) *NodeWsSendWriter { + return &NodeWsSendWriter{queries: queries} +} + +func (w *NodeWsSendWriter) CreateNodeWsSend(ctx context.Context, n mflow.NodeWsSend) error { + dbModel := ConvertToDBNodeWsSend(n) + return w.queries.CreateFlowNodeWsSend(ctx, gen.CreateFlowNodeWsSendParams(dbModel)) +} + +func (w *NodeWsSendWriter) UpdateNodeWsSend(ctx context.Context, n mflow.NodeWsSend) error { + dbModel := ConvertToDBNodeWsSend(n) + return w.queries.UpdateFlowNodeWsSend(ctx, gen.UpdateFlowNodeWsSendParams(dbModel)) +} + +func (w *NodeWsSendWriter) DeleteNodeWsSend(ctx context.Context, id idwrap.IDWrap) error { + return w.queries.DeleteFlowNodeWsSend(ctx, id) +} diff --git a/packages/server/pkg/service/sgraphql/header.go b/packages/server/pkg/service/sgraphql/header.go index 04798fc78..08bbe988f 100644 --- a/packages/server/pkg/service/sgraphql/header.go +++ b/packages/server/pkg/service/sgraphql/header.go @@ -25,6 +25,17 @@ func (s GraphQLHeaderService) TX(tx *sql.Tx) GraphQLHeaderService { return GraphQLHeaderService{queries: s.queries.WithTx(tx)} } +func (s GraphQLHeaderService) GetByID(ctx context.Context, id idwrap.IDWrap) (*mgraphql.GraphQLHeader, error) { + headers, err := s.GetByIDs(ctx, []idwrap.IDWrap{id}) + if err != nil { + return nil, err + } + if len(headers) == 0 { + return nil, ErrNoGraphQLHeaderFound + } + return &headers[0], nil +} + func (s GraphQLHeaderService) GetByGraphQLID(ctx context.Context, graphqlID idwrap.IDWrap) ([]mgraphql.GraphQLHeader, error) { headers, err := s.queries.GetGraphQLHeaders(ctx, graphqlID) if err != nil { diff --git a/packages/server/pkg/service/swebsocket/header.go b/packages/server/pkg/service/swebsocket/header.go new file mode 100644 index 000000000..3904db10e --- /dev/null +++ b/packages/server/pkg/service/swebsocket/header.go @@ -0,0 +1,75 @@ +package swebsocket + +import ( + "context" + "database/sql" + + "github.com/the-dev-tools/dev-tools/packages/db/pkg/sqlc/gen" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mwebsocket" +) + +type WebSocketHeaderService struct { + queries *gen.Queries +} + +func NewWebSocketHeaderService(queries *gen.Queries) WebSocketHeaderService { + return WebSocketHeaderService{queries: queries} +} + +func (s WebSocketHeaderService) TX(tx *sql.Tx) WebSocketHeaderService { + return WebSocketHeaderService{queries: s.queries.WithTx(tx)} +} + +func (s WebSocketHeaderService) GetByID(ctx context.Context, id idwrap.IDWrap) (mwebsocket.WebSocketHeader, error) { + h, err := s.queries.GetWebSocketHeaderByID(ctx, id) + if err != nil { + return mwebsocket.WebSocketHeader{}, err + } + return convertToModelHeader(h), nil +} + +func (s WebSocketHeaderService) GetByWebSocketID(ctx context.Context, wsID idwrap.IDWrap) ([]mwebsocket.WebSocketHeader, error) { + headers, err := s.queries.GetWebSocketHeaders(ctx, wsID) + if err != nil { + return nil, err + } + result := make([]mwebsocket.WebSocketHeader, len(headers)) + for i, h := range headers { + result[i] = convertToModelHeader(h) + } + return result, nil +} + +func (s WebSocketHeaderService) Create(ctx context.Context, h mwebsocket.WebSocketHeader) error { + return s.queries.CreateWebSocketHeader(ctx, gen.CreateWebSocketHeaderParams{ + ID: h.ID, + WebsocketID: h.WebSocketID, + HeaderKey: h.Key, + HeaderValue: h.Value, + Description: h.Description, + Enabled: h.Enabled, + DisplayOrder: float64(h.DisplayOrder), + CreatedAt: h.CreatedAt, + UpdatedAt: h.UpdatedAt, + }) +} + +func (s WebSocketHeaderService) Update(ctx context.Context, h mwebsocket.WebSocketHeader) error { + return s.queries.UpdateWebSocketHeader(ctx, gen.UpdateWebSocketHeaderParams{ + ID: h.ID, + HeaderKey: h.Key, + HeaderValue: h.Value, + Description: h.Description, + Enabled: h.Enabled, + DisplayOrder: float64(h.DisplayOrder), + }) +} + +func (s WebSocketHeaderService) Delete(ctx context.Context, id idwrap.IDWrap) error { + return s.queries.DeleteWebSocketHeader(ctx, id) +} + +func (s WebSocketHeaderService) DeleteByWebSocketID(ctx context.Context, wsID idwrap.IDWrap) error { + return s.queries.DeleteWebSocketHeadersByWebSocketID(ctx, wsID) +} diff --git a/packages/server/pkg/service/swebsocket/mapper.go b/packages/server/pkg/service/swebsocket/mapper.go new file mode 100644 index 000000000..ccf76f415 --- /dev/null +++ b/packages/server/pkg/service/swebsocket/mapper.go @@ -0,0 +1,58 @@ +package swebsocket + +import ( + "github.com/the-dev-tools/dev-tools/packages/db/pkg/sqlc/gen" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mwebsocket" +) + +func convertToModelWebSocket(db gen.Websocket) *mwebsocket.WebSocket { + ws := &mwebsocket.WebSocket{ + ID: db.ID, + WorkspaceID: db.WorkspaceID, + FolderID: db.FolderID, + Name: db.Name, + Url: db.Url, + Description: db.Description, + CreatedAt: db.CreatedAt, + UpdatedAt: db.UpdatedAt, + } + + if db.LastRunAt != nil { + if v, ok := db.LastRunAt.(int64); ok { + ws.LastRunAt = &v + } + } + + return ws +} + +func convertToDBCreateWebSocket(ws mwebsocket.WebSocket) gen.CreateWebSocketParams { + p := gen.CreateWebSocketParams{ + ID: ws.ID, + WorkspaceID: ws.WorkspaceID, + FolderID: ws.FolderID, + Name: ws.Name, + Url: ws.Url, + Description: ws.Description, + CreatedAt: ws.CreatedAt, + UpdatedAt: ws.UpdatedAt, + } + if ws.LastRunAt != nil { + p.LastRunAt = *ws.LastRunAt + } + return p +} + +func convertToModelHeader(db gen.WebsocketHeader) mwebsocket.WebSocketHeader { + return mwebsocket.WebSocketHeader{ + ID: db.ID, + WebSocketID: db.WebsocketID, + Key: db.HeaderKey, + Value: db.HeaderValue, + Enabled: db.Enabled, + Description: db.Description, + DisplayOrder: float32(db.DisplayOrder), + CreatedAt: db.CreatedAt, + UpdatedAt: db.UpdatedAt, + } +} diff --git a/packages/server/pkg/service/swebsocket/swebsocket.go b/packages/server/pkg/service/swebsocket/swebsocket.go new file mode 100644 index 000000000..a87d9d23a --- /dev/null +++ b/packages/server/pkg/service/swebsocket/swebsocket.go @@ -0,0 +1,72 @@ +package swebsocket + +import ( + "context" + "database/sql" + "log/slog" + + "github.com/the-dev-tools/dev-tools/packages/db/pkg/sqlc/gen" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mwebsocket" +) + +var ErrNoWebSocketFound = sql.ErrNoRows + +type WebSocketService struct { + queries *gen.Queries + logger *slog.Logger +} + +func New(queries *gen.Queries, logger *slog.Logger) WebSocketService { + return WebSocketService{queries: queries, logger: logger} +} + +func (s WebSocketService) TX(tx *sql.Tx) WebSocketService { + return WebSocketService{queries: s.queries.WithTx(tx), logger: s.logger} +} + +func (s WebSocketService) Get(ctx context.Context, id idwrap.IDWrap) (*mwebsocket.WebSocket, error) { + ws, err := s.queries.GetWebSocket(ctx, id) + if err != nil { + return nil, err + } + return convertToModelWebSocket(ws), nil +} + +func (s WebSocketService) GetByWorkspaceID(ctx context.Context, workspaceID idwrap.IDWrap) ([]mwebsocket.WebSocket, error) { + wsList, err := s.queries.GetWebSocketsByWorkspaceID(ctx, workspaceID) + if err != nil { + return nil, err + } + result := make([]mwebsocket.WebSocket, len(wsList)) + for i, ws := range wsList { + result[i] = *convertToModelWebSocket(ws) + } + return result, nil +} + +func (s WebSocketService) GetWorkspaceID(ctx context.Context, id idwrap.IDWrap) (idwrap.IDWrap, error) { + return s.queries.GetWebSocketWorkspaceID(ctx, id) +} + +func (s WebSocketService) Create(ctx context.Context, ws *mwebsocket.WebSocket) error { + return s.queries.CreateWebSocket(ctx, convertToDBCreateWebSocket(*ws)) +} + +func (s WebSocketService) Update(ctx context.Context, ws *mwebsocket.WebSocket) error { + var lastRunAt interface{} + if ws.LastRunAt != nil { + lastRunAt = *ws.LastRunAt + } + return s.queries.UpdateWebSocket(ctx, gen.UpdateWebSocketParams{ + ID: ws.ID, + Name: ws.Name, + Url: ws.Url, + Description: ws.Description, + LastRunAt: lastRunAt, + }) +} + +func (s WebSocketService) Delete(ctx context.Context, id idwrap.IDWrap) error { + return s.queries.DeleteWebSocket(ctx, id) +} diff --git a/packages/server/pkg/translate/yamlflowsimplev2/converter_flow.go b/packages/server/pkg/translate/yamlflowsimplev2/converter_flow.go index a50d19e3a..8781465eb 100644 --- a/packages/server/pkg/translate/yamlflowsimplev2/converter_flow.go +++ b/packages/server/pkg/translate/yamlflowsimplev2/converter_flow.go @@ -275,6 +275,11 @@ func mergeFlowData(result *ioworkspace.WorkspaceBundle, flowData *ioworkspace.Wo result.GraphQLHeaders = append(result.GraphQLHeaders, flowData.GraphQLHeaders...) result.GraphQLAsserts = append(result.GraphQLAsserts, flowData.GraphQLAsserts...) result.FlowGraphQLNodes = append(result.FlowGraphQLNodes, flowData.FlowGraphQLNodes...) + result.FlowWsConnectionNodes = append(result.FlowWsConnectionNodes, flowData.FlowWsConnectionNodes...) + result.FlowWsSendNodes = append(result.FlowWsSendNodes, flowData.FlowWsSendNodes...) + result.FlowWaitNodes = append(result.FlowWaitNodes, flowData.FlowWaitNodes...) + result.WebSockets = append(result.WebSockets, flowData.WebSockets...) + result.WebSocketHeaders = append(result.WebSocketHeaders, flowData.WebSocketHeaders...) } func mergeAssociatedData(result *ioworkspace.WorkspaceBundle, assoc *HTTPAssociatedData) { diff --git a/packages/server/pkg/translate/yamlflowsimplev2/converter_node.go b/packages/server/pkg/translate/yamlflowsimplev2/converter_node.go index 2089851d9..0c5195427 100644 --- a/packages/server/pkg/translate/yamlflowsimplev2/converter_node.go +++ b/packages/server/pkg/translate/yamlflowsimplev2/converter_node.go @@ -13,6 +13,7 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mgraphql" "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mhttp" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mwebsocket" "github.com/the-dev-tools/dev-tools/packages/server/pkg/varsystem" ) @@ -37,6 +38,12 @@ func getStepCommon(sw YamlStepWrapper) *YamlStepCommon { return &sw.AIMemory.YamlStepCommon case sw.GraphQL != nil: return &sw.GraphQL.YamlStepCommon + case sw.WsConnection != nil: + return &sw.WsConnection.YamlStepCommon + case sw.WsSend != nil: + return &sw.WsSend.YamlStepCommon + case sw.Wait != nil: + return &sw.Wait.YamlStepCommon case sw.ManualStart != nil: return sw.ManualStart default: @@ -96,6 +103,15 @@ func processSteps(flowEntry YamlFlowFlowV2, templates map[string]YamlRequestDefV case stepWrapper.AIMemory != nil: nodeName = stepWrapper.AIMemory.Name dependsOn = stepWrapper.AIMemory.DependsOn + case stepWrapper.WsConnection != nil: + nodeName = stepWrapper.WsConnection.Name + dependsOn = stepWrapper.WsConnection.DependsOn + case stepWrapper.WsSend != nil: + nodeName = stepWrapper.WsSend.Name + dependsOn = stepWrapper.WsSend.DependsOn + case stepWrapper.Wait != nil: + nodeName = stepWrapper.Wait.Name + dependsOn = stepWrapper.Wait.DependsOn case stepWrapper.ManualStart != nil: nodeName = stepWrapper.ManualStart.Name dependsOn = stepWrapper.ManualStart.DependsOn @@ -181,6 +197,18 @@ func processSteps(flowEntry YamlFlowFlowV2, templates map[string]YamlRequestDefV if err := processAIMemoryStructStep(stepWrapper.AIMemory, nodeID, flowID, result); err != nil { return nil, err } + case stepWrapper.WsConnection != nil: + if err := processWsConnectionStructStep(stepWrapper.WsConnection, nodeID, flowID, opts, result); err != nil { + return nil, err + } + case stepWrapper.WsSend != nil: + if err := processWsSendStructStep(stepWrapper.WsSend, nodeID, flowID, result); err != nil { + return nil, err + } + case stepWrapper.Wait != nil: + if err := processWaitStructStep(stepWrapper.Wait, nodeID, flowID, result); err != nil { + return nil, err + } case stepWrapper.ManualStart != nil: info.id = startNodeID createStartNodeWithID(startNodeID, flowID, result) @@ -603,3 +631,96 @@ func processGraphQLStructStep(step *YamlStepGraphQL, nodeID, flowID idwrap.IDWra return nil } + +func processWsConnectionStructStep(step *YamlStepWsConnection, nodeID, flowID idwrap.IDWrap, opts ConvertOptionsV2, result *ioworkspace.WorkspaceBundle) error { + if step.URL == "" { + return NewYamlFlowErrorV2(fmt.Sprintf("ws_connection step '%s' missing required url", step.Name), "url", nil) + } + + flowNode := mflow.Node{ + ID: nodeID, + FlowID: flowID, + Name: step.Name, + NodeKind: mflow.NODE_KIND_WS_CONNECTION, + } + result.FlowNodes = append(result.FlowNodes, flowNode) + + // Create WebSocket entity (like GraphQL pattern) + wsID := idwrap.NewNow() + now := time.Now().UnixMilli() + ws := mwebsocket.WebSocket{ + ID: wsID, + WorkspaceID: opts.WorkspaceID, + Name: step.Name, + Url: step.URL, + CreatedAt: now, + UpdatedAt: now, + } + result.WebSockets = append(result.WebSockets, ws) + + // Create headers + for i, h := range step.Headers { + header := mwebsocket.WebSocketHeader{ + ID: idwrap.NewNow(), + WebSocketID: wsID, + Key: h.Name, + Value: h.Value, + Enabled: h.Enabled, + DisplayOrder: float32(i), + CreatedAt: now, + UpdatedAt: now, + } + result.WebSocketHeaders = append(result.WebSocketHeaders, header) + } + + wsConnNode := mflow.NodeWsConnection{ + FlowNodeID: nodeID, + WebSocketID: &wsID, + } + result.FlowWsConnectionNodes = append(result.FlowWsConnectionNodes, wsConnNode) + return nil +} + +func processWsSendStructStep(step *YamlStepWsSend, nodeID, flowID idwrap.IDWrap, result *ioworkspace.WorkspaceBundle) error { + flowNode := mflow.Node{ + ID: nodeID, + FlowID: flowID, + Name: step.Name, + NodeKind: mflow.NODE_KIND_WS_SEND, + } + result.FlowNodes = append(result.FlowNodes, flowNode) + + wsSendNode := mflow.NodeWsSend{ + FlowNodeID: nodeID, + WsConnectionNodeName: step.WsConnectionNodeName, + Message: step.Message, + } + result.FlowWsSendNodes = append(result.FlowWsSendNodes, wsSendNode) + return nil +} + +func processWaitStructStep(step *YamlStepWait, nodeID, flowID idwrap.IDWrap, result *ioworkspace.WorkspaceBundle) error { + flowNode := mflow.Node{ + ID: nodeID, + FlowID: flowID, + Name: step.Name, + NodeKind: mflow.NODE_KIND_WAIT, + } + result.FlowNodes = append(result.FlowNodes, flowNode) + + var durationMs int64 + if step.DurationMs != "" { + d, err := strconv.ParseInt(step.DurationMs, 10, 64) + if err != nil { + return NewYamlFlowErrorV2(fmt.Sprintf("invalid duration_ms value '%s': %v", step.DurationMs, err), "duration_ms", step.DurationMs) + } + durationMs = d + } + + waitNode := mflow.NodeWait{ + FlowNodeID: nodeID, + DurationMs: durationMs, + } + result.FlowWaitNodes = append(result.FlowWaitNodes, waitNode) + return nil +} diff --git a/packages/server/pkg/translate/yamlflowsimplev2/exporter.go b/packages/server/pkg/translate/yamlflowsimplev2/exporter.go index 6ea9184ed..1e2c08609 100644 --- a/packages/server/pkg/translate/yamlflowsimplev2/exporter.go +++ b/packages/server/pkg/translate/yamlflowsimplev2/exporter.go @@ -5,6 +5,7 @@ import ( "fmt" "math" "sort" + "strconv" "github.com/the-dev-tools/dev-tools/packages/server/pkg/flowgraph" "github.com/the-dev-tools/dev-tools/packages/server/pkg/idwrap" @@ -13,6 +14,7 @@ import ( "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mflow" "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mgraphql" "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mhttp" + "github.com/the-dev-tools/dev-tools/packages/server/pkg/model/mwebsocket" "gopkg.in/yaml.v3" ) @@ -123,6 +125,31 @@ func MarshalSimplifiedYAML(data *ioworkspace.WorkspaceBundle) ([]byte, error) { graphqlNodeMap[n.FlowNodeID] = n } + wsConnectionNodeMap := make(map[idwrap.IDWrap]mflow.NodeWsConnection) + for _, n := range data.FlowWsConnectionNodes { + wsConnectionNodeMap[n.FlowNodeID] = n + } + + wsSendNodeMap := make(map[idwrap.IDWrap]mflow.NodeWsSend) + for _, n := range data.FlowWsSendNodes { + wsSendNodeMap[n.FlowNodeID] = n + } + + waitNodeMap := make(map[idwrap.IDWrap]mflow.NodeWait) + for _, n := range data.FlowWaitNodes { + waitNodeMap[n.FlowNodeID] = n + } + + wsEntityMap := make(map[idwrap.IDWrap]mwebsocket.WebSocket) + for _, ws := range data.WebSockets { + wsEntityMap[ws.ID] = ws + } + + wsHeaderMap := make(map[idwrap.IDWrap][]mwebsocket.WebSocketHeader) + for _, h := range data.WebSocketHeaders { + wsHeaderMap[h.WebSocketID] = append(wsHeaderMap[h.WebSocketID], h) + } + graphqlMap := make(map[idwrap.IDWrap]mgraphql.GraphQL) for _, g := range data.GraphQLRequests { graphqlMap[g.ID] = g @@ -372,6 +399,8 @@ func MarshalSimplifiedYAML(data *ioworkspace.WorkspaceBundle) ([]byte, error) { depStr += DependsSuffixElse case mflow.HandleLoop: depStr += DependsSuffixLoop + case mflow.HandleWsMessage: + depStr += DependsSuffixWsMessage case mflow.HandleUnspecified: // Do nothing, just the name default: @@ -562,6 +591,54 @@ func MarshalSimplifiedYAML(data *ioworkspace.WorkspaceBundle) ([]byte, error) { } stepWrapper.GraphQL = gqlStep + case mflow.NODE_KIND_WS_CONNECTION: + wsConnNode, ok := wsConnectionNodeMap[node.ID] + if !ok { + continue + } + wsStep := &YamlStepWsConnection{ + YamlStepCommon: common, + } + if wsConnNode.WebSocketID != nil { + if wsEntity, ok := wsEntityMap[*wsConnNode.WebSocketID]; ok { + wsStep.URL = wsEntity.Url + } + if headers, ok := wsHeaderMap[*wsConnNode.WebSocketID]; ok { + for _, h := range headers { + if h.Enabled { + wsStep.Headers = append(wsStep.Headers, YamlNameValuePairV2{ + Name: h.Key, + Value: h.Value, + Enabled: true, + }) + } + } + } + } + stepWrapper.WsConnection = wsStep + + case mflow.NODE_KIND_WS_SEND: + wsSendNode, ok := wsSendNodeMap[node.ID] + if !ok { + continue + } + wsStep := &YamlStepWsSend{ + YamlStepCommon: common, + WsConnectionNodeName: wsSendNode.WsConnectionNodeName, + Message: wsSendNode.Message, + } + stepWrapper.WsSend = wsStep + + case mflow.NODE_KIND_WAIT: + waitNode, ok := waitNodeMap[node.ID] + if !ok { + continue + } + stepWrapper.Wait = &YamlStepWait{ + YamlStepCommon: common, + DurationMs: strconv.FormatInt(waitNode.DurationMs, 10), + } + case mflow.NODE_KIND_MANUAL_START: if node.ID == startNodeID { stepWrapper.ManualStart = &common @@ -575,7 +652,8 @@ func MarshalSimplifiedYAML(data *ioworkspace.WorkspaceBundle) ([]byte, error) { // Checking if any field is set (simplified check, assume one set if we got here) isValid := stepWrapper.Request != nil || stepWrapper.GraphQL != nil || stepWrapper.If != nil || stepWrapper.For != nil || stepWrapper.ForEach != nil || stepWrapper.JS != nil || stepWrapper.AI != nil || - stepWrapper.AIProvider != nil || stepWrapper.AIMemory != nil || stepWrapper.ManualStart != nil + stepWrapper.AIProvider != nil || stepWrapper.AIMemory != nil || stepWrapper.WsConnection != nil || + stepWrapper.WsSend != nil || stepWrapper.Wait != nil || stepWrapper.ManualStart != nil if isValid { flowYaml.Steps = append(flowYaml.Steps, stepWrapper) } diff --git a/packages/server/pkg/translate/yamlflowsimplev2/types.go b/packages/server/pkg/translate/yamlflowsimplev2/types.go index 8aa6f2322..fb38536eb 100644 --- a/packages/server/pkg/translate/yamlflowsimplev2/types.go +++ b/packages/server/pkg/translate/yamlflowsimplev2/types.go @@ -83,8 +83,11 @@ type YamlStepWrapper struct { JS *YamlStepJS `yaml:"js,omitempty"` AI *YamlStepAI `yaml:"ai,omitempty"` AIProvider *YamlStepAIProvider `yaml:"ai_provider,omitempty"` - AIMemory *YamlStepAIMemory `yaml:"ai_memory,omitempty"` - ManualStart *YamlStepCommon `yaml:"manual_start,omitempty"` + AIMemory *YamlStepAIMemory `yaml:"ai_memory,omitempty"` + WsConnection *YamlStepWsConnection `yaml:"ws_connection,omitempty"` + WsSend *YamlStepWsSend `yaml:"ws_send,omitempty"` + Wait *YamlStepWait `yaml:"wait,omitempty"` + ManualStart *YamlStepCommon `yaml:"manual_start,omitempty"` } // Common fields for all step types @@ -166,6 +169,23 @@ type YamlStepAIMemory struct { WindowSize int `yaml:"window_size,omitempty"` // Number of messages to keep (default 10) } +type YamlStepWsConnection struct { + YamlStepCommon `yaml:",inline"` + URL string `yaml:"url,omitempty"` + Headers HeaderMapOrSlice `yaml:"headers,omitempty"` +} + +type YamlStepWsSend struct { + YamlStepCommon `yaml:",inline"` + WsConnectionNodeName string `yaml:"ws_connection_node_name"` + Message string `yaml:"message,omitempty"` +} + +type YamlStepWait struct { + YamlStepCommon `yaml:",inline"` + DurationMs string `yaml:"duration_ms"` +} + // YamlFlowVariableV2 represents a flow variable type YamlFlowVariableV2 struct { Name string `yaml:"name"` @@ -418,7 +438,9 @@ type YamlFlowDataV2 struct { AINodes []mflow.NodeAI AIProviderNodes []mflow.NodeAiProvider AIMemoryNodes []mflow.NodeMemory - GraphQLNodes []mflow.NodeGraphQL + GraphQLNodes []mflow.NodeGraphQL + WsConnectionNodes []mflow.NodeWsConnection + WsSendNodes []mflow.NodeWsSend } // YamlVariableV2 represents a variable during parsing diff --git a/packages/server/pkg/translate/yamlflowsimplev2/utils.go b/packages/server/pkg/translate/yamlflowsimplev2/utils.go index f9dcaec30..4f4b30859 100644 --- a/packages/server/pkg/translate/yamlflowsimplev2/utils.go +++ b/packages/server/pkg/translate/yamlflowsimplev2/utils.go @@ -4,6 +4,7 @@ import ( "fmt" "net/url" "regexp" + "strconv" "strings" "time" @@ -39,9 +40,10 @@ const ( DefaultCollectionName = "Imported Collection" // Dependency handler suffixes (used in depends_on field) - DependsSuffixThen = ".then" - DependsSuffixElse = ".else" - DependsSuffixLoop = ".loop" + DependsSuffixThen = ".then" + DependsSuffixElse = ".else" + DependsSuffixLoop = ".loop" + DependsSuffixWsMessage = ".ws_message" // Environment variable template patterns (used in credential export) EnvVarTemplateToken = "{{ #env:%s_TOKEN }}" //nolint:gosec // G101: template pattern, not a credential @@ -486,7 +488,7 @@ func GenerateStats(data *ioworkspace.WorkspaceBundle) map[string]interface{} { // Flow node breakdown nodeTypes := make(map[string]int) for _, node := range data.FlowNodes { - nodeTypes[string(node.NodeKind)]++ + nodeTypes[strconv.FormatInt(int64(node.NodeKind), 10)]++ } stats["flow_node_types"] = nodeTypes diff --git a/packages/server/pkg/translate/yamlflowsimplev2/utils_test.go b/packages/server/pkg/translate/yamlflowsimplev2/utils_test.go index b17a089e0..8deffd9f6 100644 --- a/packages/server/pkg/translate/yamlflowsimplev2/utils_test.go +++ b/packages/server/pkg/translate/yamlflowsimplev2/utils_test.go @@ -1,6 +1,7 @@ package yamlflowsimplev2 import ( + "strconv" "strings" "testing" @@ -359,8 +360,8 @@ func TestGenerateStats(t *testing.T) { // Check node type breakdown nodeTypes := stats["flow_node_types"].(map[string]int) - require.Equal(t, 2, nodeTypes[string(mflow.NODE_KIND_REQUEST)]) - require.Equal(t, 1, nodeTypes[string(mflow.NODE_KIND_CONDITION)]) + require.Equal(t, 2, nodeTypes[strconv.FormatInt(int64(mflow.NODE_KIND_REQUEST), 10)]) + require.Equal(t, 1, nodeTypes[strconv.FormatInt(int64(mflow.NODE_KIND_CONDITION), 10)]) // Check averages require.Equal(t, 1.5, stats["avg_nodes_per_flow"].(float64)) diff --git a/packages/server/test/e2e_har_to_cli_test.go b/packages/server/test/e2e_har_to_cli_test.go index c1120ae74..003c1366c 100644 --- a/packages/server/test/e2e_har_to_cli_test.go +++ b/packages/server/test/e2e_har_to_cli_test.go @@ -273,6 +273,11 @@ func TestE2E_HAR_To_CLI_Chain(t *testing.T) { nil, // NodeAiProviderService nil, // NodeMemoryService nil, // NodeGraphQLService + nil, // NodeWsConnectionService + nil, // NodeWsSendService + nil, // NodeWaitService + nil, // WebSocketService + nil, // WebSocketHeaderService nil, // GraphQLService nil, // GraphQLHeaderService cli.Workspace, @@ -449,7 +454,6 @@ func executeFlow(ctx context.Context, flowPtr *mflow.Flow, c *cliServices, build if err != nil { return err } - fmt.Printf("DEBUG: Found %d edges for flow %s\n", len(edges), latestFlowID) edgeMap := mflow.NewEdgesMap(edges) flowVars, err := c.FlowVariable.GetFlowVariablesByFlowID(ctx, latestFlowID) @@ -491,7 +495,7 @@ func executeFlow(ctx context.Context, flowPtr *mflow.Flow, c *cliServices, build defer close(gqlRespChan) // Build flow node map - flowNodeMap, startNodeID, err := builder.BuildNodes( + flowNodeMap, startNodeIDs, err := builder.BuildNodes( ctx, *flowPtr, nodes, @@ -506,7 +510,7 @@ func executeFlow(ctx context.Context, flowPtr *mflow.Flow, c *cliServices, build } // Create runner - runnerInst := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), latestFlowID, startNodeID, flowNodeMap, edgeMap, nodeTimeout, nil) + runnerInst := flowlocalrunner.CreateFlowRunner(idwrap.NewNow(), latestFlowID, startNodeIDs, flowNodeMap, edgeMap, nodeTimeout, nil) flowNodeStatusChan := make(chan runner.FlowNodeStatus, 1000) flowStatusChan := make(chan runner.FlowStatus, 10) diff --git a/packages/spec/api/export.tsp b/packages/spec/api/export.tsp index a327d0aa2..cb14e5706 100644 --- a/packages/spec/api/export.tsp +++ b/packages/spec/api/export.tsp @@ -21,3 +21,13 @@ model ExportCurlResponse { data: string; } op ExportCurl(...ExportCurlRequest): ExportCurlResponse; + +model ExportCurlGraphQLRequest { + workspaceId: Id; + graphqlIds?: Id[]; +} + +model ExportCurlGraphQLResponse { + data: string; +} +op ExportCurlGraphQL(...ExportCurlGraphQLRequest): ExportCurlGraphQLResponse; diff --git a/packages/spec/api/file-system.tsp b/packages/spec/api/file-system.tsp index 88fcdb0b7..ceefccf54 100644 --- a/packages/spec/api/file-system.tsp +++ b/packages/spec/api/file-system.tsp @@ -9,6 +9,7 @@ enum FileKind { Flow, Credential, GraphQL, + WebSocket, } @TanStackDB.collection diff --git a/packages/spec/api/flow.tsp b/packages/spec/api/flow.tsp index 27c23414b..d4e91f4ab 100644 --- a/packages/spec/api/flow.tsp +++ b/packages/spec/api/flow.tsp @@ -67,6 +67,7 @@ enum HandleKind { AiProvider, AiMemory, AiTools, + WsMessage, } @AITools.mutationTool(#{ @@ -96,6 +97,9 @@ enum NodeKind { AiProvider, AiMemory, GraphQL, + WsConnection, + WsSend, + Wait, } enum AiMemoryType { @@ -293,6 +297,25 @@ model NodeAiMemory { windowSize: int32; } +@TanStackDB.collection +model NodeWsConnection { + @primaryKey nodeId: Id; + @foreignKey websocketId?: Id; +} + +@TanStackDB.collection +model NodeWsSend { + @primaryKey nodeId: Id; + wsConnectionNodeName: string; + message: string; +} + +@TanStackDB.collection +model NodeWait { + @primaryKey nodeId: Id; + durationMs: int64; +} + // Copy/Paste operations enum ReferenceMode { CreateCopy, diff --git a/packages/spec/api/main.tsp b/packages/spec/api/main.tsp index ae71a6e20..9fcb49703 100644 --- a/packages/spec/api/main.tsp +++ b/packages/spec/api/main.tsp @@ -17,6 +17,7 @@ import "./private/node-js-executor.tsp"; import "./log.tsp"; import "./reference.tsp"; // import "./user.tsp"; +import "./websocket.tsp"; import "./workspace.tsp"; using DevTools; diff --git a/packages/spec/api/websocket.tsp b/packages/spec/api/websocket.tsp new file mode 100644 index 000000000..cd1e3405e --- /dev/null +++ b/packages/spec/api/websocket.tsp @@ -0,0 +1,23 @@ +using DevTools; + +namespace Api.WebSocket; + +@TanStackDB.collection +model WebSocket { + @primaryKey websocketId: Id; + name: string; + url: string; + lastRunAt?: Protobuf.WellKnown.Timestamp; +} + +@TanStackDB.collection +model WebSocketHeader { + @primaryKey websocketHeaderId: Id; + ...CommonTableFields; +} + +model WebSocketRunRequest { + websocketId: Id; +} + +op WebSocketRun(...WebSocketRunRequest): {}; diff --git a/packages/spec/package.json b/packages/spec/package.json index 1407f9752..01acd4b73 100755 --- a/packages/spec/package.json +++ b/packages/spec/package.json @@ -25,7 +25,7 @@ "@the-dev-tools/eslint-config": "workspace:^", "@types/node": "catalog:", "prettier": "catalog:", - "tsx": "^4.19.0", + "tsx": "catalog:", "typescript": "catalog:" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b2b16a50a..d58464f08 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,8 +7,8 @@ settings: catalogs: default: '@aikidosec/safe-chain': - specifier: 1.4.0 - version: 1.4.0 + specifier: 1.4.4 + version: 1.4.4 '@alloy-js/cli': specifier: 0.22.0 version: 0.22.0 @@ -19,26 +19,26 @@ catalogs: specifier: 0.22.0 version: 0.22.0 '@better-auth/cli': - specifier: 1.4.18 - version: 1.4.18 + specifier: 1.4.21 + version: 1.4.21 '@bufbuild/buf': - specifier: 1.63.0 - version: 1.63.0 + specifier: 1.66.0 + version: 1.66.0 '@bufbuild/protobuf': - specifier: 2.10.2 - version: 2.10.2 + specifier: 2.11.0 + version: 2.11.0 '@bufbuild/protoc-gen-es': - specifier: 2.10.2 - version: 2.10.2 + specifier: 2.11.0 + version: 2.11.0 '@bufbuild/protovalidate': - specifier: 1.1.0 - version: 1.1.0 + specifier: 1.1.1 + version: 1.1.1 '@codemirror/lang-html': specifier: 6.4.11 version: 6.4.11 '@codemirror/lang-javascript': - specifier: 6.2.4 - version: 6.2.4 + specifier: 6.2.5 + version: 6.2.5 '@codemirror/lang-json': specifier: 6.0.2 version: 6.0.2 @@ -58,29 +58,29 @@ catalogs: specifier: 2.1.1 version: 2.1.1 '@effect-atom/atom-react': - specifier: 0.4.4 - version: 0.4.4 + specifier: 0.5.0 + version: 0.5.0 '@effect/cli': - specifier: 0.73.0 - version: 0.73.0 + specifier: 0.73.2 + version: 0.73.2 '@effect/platform': - specifier: 0.94.1 - version: 0.94.1 + specifier: 0.94.5 + version: 0.94.5 '@effect/platform-browser': specifier: 0.74.0 version: 0.74.0 '@effect/platform-node': - specifier: 0.104.0 - version: 0.104.0 + specifier: 0.104.1 + version: 0.104.1 '@eslint/compat': - specifier: 2.0.0 - version: 2.0.0 + specifier: 2.0.2 + version: 2.0.2 '@eslint/js': specifier: 9.39.2 version: 9.39.2 '@faker-js/faker': - specifier: 10.2.0 - version: 10.2.0 + specifier: 10.3.0 + version: 10.3.0 '@fontsource-variable/dm-sans': specifier: 5.2.8 version: 5.2.8 @@ -100,26 +100,26 @@ catalogs: specifier: 1.2.3 version: 1.2.3 '@lezer/lr': - specifier: 1.4.7 - version: 1.4.7 + specifier: 1.4.8 + version: 1.4.8 '@nx/eslint': - specifier: 22.3.3 - version: 22.3.3 + specifier: 22.5.4 + version: 22.5.4 '@nx/js': - specifier: 22.3.3 - version: 22.3.3 + specifier: 22.5.4 + version: 22.5.4 '@nx/react': - specifier: 22.3.3 - version: 22.3.3 + specifier: 22.5.4 + version: 22.5.4 '@nx/storybook': - specifier: 22.3.3 - version: 22.3.3 + specifier: 22.5.4 + version: 22.5.4 '@nx/vite': - specifier: 22.3.3 - version: 22.3.3 + specifier: 22.5.4 + version: 22.5.4 '@nx/web': - specifier: 22.3.3 - version: 22.3.3 + specifier: 22.5.4 + version: 22.5.4 '@octokit/auth-action': specifier: 6.0.2 version: 6.0.2 @@ -130,50 +130,50 @@ catalogs: specifier: 3.4.2 version: 3.4.2 '@react-aria/collections': - specifier: 3.0.1 - version: 3.0.1 + specifier: 3.0.3 + version: 3.0.3 '@standard-schema/spec': specifier: 1.1.0 version: 1.1.0 '@storybook/addon-docs': - specifier: 10.1.11 - version: 10.1.11 + specifier: 10.2.16 + version: 10.2.16 '@storybook/react': - specifier: 10.1.11 - version: 10.1.11 + specifier: 10.2.16 + version: 10.2.16 '@storybook/react-vite': - specifier: 10.1.11 - version: 10.1.11 + specifier: 10.2.16 + version: 10.2.16 '@tailwindcss/typography': specifier: 0.5.19 version: 0.5.19 '@tailwindcss/vite': - specifier: 4.1.18 - version: 4.1.18 + specifier: 4.2.1 + version: 4.2.1 '@tanstack/eslint-plugin-router': - specifier: 1.141.0 - version: 1.141.0 + specifier: 1.161.4 + version: 1.161.4 '@tanstack/react-db': - specifier: 0.1.60 - version: 0.1.60 + specifier: 0.1.74 + version: 0.1.74 '@tanstack/react-query': - specifier: 5.90.16 - version: 5.90.16 + specifier: 5.90.21 + version: 5.90.21 '@tanstack/react-query-devtools': - specifier: 5.91.2 - version: 5.91.2 + specifier: 5.91.3 + version: 5.91.3 '@tanstack/react-router': - specifier: 1.145.7 - version: 1.145.7 + specifier: 1.166.2 + version: 1.166.2 '@tanstack/react-router-devtools': - specifier: 1.145.7 - version: 1.145.7 + specifier: 1.166.2 + version: 1.166.2 '@tanstack/router-plugin': - specifier: 1.145.10 - version: 1.145.10 + specifier: 1.166.2 + version: 1.166.2 '@tanstack/virtual-file-routes': - specifier: 1.145.4 - version: 1.145.4 + specifier: 1.161.4 + version: 1.161.4 '@tsconfig/strictest': specifier: 2.0.8 version: 2.0.8 @@ -181,11 +181,11 @@ catalogs: specifier: 6.10.1 version: 6.10.1 '@types/node': - specifier: 25.0.3 - version: 25.0.3 + specifier: 25.3.5 + version: 25.3.5 '@types/react': - specifier: 19.2.7 - version: 19.2.7 + specifier: 19.2.14 + version: 19.2.14 '@types/react-dom': specifier: 19.2.3 version: 19.2.3 @@ -193,23 +193,23 @@ catalogs: specifier: 8.0.0 version: 8.0.0 '@typescript-eslint/parser': - specifier: 8.52.0 - version: 8.52.0 + specifier: 8.56.1 + version: 8.56.1 '@typespec/compiler': - specifier: 1.7.1 - version: 1.7.1 + specifier: 1.9.0 + version: 1.9.0 '@typespec/emitter-framework': - specifier: 0.14.0 - version: 0.14.0 + specifier: 0.16.0 + version: 0.16.0 '@typespec/prettier-plugin-typespec': - specifier: 1.7.0 - version: 1.7.0 + specifier: 1.9.0 + version: 1.9.0 '@uiw/react-codemirror': - specifier: 4.25.4 - version: 4.25.4 + specifier: 4.25.7 + version: 4.25.7 '@vitejs/plugin-react': - specifier: 5.1.2 - version: 5.1.2 + specifier: 5.1.4 + version: 5.1.4 '@xyflow/react': specifier: 12.10.1 version: 12.10.1 @@ -217,23 +217,26 @@ catalogs: specifier: 19.1.0-rc.3 version: 19.1.0-rc.3 better-auth: - specifier: 1.4.18 - version: 1.4.18 + specifier: 1.5.4 + version: 1.5.4 builder-util-runtime: specifier: 9.5.1 version: 9.5.1 effect: - specifier: 3.19.14 - version: 3.19.14 + specifier: 3.19.19 + version: 3.19.19 electron: - specifier: 39.2.7 - version: 39.2.7 + specifier: 40.8.0 + version: 40.8.0 electron-builder: - specifier: 26.3.1 - version: 26.3.1 + specifier: 26.8.1 + version: 26.8.1 electron-devtools-installer: specifier: 4.0.0 version: 4.0.0 + electron-updater: + specifier: 6.8.3 + version: 6.8.3 electron-vite: specifier: 5.0.0 version: 5.0.0 @@ -247,8 +250,8 @@ catalogs: specifier: 4.4.4 version: 4.4.4 eslint-plugin-better-tailwindcss: - specifier: 3.8.0 - version: 3.8.0 + specifier: 4.3.2 + version: 4.3.2 eslint-plugin-import-x: specifier: 4.16.1 version: 4.16.1 @@ -256,8 +259,8 @@ catalogs: specifier: 6.10.2 version: 6.10.2 eslint-plugin-perfectionist: - specifier: 5.3.0 - version: 5.3.0 + specifier: 5.6.0 + version: 5.6.0 eslint-plugin-react: specifier: 7.37.5 version: 7.37.5 @@ -265,8 +268,8 @@ catalogs: specifier: 7.0.1 version: 7.0.1 globals: - specifier: 17.0.0 - version: 17.0.0 + specifier: 17.4.0 + version: 17.4.0 id128: specifier: 1.6.6 version: 1.6.6 @@ -274,44 +277,44 @@ catalogs: specifier: 2.6.1 version: 2.6.1 nx: - specifier: 22.3.3 - version: 22.3.3 + specifier: 22.5.4 + version: 22.5.4 openai: - specifier: 4.77.0 - version: 4.77.0 + specifier: 6.27.0 + version: 6.27.0 prettier: - specifier: 3.7.4 - version: 3.7.4 + specifier: 3.8.1 + version: 3.8.1 react: - specifier: 19.2.3 - version: 19.2.3 + specifier: 19.2.4 + version: 19.2.4 react-aria: - specifier: 3.45.0 - version: 3.45.0 + specifier: 3.47.0 + version: 3.47.0 react-aria-components: - specifier: 1.14.0 - version: 1.14.0 + specifier: 1.16.0 + version: 1.16.0 react-dom: - specifier: 19.2.3 - version: 19.2.3 + specifier: 19.2.4 + version: 19.2.4 react-error-boundary: - specifier: 6.0.2 - version: 6.0.2 + specifier: 6.1.1 + version: 6.1.1 react-icons: - specifier: 5.5.0 - version: 5.5.0 + specifier: 5.6.0 + version: 5.6.0 react-markdown: specifier: 10.1.0 version: 10.1.0 react-resizable-panels: - specifier: 4.3.0 - version: 4.3.0 + specifier: 4.7.1 + version: 4.7.1 react-scan: - specifier: 0.4.3 - version: 0.4.3 + specifier: 0.5.3 + version: 0.5.3 react-stately: - specifier: 3.43.0 - version: 3.43.0 + specifier: 3.45.0 + version: 3.45.0 react-timeago: specifier: 8.3.0 version: 8.3.0 @@ -319,8 +322,8 @@ catalogs: specifier: 4.0.1 version: 4.0.1 storybook: - specifier: 10.1.11 - version: 10.1.11 + specifier: 10.2.16 + version: 10.2.16 swc-node: specifier: 1.0.0 version: 1.0.0 @@ -328,14 +331,14 @@ catalogs: specifier: 13.0.4 version: 13.0.4 tailwind-merge: - specifier: 3.4.0 - version: 3.4.0 + specifier: 3.5.0 + version: 3.5.0 tailwind-variants: specifier: 3.2.2 version: 3.2.2 tailwindcss: - specifier: 4.1.18 - version: 4.1.18 + specifier: 4.2.1 + version: 4.2.1 tailwindcss-react-aria-components: specifier: 2.0.1 version: 2.0.1 @@ -345,6 +348,9 @@ catalogs: tsup: specifier: 8.5.1 version: 8.5.1 + tsx: + specifier: ^4.21.0 + version: 4.21.0 tw-animate-css: specifier: 1.4.0 version: 1.4.0 @@ -352,20 +358,20 @@ catalogs: specifier: 5.9.3 version: 5.9.3 typescript-eslint: - specifier: 8.52.0 - version: 8.52.0 + specifier: 8.56.1 + version: 8.56.1 undici: - specifier: 7.18.2 - version: 7.18.2 + specifier: 7.22.0 + version: 7.22.0 use-debounce: - specifier: 10.0.6 - version: 10.0.6 + specifier: 10.1.0 + version: 10.1.0 vite: specifier: 7.3.1 version: 7.3.1 vite-tsconfig-paths: - specifier: 6.0.3 - version: 6.0.3 + specifier: 6.1.1 + version: 6.1.1 vitest: specifier: 4.0.18 version: 4.0.18 @@ -379,6 +385,7 @@ overrides: '@codemirror/language': 6.12.1 '@codemirror/state': 6.5.3 '@codemirror/view': 6.39.9 + '@lezer/common': 1.5.1 '@types/eslint': '-' patchedDependencies: @@ -402,25 +409,25 @@ importers: devDependencies: '@aikidosec/safe-chain': specifier: 'catalog:' - version: 1.4.0 + version: 1.4.4 '@nx/eslint': specifier: 'catalog:' - version: 22.3.3(patch_hash=45d7a0a2e2d55c4ffd4beb467a0e02fac3f27bc1857270f522acafd5365d2c6b)(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) + version: 22.5.4(patch_hash=45d7a0a2e2d55c4ffd4beb467a0e02fac3f27bc1857270f522acafd5365d2c6b)(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) '@nx/js': specifier: 'catalog:' - version: 22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) + version: 22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) '@nx/react': specifier: 'catalog:' - version: 22.3.3(@babel/core@7.28.5)(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/helpers@0.5.18)(@types/babel__core@7.20.5)(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(ts-node@10.9.2(@swc/core@1.15.8(@swc/helpers@0.5.18))(@types/node@25.0.3)(typescript@5.9.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))) + version: 22.5.4(@babel/core@7.29.0)(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/helpers@0.5.19)(@types/babel__core@7.20.5)(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@nx/storybook': specifier: 'catalog:' - version: 22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)))(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.7.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3) + version: 22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)))(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) '@nx/vite': specifier: 'catalog:' - version: 22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)))(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@nx/web': specifier: 'catalog:' - version: 22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) + version: 22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) '@the-dev-tools/eslint-config': specifier: workspace:^ version: link:tools/eslint @@ -429,10 +436,10 @@ importers: version: 2.0.8 '@typespec/compiler': specifier: 'catalog:' - version: 1.7.1(@types/node@25.0.3) + version: 1.9.0(@types/node@25.3.5) '@typespec/prettier-plugin-typespec': specifier: 'catalog:' - version: 1.7.0 + version: 1.9.0 eslint: specifier: 'catalog:' version: 9.39.2(jiti@2.6.1) @@ -441,31 +448,31 @@ importers: version: 2.6.1 nx: specifier: 'catalog:' - version: 22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)) + version: 22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)) prettier: specifier: 'catalog:' - version: 3.7.4 + version: 3.8.1 react: specifier: 'catalog:' - version: 19.2.3 + version: 19.2.4 swc-node: specifier: 'catalog:' - version: 1.0.0(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3) + version: 1.0.0(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3) syncpack: specifier: 'catalog:' version: 13.0.4(typescript@5.9.3) tailwindcss: specifier: 'catalog:' - version: 4.1.18 + version: 4.2.1 ts-node: specifier: 'catalog:' - version: 10.9.2(@swc/core@1.15.8(@swc/helpers@0.5.18))(@types/node@25.0.3)(typescript@5.9.3) + version: 10.9.2(@swc/core@1.15.8(@swc/helpers@0.5.19))(@types/node@25.3.5)(typescript@5.9.3) typescript: specifier: 'catalog:' version: 5.9.3 typescript-eslint: specifier: 'catalog:' - version: 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + version: 8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) apps/cli: dependencies: @@ -487,34 +494,34 @@ importers: devDependencies: '@bufbuild/protobuf': specifier: 'catalog:' - version: 2.10.2 + version: 2.11.0 '@connectrpc/connect': specifier: 'catalog:' - version: 2.1.1(@bufbuild/protobuf@2.10.2) + version: 2.1.1(@bufbuild/protobuf@2.11.0) '@connectrpc/connect-node': specifier: 'catalog:' - version: 2.1.1(@bufbuild/protobuf@2.10.2)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.10.2)) + version: 2.1.1(@bufbuild/protobuf@2.11.0)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.11.0)) '@effect-atom/atom-react': specifier: 'catalog:' - version: 0.4.4(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14)(react@19.2.3)(scheduler@0.27.0) + version: 0.5.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19)(react@19.2.4)(scheduler@0.27.0) '@effect/platform': specifier: 'catalog:' - version: 0.94.1(effect@3.19.14) + version: 0.94.5(effect@3.19.19) '@effect/platform-browser': specifier: 'catalog:' - version: 0.74.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14) + version: 0.74.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19) '@effect/platform-node': specifier: 'catalog:' - version: 0.104.0(@effect/cluster@0.56.1(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14) + version: 0.104.1(@effect/cluster@0.56.1(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19) '@lezer/generator': specifier: 'catalog:' version: 1.8.0 '@tailwindcss/typography': specifier: 'catalog:' - version: 0.5.19(tailwindcss@4.1.18) + version: 0.5.19(tailwindcss@4.2.1) '@tailwindcss/vite': specifier: 'catalog:' - version: 4.1.18(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 4.2.1(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@the-dev-tools/client': specifier: workspace:^ version: link:../../packages/client @@ -526,13 +533,13 @@ importers: version: link:../../packages/ui '@types/react': specifier: 'catalog:' - version: 19.2.7 + version: 19.2.14 '@types/react-dom': specifier: 'catalog:' - version: 19.2.3(@types/react@19.2.7) + version: 19.2.3(@types/react@19.2.14) '@vitejs/plugin-react': specifier: 'catalog:' - version: 5.1.2(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 5.1.4(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) babel-plugin-react-compiler: specifier: 'catalog:' version: 19.1.0-rc.3 @@ -541,49 +548,49 @@ importers: version: 9.5.1 effect: specifier: 'catalog:' - version: 3.19.14 + version: 3.19.19 electron: specifier: 'catalog:' - version: 39.2.7 + version: 40.8.0 electron-builder: specifier: 'catalog:' - version: 26.3.1(electron-builder-squirrel-windows@26.4.0) + version: 26.8.1(electron-builder-squirrel-windows@26.4.0) electron-devtools-installer: specifier: 'catalog:' version: 4.0.0 electron-updater: - specifier: 6.7.3 - version: 6.7.3 + specifier: 'catalog:' + version: 6.8.3 electron-vite: specifier: 'catalog:' - version: 5.0.0(@swc/core@1.15.8(@swc/helpers@0.5.18))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 5.0.0(@swc/core@1.15.8(@swc/helpers@0.5.19))(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) eslint: specifier: 'catalog:' version: 9.39.2(jiti@2.6.1) react: specifier: 'catalog:' - version: 19.2.3 + version: 19.2.4 react-dom: specifier: 'catalog:' - version: 19.2.3(react@19.2.3) + version: 19.2.4(react@19.2.4) react-markdown: specifier: 'catalog:' - version: 10.1.0(@types/react@19.2.7)(react@19.2.3) + version: 10.1.0(@types/react@19.2.14)(react@19.2.4) tailwindcss: specifier: 'catalog:' - version: 4.1.18 + version: 4.2.1 typescript: specifier: 'catalog:' version: 5.9.3 undici: specifier: 'catalog:' - version: 7.18.2 + version: 7.22.0 vite: specifier: 'catalog:' - version: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + version: 7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vite-tsconfig-paths: specifier: 'catalog:' - version: 6.0.3(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) yaml: specifier: 'catalog:' version: 2.8.2 @@ -592,35 +599,35 @@ importers: dependencies: '@bufbuild/protobuf': specifier: 'catalog:' - version: 2.10.2 + version: 2.11.0 '@connectrpc/connect': specifier: 'catalog:' - version: 2.1.1(@bufbuild/protobuf@2.10.2) + version: 2.1.1(@bufbuild/protobuf@2.11.0) '@connectrpc/connect-node': specifier: 'catalog:' - version: 2.1.1(@bufbuild/protobuf@2.10.2)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.10.2)) + version: 2.1.1(@bufbuild/protobuf@2.11.0)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.11.0)) '@effect/platform': specifier: 'catalog:' - version: 0.94.1(effect@3.19.14) + version: 0.94.5(effect@3.19.19) '@effect/platform-node': specifier: 'catalog:' - version: 0.104.0(@effect/cluster@0.56.1(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14) + version: 0.104.1(@effect/cluster@0.56.1(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19) '@the-dev-tools/spec': specifier: workspace:^ version: link:../spec better-auth: specifier: 'catalog:' - version: 1.4.18(@prisma/client@5.22.0)(better-sqlite3@12.6.2)(drizzle-orm@0.41.0(@libsql/client@0.14.0)(@prisma/client@5.22.0)(@types/pg@8.16.0)(better-sqlite3@12.6.2)(kysely@0.28.11)(pg@8.18.0))(pg@8.18.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.10)(vitest@4.0.18(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 1.5.4(@prisma/client@5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(better-sqlite3@12.6.2)(drizzle-orm@0.41.0(@electric-sql/pglite@0.3.15)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.18.0)(better-sqlite3@12.6.2)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(mongodb@7.1.0(socks@2.8.7))(mysql2@3.15.3)(pg@8.20.0)(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(solid-js@1.9.10)(vitest@4.0.18(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) effect: specifier: 'catalog:' - version: 3.19.14 + version: 3.19.19 id128: specifier: 'catalog:' version: 1.6.6 devDependencies: '@better-auth/cli': specifier: 'catalog:' - version: 1.4.18(@better-fetch/fetch@1.1.21)(@libsql/client@0.14.0)(better-call@1.1.8(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.10)(vitest@4.0.18(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 1.4.21(@better-fetch/fetch@1.1.21)(@electric-sql/pglite@0.3.15)(@libsql/client@0.14.0)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(mongodb@7.1.0(socks@2.8.7))(mysql2@3.15.3)(nanostores@1.1.1)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(solid-js@1.9.10)(vitest@4.0.18(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@the-dev-tools/eslint-config': specifier: workspace:^ version: link:../../tools/eslint @@ -629,7 +636,7 @@ importers: version: link:../server '@types/node': specifier: 'catalog:' - version: 25.0.3 + version: 25.3.5 eslint: specifier: 'catalog:' version: 9.39.2(jiti@2.6.1) @@ -638,16 +645,16 @@ importers: version: 5.9.3 vitest: specifier: 'catalog:' - version: 4.0.18(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + version: 4.0.18(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) packages/client: dependencies: '@bufbuild/protobuf': specifier: 'catalog:' - version: 2.10.2 + version: 2.11.0 '@bufbuild/protovalidate': specifier: 'catalog:' - version: 1.1.0(@bufbuild/protobuf@2.10.2) + version: 1.1.1(@bufbuild/protobuf@2.11.0) '@codemirror/autocomplete': specifier: 6.20.0 version: 6.20.0 @@ -659,7 +666,7 @@ importers: version: 6.4.11 '@codemirror/lang-javascript': specifier: 'catalog:' - version: 6.2.4 + version: 6.2.5 '@codemirror/lang-json': specifier: 'catalog:' version: 6.0.2 @@ -677,55 +684,55 @@ importers: version: 6.39.9 '@connectrpc/connect': specifier: 'catalog:' - version: 2.1.1(@bufbuild/protobuf@2.10.2) + version: 2.1.1(@bufbuild/protobuf@2.11.0) '@connectrpc/connect-query': specifier: 'catalog:' - version: 2.2.0(@bufbuild/protobuf@2.10.2)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.10.2))(@tanstack/query-core@5.90.16)(@tanstack/react-query@5.90.16(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 2.2.0(@bufbuild/protobuf@2.11.0)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.11.0))(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@connectrpc/connect-web': specifier: 'catalog:' - version: 2.1.1(@bufbuild/protobuf@2.10.2)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.10.2)) + version: 2.1.1(@bufbuild/protobuf@2.11.0)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.11.0)) '@effect-atom/atom-react': specifier: 'catalog:' - version: 0.4.4(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14)(react@19.2.3)(scheduler@0.27.0) + version: 0.5.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19)(react@19.2.4)(scheduler@0.27.0) '@effect/platform': specifier: 'catalog:' - version: 0.94.1(effect@3.19.14) + version: 0.94.5(effect@3.19.19) '@effect/platform-browser': specifier: 'catalog:' - version: 0.74.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14) + version: 0.74.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19) '@faker-js/faker': specifier: 'catalog:' - version: 10.2.0 + version: 10.3.0 '@hookform/resolvers': specifier: 'catalog:' - version: 5.2.2(react-hook-form@7.70.0(react@19.2.3)) + version: 5.2.2(react-hook-form@7.70.0(react@19.2.4)) '@lezer/highlight': specifier: 'catalog:' version: 1.2.3 '@lezer/lr': specifier: 'catalog:' - version: 1.4.7 + version: 1.4.8 '@prettier/plugin-xml': specifier: 'catalog:' - version: 3.4.2(prettier@3.7.4) + version: 3.4.2(prettier@3.8.1) '@react-aria/collections': specifier: 'catalog:' - version: 3.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 3.0.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@standard-schema/spec': specifier: 'catalog:' version: 1.1.0 '@tanstack/react-db': specifier: 'catalog:' - version: 0.1.60(react@19.2.3)(typescript@5.9.3) + version: 0.1.74(react@19.2.4)(typescript@5.9.3) '@tanstack/react-query': specifier: 'catalog:' - version: 5.90.16(react@19.2.3) + version: 5.90.21(react@19.2.4) '@tanstack/react-router': specifier: 'catalog:' - version: 1.145.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 1.166.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@tanstack/virtual-file-routes': specifier: 'catalog:' - version: 1.145.4 + version: 1.161.4 '@the-dev-tools/spec': specifier: workspace:^ version: link:../spec @@ -737,89 +744,89 @@ importers: version: link:../ui '@uiw/react-codemirror': specifier: 'catalog:' - version: 4.25.4(@babel/runtime@7.28.4)(@codemirror/autocomplete@6.20.0)(@codemirror/language@6.12.1)(@codemirror/lint@6.9.2)(@codemirror/search@6.5.11)(@codemirror/state@6.5.3)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.39.9)(codemirror@6.0.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 4.25.7(@babel/runtime@7.28.6)(@codemirror/autocomplete@6.20.0)(@codemirror/language@6.12.1)(@codemirror/lint@6.9.5)(@codemirror/search@6.5.11)(@codemirror/state@6.5.3)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.39.9)(codemirror@6.0.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@xyflow/react': specifier: 'catalog:' - version: 12.10.1(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 12.10.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) effect: specifier: 'catalog:' - version: 3.19.14 + version: 3.19.19 id128: specifier: 'catalog:' version: 1.6.6 openai: specifier: 'catalog:' - version: 4.77.0(encoding@0.1.13)(zod@3.25.76) + version: 6.27.0(ws@8.19.0)(zod@4.3.6) prettier: specifier: 'catalog:' - version: 3.7.4 + version: 3.8.1 react: specifier: 'catalog:' - version: 19.2.3 + version: 19.2.4 react-aria: specifier: 'catalog:' - version: 3.45.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 3.47.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react-aria-components: specifier: 'catalog:' - version: 1.14.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 1.16.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react-dom: specifier: 'catalog:' - version: 19.2.3(react@19.2.3) + version: 19.2.4(react@19.2.4) react-error-boundary: specifier: 'catalog:' - version: 6.0.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 6.1.1(react@19.2.4) react-icons: specifier: 'catalog:' - version: 5.5.0(react@19.2.3) + version: 5.6.0(react@19.2.4) react-markdown: specifier: 'catalog:' - version: 10.1.0(@types/react@19.2.7)(react@19.2.3) + version: 10.1.0(@types/react@19.2.14)(react@19.2.4) react-resizable-panels: specifier: 'catalog:' - version: 4.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 4.7.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react-scan: specifier: 'catalog:' - version: 0.4.3(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.55.1) + version: 0.5.3(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.59.0) react-stately: specifier: 'catalog:' - version: 3.43.0(react@19.2.3) + version: 3.45.0(react@19.2.4) react-timeago: specifier: 'catalog:' - version: 8.3.0(react@19.2.3) + version: 8.3.0(react@19.2.4) remark-gfm: specifier: 'catalog:' version: 4.0.1 tailwind-merge: specifier: 'catalog:' - version: 3.4.0 + version: 3.5.0 tailwind-variants: specifier: 'catalog:' - version: 3.2.2(tailwind-merge@3.4.0)(tailwindcss@4.1.18) + version: 3.2.2(tailwind-merge@3.5.0)(tailwindcss@4.2.1) use-debounce: specifier: 'catalog:' - version: 10.0.6(react@19.2.3) + version: 10.1.0(react@19.2.4) devDependencies: '@hookform/devtools': specifier: 'catalog:' - version: 4.4.0(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 4.4.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@lezer/generator': specifier: 'catalog:' version: 1.8.0 '@storybook/react-vite': specifier: 'catalog:' - version: 10.1.11(esbuild@0.27.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.55.1)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.7.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2)) + version: 10.2.16(esbuild@0.27.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.59.0)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3)) '@tailwindcss/vite': specifier: 'catalog:' - version: 4.1.18(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 4.2.1(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@tanstack/react-query-devtools': specifier: 'catalog:' - version: 5.91.2(@tanstack/react-query@5.90.16(react@19.2.3))(react@19.2.3) + version: 5.91.3(@tanstack/react-query@5.90.21(react@19.2.4))(react@19.2.4) '@tanstack/react-router-devtools': specifier: 'catalog:' - version: 1.145.7(@tanstack/react-router@1.145.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.145.7)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.10) + version: 1.166.2(@tanstack/react-router@1.166.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@tanstack/router-core@1.166.2)(csstype@3.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@tanstack/router-plugin': specifier: 'catalog:' - version: 1.145.10(@tanstack/react-router@1.145.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2)) + version: 1.166.2(@tanstack/react-router@1.166.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3)) '@the-dev-tools/auth': specifier: workspace:^ version: link:../auth @@ -828,40 +835,40 @@ importers: version: link:../../tools/eslint '@types/react': specifier: 'catalog:' - version: 19.2.7 + version: 19.2.14 '@types/react-dom': specifier: 'catalog:' - version: 19.2.3(@types/react@19.2.7) + version: 19.2.3(@types/react@19.2.14) '@types/react-timeago': specifier: 'catalog:' - version: 8.0.0(react@19.2.3) + version: 8.0.0(react@19.2.4) '@vitejs/plugin-react': specifier: 'catalog:' - version: 5.1.2(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 5.1.4(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) babel-plugin-react-compiler: specifier: 'catalog:' version: 19.1.0-rc.3 electron: specifier: 'catalog:' - version: 39.2.7 + version: 40.8.0 eslint: specifier: 'catalog:' version: 9.39.2(jiti@2.6.1) globals: specifier: 'catalog:' - version: 17.0.0 + version: 17.4.0 storybook: specifier: 'catalog:' - version: 10.1.11(@testing-library/dom@10.4.1)(prettier@3.7.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) typescript: specifier: 'catalog:' version: 5.9.3 vite: specifier: 'catalog:' - version: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + version: 7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vite-tsconfig-paths: specifier: 'catalog:' - version: 6.0.3(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) packages/server: dependencies: @@ -876,28 +883,28 @@ importers: version: link:../../tools/spec-lib effect: specifier: 'catalog:' - version: 3.19.14 + version: 3.19.19 devDependencies: '@bufbuild/buf': specifier: 'catalog:' - version: 1.63.0 + version: 1.66.0 '@bufbuild/protobuf': specifier: 'catalog:' - version: 2.10.2 + version: 2.11.0 '@bufbuild/protoc-gen-es': specifier: 'catalog:' - version: 2.10.2(@bufbuild/protobuf@2.10.2) + version: 2.11.0(@bufbuild/protobuf@2.11.0) '@the-dev-tools/eslint-config': specifier: workspace:^ version: link:../../tools/eslint '@types/node': specifier: 'catalog:' - version: 25.0.3 + version: 25.3.5 prettier: specifier: 'catalog:' - version: 3.7.4 + version: 3.8.1 tsx: - specifier: ^4.19.0 + specifier: 'catalog:' version: 4.21.0 typescript: specifier: 'catalog:' @@ -907,7 +914,7 @@ importers: dependencies: '@bufbuild/protobuf': specifier: 'catalog:' - version: 2.10.2 + version: 2.11.0 '@fontsource-variable/dm-sans': specifier: 'catalog:' version: 5.2.8 @@ -916,77 +923,77 @@ importers: version: 5.2.7 '@react-aria/collections': specifier: 'catalog:' - version: 3.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 3.0.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@tanstack/react-router': specifier: 'catalog:' - version: 1.145.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 1.166.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) effect: specifier: 'catalog:' - version: 3.19.14 + version: 3.19.19 react: specifier: 'catalog:' - version: 19.2.3 + version: 19.2.4 react-aria: specifier: 'catalog:' - version: 3.45.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 3.47.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react-aria-components: specifier: 'catalog:' - version: 1.14.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 1.16.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react-dom: specifier: 'catalog:' - version: 19.2.3(react@19.2.3) + version: 19.2.4(react@19.2.4) react-icons: specifier: 'catalog:' - version: 5.5.0(react@19.2.3) + version: 5.6.0(react@19.2.4) react-resizable-panels: specifier: 'catalog:' - version: 4.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 4.7.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) tailwind-merge: specifier: 'catalog:' - version: 3.4.0 + version: 3.5.0 tailwind-variants: specifier: 'catalog:' - version: 3.2.2(tailwind-merge@3.4.0)(tailwindcss@4.1.18) + version: 3.2.2(tailwind-merge@3.5.0)(tailwindcss@4.2.1) devDependencies: '@storybook/addon-docs': specifier: 'catalog:' - version: 10.1.11(@types/react@19.2.7)(esbuild@0.27.2)(rollup@4.55.1)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2)) + version: 10.2.16(@types/react@19.2.14)(esbuild@0.27.3)(rollup@4.59.0)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3)) '@storybook/react': specifier: 'catalog:' - version: 10.1.11(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3) + version: 10.2.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) '@storybook/react-vite': specifier: 'catalog:' - version: 10.1.11(esbuild@0.27.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.55.1)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2)) + version: 10.2.16(esbuild@0.27.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.59.0)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3)) '@tailwindcss/vite': specifier: 'catalog:' - version: 4.1.18(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 4.2.1(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@the-dev-tools/eslint-config': specifier: workspace:^ version: link:../../tools/eslint '@types/node': specifier: 'catalog:' - version: 25.0.3 + version: 25.3.5 '@types/react': specifier: 'catalog:' - version: 19.2.7 + version: 19.2.14 '@types/react-dom': specifier: 'catalog:' - version: 19.2.3(@types/react@19.2.7) + version: 19.2.3(@types/react@19.2.14) '@vitejs/plugin-react': specifier: 'catalog:' - version: 5.1.2(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 5.1.4(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) babel-plugin-react-compiler: specifier: 'catalog:' version: 19.1.0-rc.3 storybook: specifier: 'catalog:' - version: 10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) tailwindcss: specifier: 'catalog:' - version: 4.1.18 + version: 4.2.1 tailwindcss-react-aria-components: specifier: 'catalog:' - version: 2.0.1(tailwindcss@4.1.18) + version: 2.0.1(tailwindcss@4.2.1) tw-animate-css: specifier: 'catalog:' version: 1.4.0 @@ -995,22 +1002,22 @@ importers: version: 5.9.3 vite: specifier: 'catalog:' - version: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + version: 7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) packages/worker-js: devDependencies: '@bufbuild/protobuf': specifier: 'catalog:' - version: 2.10.2 + version: 2.11.0 '@connectrpc/connect': specifier: 'catalog:' - version: 2.1.1(@bufbuild/protobuf@2.10.2) + version: 2.1.1(@bufbuild/protobuf@2.11.0) '@effect/platform': specifier: 'catalog:' - version: 0.94.1(effect@3.19.14) + version: 0.94.5(effect@3.19.19) '@effect/platform-node': specifier: 'catalog:' - version: 0.104.0(@effect/cluster@0.56.1(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14) + version: 0.104.1(@effect/cluster@0.56.1(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19) '@the-dev-tools/eslint-config': specifier: workspace:^ version: link:../../tools/eslint @@ -1019,16 +1026,16 @@ importers: version: link:../spec '@types/node': specifier: 'catalog:' - version: 25.0.3 + version: 25.3.5 effect: specifier: 'catalog:' - version: 3.19.14 + version: 3.19.19 eslint: specifier: 'catalog:' version: 9.39.2(jiti@2.6.1) tsup: specifier: 'catalog:' - version: 8.5.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) + version: 8.5.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) typescript: specifier: 'catalog:' version: 5.9.3 @@ -1037,25 +1044,25 @@ importers: devDependencies: '@eslint/compat': specifier: 'catalog:' - version: 2.0.0(eslint@9.39.2(jiti@2.6.1)) + version: 2.0.2(eslint@9.39.2(jiti@2.6.1)) '@eslint/js': specifier: 'catalog:' version: 9.39.2 '@tanstack/eslint-plugin-router': specifier: 'catalog:' - version: 1.141.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + version: 1.161.4(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) '@types/eslint-plugin-jsx-a11y': specifier: 'catalog:' version: 6.10.1(jiti@2.6.1) '@types/node': specifier: 'catalog:' - version: 25.0.3 + version: 25.3.5 '@typescript-eslint/parser': specifier: 'catalog:' - version: 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + version: 8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) effect: specifier: 'catalog:' - version: 3.19.14 + version: 3.19.19 eslint: specifier: 'catalog:' version: 9.39.2(jiti@2.6.1) @@ -1064,19 +1071,19 @@ importers: version: 10.1.8(eslint@9.39.2(jiti@2.6.1)) eslint-import-resolver-typescript: specifier: 'catalog:' - version: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)) + version: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-better-tailwindcss: specifier: 'catalog:' - version: 3.8.0(eslint@9.39.2(jiti@2.6.1))(tailwindcss@4.1.18) + version: 4.3.2(eslint@9.39.2(jiti@2.6.1))(tailwindcss@4.2.1)(typescript@5.9.3) eslint-plugin-import-x: specifier: 'catalog:' - version: 4.16.1(@typescript-eslint/utils@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)) + version: 4.16.1(@typescript-eslint/utils@8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-jsx-a11y: specifier: 'catalog:' version: 6.10.2(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-perfectionist: specifier: 'catalog:' - version: 5.3.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + version: 5.6.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint-plugin-react: specifier: 'catalog:' version: 7.37.5(eslint@9.39.2(jiti@2.6.1)) @@ -1085,25 +1092,25 @@ importers: version: 7.0.1(eslint@9.39.2(jiti@2.6.1)) globals: specifier: 'catalog:' - version: 17.0.0 + version: 17.4.0 typescript: specifier: 'catalog:' version: 5.9.3 typescript-eslint: specifier: 'catalog:' - version: 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + version: 8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) tools/gha-scripts: devDependencies: '@effect/cli': specifier: 'catalog:' - version: 0.73.0(@effect/platform@0.94.1(effect@3.19.14))(@effect/printer-ansi@0.47.0(@effect/typeclass@0.38.0(effect@3.19.14))(effect@3.19.14))(@effect/printer@0.47.0(@effect/typeclass@0.38.0(effect@3.19.14))(effect@3.19.14))(effect@3.19.14) + version: 0.73.2(@effect/platform@0.94.5(effect@3.19.19))(@effect/printer-ansi@0.47.0(@effect/typeclass@0.38.0(effect@3.19.19))(effect@3.19.19))(@effect/printer@0.47.0(@effect/typeclass@0.38.0(effect@3.19.19))(effect@3.19.19))(effect@3.19.19) '@effect/platform': specifier: 'catalog:' - version: 0.94.1(effect@3.19.14) + version: 0.94.5(effect@3.19.19) '@effect/platform-node': specifier: 'catalog:' - version: 0.104.0(@effect/cluster@0.56.1(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14) + version: 0.104.1(@effect/cluster@0.56.1(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19) '@octokit/auth-action': specifier: 'catalog:' version: 6.0.2 @@ -1115,13 +1122,13 @@ importers: version: link:../eslint '@types/node': specifier: 'catalog:' - version: 25.0.3 + version: 25.3.5 effect: specifier: 'catalog:' - version: 3.19.14 + version: 3.19.19 nx: specifier: 'catalog:' - version: 22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)) + version: 22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)) typescript: specifier: 'catalog:' version: 5.9.3 @@ -1130,7 +1137,7 @@ importers: dependencies: effect: specifier: 'catalog:' - version: 3.19.14 + version: 3.19.19 devDependencies: '@alloy-js/cli': specifier: 'catalog:' @@ -1143,19 +1150,19 @@ importers: version: 0.22.0 '@bufbuild/protobuf': specifier: 'catalog:' - version: 2.10.2 + version: 2.11.0 '@the-dev-tools/eslint-config': specifier: workspace:^ version: link:../eslint '@types/node': specifier: 'catalog:' - version: 25.0.3 + version: 25.3.5 '@typespec/emitter-framework': specifier: 'catalog:' - version: 0.14.0(@alloy-js/core@0.22.0)(@alloy-js/csharp@0.21.0)(@alloy-js/typescript@0.22.0)(@typespec/compiler@1.7.1(@types/node@25.0.3)) + version: 0.16.0(@alloy-js/core@0.22.0)(@alloy-js/csharp@0.21.0)(@alloy-js/python@0.3.0)(@alloy-js/typescript@0.22.0)(@typespec/compiler@1.9.0(@types/node@25.3.5)) prettier: specifier: 'catalog:' - version: 3.7.4 + version: 3.8.1 typescript: specifier: 'catalog:' version: 5.9.3 @@ -1164,56 +1171,56 @@ importers: dependencies: effect: specifier: 'catalog:' - version: 3.19.14 + version: 3.19.19 react: specifier: 'catalog:' - version: 19.2.3 + version: 19.2.4 react-dom: specifier: 'catalog:' - version: 19.2.3(react@19.2.3) + version: 19.2.4(react@19.2.4) devDependencies: '@storybook/addon-docs': specifier: 'catalog:' - version: 10.1.11(@types/react@19.2.7)(esbuild@0.27.2)(rollup@4.55.1)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2)) + version: 10.2.16(@types/react@19.2.14)(esbuild@0.27.3)(rollup@4.59.0)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3)) '@storybook/react': specifier: 'catalog:' - version: 10.1.11(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3) + version: 10.2.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) '@storybook/react-vite': specifier: 'catalog:' - version: 10.1.11(esbuild@0.27.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.55.1)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2)) + version: 10.2.16(esbuild@0.27.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.59.0)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3)) '@tailwindcss/vite': specifier: 'catalog:' - version: 4.1.18(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 4.2.1(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@the-dev-tools/eslint-config': specifier: workspace:^ version: link:../eslint '@types/node': specifier: 'catalog:' - version: 25.0.3 + version: 25.3.5 '@types/react': specifier: 'catalog:' - version: 19.2.7 + version: 19.2.14 '@types/react-dom': specifier: 'catalog:' - version: 19.2.3(@types/react@19.2.7) + version: 19.2.3(@types/react@19.2.14) '@vitejs/plugin-react': specifier: 'catalog:' - version: 5.1.2(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 5.1.4(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) babel-plugin-react-compiler: specifier: 'catalog:' version: 19.1.0-rc.3 storybook: specifier: 'catalog:' - version: 10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) tailwindcss: specifier: 'catalog:' - version: 4.1.18 + version: 4.2.1 typescript: specifier: 'catalog:' version: 5.9.3 vite: specifier: 'catalog:' - version: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + version: 7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) packages: @@ -1223,8 +1230,8 @@ packages: '@adobe/css-tools@4.4.4': resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==} - '@aikidosec/safe-chain@1.4.0': - resolution: {integrity: sha512-me+R8atYLE8zWdgmR6QDAbnYvm/zYtXvgITWDC5Oxd4n/U/FTBkOVR5dLRchyybA8g+DphsZqs4SZzn09+ff+g==} + '@aikidosec/safe-chain@1.4.4': + resolution: {integrity: sha512-yxsjN1fXQ3Iuk0J8DxpAR0D6dHuuqlf5XYUYlXbzrcZwKN6Lf1V6NyTUypct2sYNKIJRipiN/iTVIxb5y3dKlw==} hasBin: true '@alloy-js/babel-plugin-jsx-dom-expressions@0.39.1': @@ -1257,39 +1264,42 @@ packages: '@alloy-js/msbuild@0.21.0': resolution: {integrity: sha512-QmMwF7eoYMdR5mX+8cIKb5F3Mgi3uQlFYrGYq92ht6BOc/XKyBXIwCXq6zqPMAT7nd2BHDD2hvgbL6nLS4QcGg==} + '@alloy-js/python@0.3.0': + resolution: {integrity: sha512-VujQyh6aGC5oAXvmtKcDGYg3rRgU01IvN5uOu6u5m/kXR7rUTsndrv960r0bBniIL+EvRF3CMu7E6EEcbb3Pyg==} + '@alloy-js/typescript@0.22.0': resolution: {integrity: sha512-jARBNxAA5aEhysleFFd7cGfjckkEXLCH9kDaJSH5xBOu4cU0v7q5TvAqgPlEIkhfOh2983XLX0nVtZu01p0UjQ==} - '@babel/code-frame@7.27.1': - resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + '@babel/code-frame@7.28.6': + resolution: {integrity: sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==} engines: {node: '>=6.9.0'} '@babel/code-frame@7.29.0': resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.28.5': - resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} engines: {node: '>=6.9.0'} - '@babel/core@7.28.5': - resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} engines: {node: '>=6.9.0'} - '@babel/generator@7.28.5': - resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} engines: {node: '>=6.9.0'} '@babel/helper-annotate-as-pure@7.27.3': resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.27.2': - resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} engines: {node: '>=6.9.0'} - '@babel/helper-create-class-features-plugin@7.28.5': - resolution: {integrity: sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==} + '@babel/helper-create-class-features-plugin@7.28.6': + resolution: {integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1300,8 +1310,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-define-polyfill-provider@0.6.5': - resolution: {integrity: sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==} + '@babel/helper-define-polyfill-provider@0.6.6': + resolution: {integrity: sha512-mOAsxeeKkUKayvZR3HeTYD/fICpCPLJrU5ZjelT/PA6WHtNDBOE436YiaEUvHN454bRM3CebhDsIpieCc4texA==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -1317,8 +1327,12 @@ packages: resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.28.3': - resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1327,8 +1341,8 @@ packages: resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@7.27.1': - resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} engines: {node: '>=6.9.0'} '@babel/helper-remap-async-to-generator@7.27.1': @@ -1337,8 +1351,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-replace-supers@7.27.1': - resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} + '@babel/helper-replace-supers@7.28.6': + resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1359,16 +1373,16 @@ packages: resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helper-wrap-function@7.28.3': - resolution: {integrity: sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==} + '@babel/helper-wrap-function@7.28.6': + resolution: {integrity: sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.28.4': - resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} + '@babel/helpers@7.28.6': + resolution: {integrity: sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.28.5': - resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + '@babel/parser@7.29.0': + resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} engines: {node: '>=6.0.0'} hasBin: true @@ -1396,14 +1410,14 @@ packages: peerDependencies: '@babel/core': ^7.13.0 - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3': - resolution: {integrity: sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==} + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6': + resolution: {integrity: sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-proposal-decorators@7.28.0': - resolution: {integrity: sha512-zOiZqvANjWDUaUS9xMxbMcK/Zccztbe/6ikvUXaG9nsPH3w6qh5UaPGAnirI/WhIbZ8m3OHU0ReyPrknG+ZKeg==} + '@babel/plugin-proposal-decorators@7.29.0': + resolution: {integrity: sha512-CVBVv3VY/XRMxRYq5dwr2DS7/MvqPm23cOCjbwNnVrfOqcWlnefua1uUs0sjdKOGjvPUG633o07uWzJq4oI6dA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1414,32 +1428,32 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-decorators@7.27.1': - resolution: {integrity: sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==} + '@babel/plugin-syntax-decorators@7.28.6': + resolution: {integrity: sha512-71EYI0ONURHJBL4rSFXnITXqXrrY8q4P0q006DPfN+Rk+ASM+++IBXem/ruokgBZR8YNEWZ8R6B+rCb8VcUTqA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-assertions@7.27.1': - resolution: {integrity: sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==} + '@babel/plugin-syntax-import-assertions@7.28.6': + resolution: {integrity: sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-attributes@7.27.1': - resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} + '@babel/plugin-syntax-import-attributes@7.28.6': + resolution: {integrity: sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-jsx@7.27.1': - resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} + '@babel/plugin-syntax-jsx@7.28.6': + resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-typescript@7.27.1': - resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} + '@babel/plugin-syntax-typescript@7.28.6': + resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1456,14 +1470,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-generator-functions@7.28.0': - resolution: {integrity: sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==} + '@babel/plugin-transform-async-generator-functions@7.29.0': + resolution: {integrity: sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-to-generator@7.27.1': - resolution: {integrity: sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==} + '@babel/plugin-transform-async-to-generator@7.28.6': + resolution: {integrity: sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1474,32 +1488,32 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoping@7.28.5': - resolution: {integrity: sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==} + '@babel/plugin-transform-block-scoping@7.28.6': + resolution: {integrity: sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-properties@7.27.1': - resolution: {integrity: sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==} + '@babel/plugin-transform-class-properties@7.28.6': + resolution: {integrity: sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-static-block@7.28.3': - resolution: {integrity: sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==} + '@babel/plugin-transform-class-static-block@7.28.6': + resolution: {integrity: sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 - '@babel/plugin-transform-classes@7.28.4': - resolution: {integrity: sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==} + '@babel/plugin-transform-classes@7.28.6': + resolution: {integrity: sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-computed-properties@7.27.1': - resolution: {integrity: sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==} + '@babel/plugin-transform-computed-properties@7.28.6': + resolution: {integrity: sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1510,8 +1524,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-dotall-regex@7.27.1': - resolution: {integrity: sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==} + '@babel/plugin-transform-dotall-regex@7.28.6': + resolution: {integrity: sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1522,8 +1536,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1': - resolution: {integrity: sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==} + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0': + resolution: {integrity: sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1534,14 +1548,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-explicit-resource-management@7.28.0': - resolution: {integrity: sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==} + '@babel/plugin-transform-explicit-resource-management@7.28.6': + resolution: {integrity: sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-exponentiation-operator@7.28.5': - resolution: {integrity: sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==} + '@babel/plugin-transform-exponentiation-operator@7.28.6': + resolution: {integrity: sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1564,8 +1578,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-json-strings@7.27.1': - resolution: {integrity: sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==} + '@babel/plugin-transform-json-strings@7.28.6': + resolution: {integrity: sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1576,8 +1590,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-logical-assignment-operators@7.28.5': - resolution: {integrity: sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==} + '@babel/plugin-transform-logical-assignment-operators@7.28.6': + resolution: {integrity: sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1594,14 +1608,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-commonjs@7.27.1': - resolution: {integrity: sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==} + '@babel/plugin-transform-modules-commonjs@7.28.6': + resolution: {integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-systemjs@7.28.5': - resolution: {integrity: sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==} + '@babel/plugin-transform-modules-systemjs@7.29.0': + resolution: {integrity: sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1612,8 +1626,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-named-capturing-groups-regex@7.27.1': - resolution: {integrity: sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==} + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0': + resolution: {integrity: sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1624,20 +1638,20 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-nullish-coalescing-operator@7.27.1': - resolution: {integrity: sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==} + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6': + resolution: {integrity: sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-numeric-separator@7.27.1': - resolution: {integrity: sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==} + '@babel/plugin-transform-numeric-separator@7.28.6': + resolution: {integrity: sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-rest-spread@7.28.4': - resolution: {integrity: sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==} + '@babel/plugin-transform-object-rest-spread@7.28.6': + resolution: {integrity: sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1648,14 +1662,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-optional-catch-binding@7.27.1': - resolution: {integrity: sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==} + '@babel/plugin-transform-optional-catch-binding@7.28.6': + resolution: {integrity: sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-optional-chaining@7.28.5': - resolution: {integrity: sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==} + '@babel/plugin-transform-optional-chaining@7.28.6': + resolution: {integrity: sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1666,14 +1680,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-private-methods@7.27.1': - resolution: {integrity: sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==} + '@babel/plugin-transform-private-methods@7.28.6': + resolution: {integrity: sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-private-property-in-object@7.27.1': - resolution: {integrity: sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==} + '@babel/plugin-transform-private-property-in-object@7.28.6': + resolution: {integrity: sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1714,8 +1728,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx@7.27.1': - resolution: {integrity: sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==} + '@babel/plugin-transform-react-jsx@7.28.6': + resolution: {integrity: sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1726,14 +1740,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regenerator@7.28.4': - resolution: {integrity: sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==} + '@babel/plugin-transform-regenerator@7.29.0': + resolution: {integrity: sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regexp-modifiers@7.27.1': - resolution: {integrity: sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==} + '@babel/plugin-transform-regexp-modifiers@7.28.6': + resolution: {integrity: sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1744,8 +1758,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-runtime@7.28.5': - resolution: {integrity: sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w==} + '@babel/plugin-transform-runtime@7.29.0': + resolution: {integrity: sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1756,8 +1770,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-spread@7.27.1': - resolution: {integrity: sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==} + '@babel/plugin-transform-spread@7.28.6': + resolution: {integrity: sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1780,8 +1794,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.28.5': - resolution: {integrity: sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==} + '@babel/plugin-transform-typescript@7.28.6': + resolution: {integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1792,8 +1806,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-property-regex@7.27.1': - resolution: {integrity: sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==} + '@babel/plugin-transform-unicode-property-regex@7.28.6': + resolution: {integrity: sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1804,14 +1818,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-sets-regex@7.27.1': - resolution: {integrity: sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==} + '@babel/plugin-transform-unicode-sets-regex@7.28.6': + resolution: {integrity: sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/preset-env@7.28.5': - resolution: {integrity: sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg==} + '@babel/preset-env@7.29.0': + resolution: {integrity: sha512-fNEdfc0yi16lt6IZo2Qxk3knHVdfMYX33czNb4v8yWhemoBhibCpQK/uYHtSKIiO+p/zd3+8fYVXhQdOVV608w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1833,28 +1847,28 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/runtime@7.28.4': - resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} + '@babel/runtime@7.28.6': + resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} engines: {node: '>=6.9.0'} - '@babel/template@7.27.2': - resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.28.5': - resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.5': - resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} - '@better-auth/cli@1.4.18': - resolution: {integrity: sha512-T7koP/fNpP0+hZ3INNj+A2bx2B/6783XPE8xKjldndmdhG3orJZFkzKWzlXPJYh1jX56tFOfcvDMNErzE40LjQ==} + '@better-auth/cli@1.4.21': + resolution: {integrity: sha512-bKEa8BupnZxNjLk9ZDntvgQGm5jogeE2wHdMbYifhet3GTyxgDi6pXoOK8+aqHYQGg1C3OALi9hVVWnrv7JJWQ==} hasBin: true - '@better-auth/core@1.4.18': - resolution: {integrity: sha512-q+awYgC7nkLEBdx2sW0iJjkzgSHlIxGnOpsN1r/O1+a4m7osJNHtfK2mKJSL1I+GfNyIlxJF8WvD/NLuYMpmcg==} + '@better-auth/core@1.4.21': + resolution: {integrity: sha512-R4s7pwShkqB21fZ599QASbXxqFcoxanLyz7DHSX6SJPNYV748wBLsm3xM9VrjfvWMpS+cQUErOCt9yWT1hMn6w==} peerDependencies: '@better-auth/utils': 0.3.0 '@better-fetch/fetch': 1.1.21 @@ -1863,92 +1877,149 @@ packages: kysely: ^0.28.5 nanostores: ^1.0.1 - '@better-auth/telemetry@1.4.18': - resolution: {integrity: sha512-e5rDF8S4j3Um/0LIVATL2in9dL4lfO2fr2v1Wio4qTMRbfxqnUDTa+6SZtwdeJrbc4O+a3c+IyIpjG9Q/6GpfQ==} + '@better-auth/core@1.5.4': + resolution: {integrity: sha512-k5AdwPRQETZn0vdB60EB9CDxxfllpJXKqVxTjyXIUSRz7delNGlU0cR/iRP3VfVJwvYR1NbekphBDNo+KGoEzQ==} + peerDependencies: + '@better-auth/utils': 0.3.1 + '@better-fetch/fetch': 1.1.21 + '@cloudflare/workers-types': '>=4' + better-call: 1.3.2 + jose: ^6.1.0 + kysely: ^0.28.5 + nanostores: ^1.0.1 + peerDependenciesMeta: + '@cloudflare/workers-types': + optional: true + + '@better-auth/drizzle-adapter@1.5.4': + resolution: {integrity: sha512-4M4nMAWrDd3TmpV6dONkJjybBVKRZghe5Oj0NNyDEoXubxastQdO7Sb5B54I1rTx5yoMgsqaB+kbJnu/9UgjQg==} peerDependencies: - '@better-auth/core': 1.4.18 + '@better-auth/core': 1.5.4 + '@better-auth/utils': ^0.3.0 + drizzle-orm: '>=0.41.0' + + '@better-auth/kysely-adapter@1.5.4': + resolution: {integrity: sha512-DPww7rIfz6Ed7dZlJSW9xMQ42VKaJLB5Cs+pPqd+UHKRyighKjf3VgvMIcAdFPc4olQ0qRHo3+ZJhFlBCxRhxA==} + peerDependencies: + '@better-auth/core': 1.5.4 + '@better-auth/utils': ^0.3.0 + kysely: ^0.27.0 || ^0.28.0 + + '@better-auth/memory-adapter@1.5.4': + resolution: {integrity: sha512-iiWYut9rbQqiAsgRBtj6+nxanwjapxRgpIJbiS2o81h7b9iclE0AiDA0Foes590gdFQvskNauZcCpuF8ytxthg==} + peerDependencies: + '@better-auth/core': 1.5.4 + '@better-auth/utils': ^0.3.0 + + '@better-auth/mongo-adapter@1.5.4': + resolution: {integrity: sha512-ArzJN5Obk6i6+vLK1HpPzLIcsjxZYXPPUvxVU8eyU5HyoUT2MlswWfPQ8UJAKPn0iq/T4PVp/wZcQMhWk1tuNA==} + peerDependencies: + '@better-auth/core': 1.5.4 + '@better-auth/utils': ^0.3.0 + mongodb: ^6.0.0 || ^7.0.0 + + '@better-auth/prisma-adapter@1.5.4': + resolution: {integrity: sha512-ZQTbcBopw/ezjjbNFsfR3CRp0QciC4tJCarAnB5G9fZtUYbDjfY0vZOxIRmU4kI3x755CXQpGqTrkwmXaMRa3w==} + peerDependencies: + '@better-auth/core': 1.5.4 + '@better-auth/utils': ^0.3.0 + '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0 + prisma: ^5.0.0 || ^6.0.0 || ^7.0.0 + + '@better-auth/telemetry@1.4.21': + resolution: {integrity: sha512-LX+FGMZnhR2KQZ0idHH1+UwlXvkOl6P8w3Gne4TtjvUCt3QjG9FKIuP9JD3MAmEEkwGt0SoAPHPJEGTjUl3ydg==} + peerDependencies: + '@better-auth/core': 1.4.21 + + '@better-auth/telemetry@1.5.4': + resolution: {integrity: sha512-mGXTY7Ecxo7uvlMr6TFCBUvlH0NUMOeE9LKgPhG4HyhBN6VfCEg/DD9PG0Z2IatmMWQbckkt7ox5A0eBpG9m5w==} + peerDependencies: + '@better-auth/core': 1.5.4 '@better-auth/utils@0.3.0': resolution: {integrity: sha512-W+Adw6ZA6mgvnSnhOki270rwJ42t4XzSK6YWGF//BbVXL6SwCLWfyzBc1lN2m/4RM28KubdBKQ4X5VMoLRNPQw==} + '@better-auth/utils@0.3.1': + resolution: {integrity: sha512-+CGp4UmZSUrHHnpHhLPYu6cV+wSUSvVbZbNykxhUDocpVNTo9uFFxw/NqJlh1iC4wQ9HKKWGCKuZ5wUgS0v6Kg==} + '@better-fetch/fetch@1.1.21': resolution: {integrity: sha512-/ImESw0sskqlVR94jB+5+Pxjf+xBwDZF/N5+y2/q4EqD7IARUTSpPfIo8uf39SYpCxyOCtbyYpUrZ3F/k0zT4A==} - '@bufbuild/buf-darwin-arm64@1.63.0': - resolution: {integrity: sha512-Jpbz2mnNO+23E3TmDgLdbYuF+ozqsKu/ASvD37RjDgp9HtqQT+ciJMYOzqd/HdrGiM9tWYN1vhjl/gP/Y23lIw==} + '@bufbuild/buf-darwin-arm64@1.66.0': + resolution: {integrity: sha512-C9orXX4SSVYKEumWFEO2T6xKrXsrvij0uS8kR20sHt9MYuFke14y6DfnAvXINPZrNpDiyOTldG7BPQtR40poRw==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] - '@bufbuild/buf-darwin-x64@1.63.0': - resolution: {integrity: sha512-HkVMm2cOBnTtT+AZFAQAUyrwcXtnvaBtVCW0ltBi5PzLp6CNgmkH97OAROKWiNPWrXJh5thdhdZBNjGPyTfX3w==} + '@bufbuild/buf-darwin-x64@1.66.0': + resolution: {integrity: sha512-5I33S9UbimoBNCpOdMsmJHcW9NfxzKW5PsVrSyajpo+LL22Lfyha2ZO3JNhT/k3ZlGVvtpDAS9pRS0ouNKmGgA==} engines: {node: '>=12'} cpu: [x64] os: [darwin] - '@bufbuild/buf-linux-aarch64@1.63.0': - resolution: {integrity: sha512-vFeFKzC+PZSngct0bP3ASGCus7qhBPFxSfz6Hi+3a2zAajn857iJC3iPiX0tRlRIUTOHuj5NmOYxg9dhev0vDw==} + '@bufbuild/buf-linux-aarch64@1.66.0': + resolution: {integrity: sha512-KFz9HukP3ACKfSe0fo+XbxndQR0kKCVLVfUkoc6qPUTrKn9lACnah6HlUtBlwanK95vg+MIMvy0DWoLYUX9cuA==} engines: {node: '>=12'} cpu: [arm64] os: [linux] - '@bufbuild/buf-linux-armv7@1.63.0': - resolution: {integrity: sha512-XbrRiOfeY3d/GmR+WNnkcDo480V+cz/ecfj/Ay/JO/ZLe7quEQqHmJ6dMcIQN8QNFPZBKv0IVyhhljh8+0/gkA==} + '@bufbuild/buf-linux-armv7@1.66.0': + resolution: {integrity: sha512-W56iEZtnqB4ww9JCyhIipPrwZVe/zQ5I0pmWrJF8Daw67qvRYtvP3NSxtF5f0yAoB0tQAXDoqIiB/Ypl1UOz0g==} engines: {node: '>=12'} cpu: [arm] os: [linux] - '@bufbuild/buf-linux-x64@1.63.0': - resolution: {integrity: sha512-78TsMWxQ7Rn4FJPN4QZZDM3NTS1U5ZCcwLYJmwOLJbHyfYnFiC1e91yL6sVfYrWXF1Pt9xJZU50yhmJZ+9AtmA==} + '@bufbuild/buf-linux-x64@1.66.0': + resolution: {integrity: sha512-6AYYyc2O32jnDjjHbyW9Oqcehd+PMw+34qVo+wGfaEgGwC+fyoL2oxcEmzsPyEvhY4mkYJRXaCb8p90Ndzd2vQ==} engines: {node: '>=12'} cpu: [x64] os: [linux] - '@bufbuild/buf-win32-arm64@1.63.0': - resolution: {integrity: sha512-sMZ63kK+MuxZVBFAh95Woly9QmeApohgQoWvO9ZppTzNXya7Kznz5lqa0B7f3zfDxgy2/DmOXILOMn3n8GoAww==} + '@bufbuild/buf-win32-arm64@1.66.0': + resolution: {integrity: sha512-S+CD5NZ6q0HCI0g0PTVypjSQ63LsLm1Svd7yG1MjKz9mQ83Vl6rYXuzmYYVi2cww7w5tDew8sYASZETewvEuxg==} engines: {node: '>=12'} cpu: [arm64] os: [win32] - '@bufbuild/buf-win32-x64@1.63.0': - resolution: {integrity: sha512-ooY4o3XPpvJ6BEOWB18pc52beeB9NdRRHMINuZ1oef3HNsFqtbv7DrPX9vm/mmOkzbTQDa8m7M8bjWjBO9ynkg==} + '@bufbuild/buf-win32-x64@1.66.0': + resolution: {integrity: sha512-uSPoWRaX8Qd5pHZt6zzRuZXr4Sdbqe4Pm1PmMax/SGUPacVpH1v9AGX1/BTgx+g+b4vLS5T4SGxTl9ngkQaY3Q==} engines: {node: '>=12'} cpu: [x64] os: [win32] - '@bufbuild/buf@1.63.0': - resolution: {integrity: sha512-SvYWiCs9J8tX8qIh1haNJEwM0MmyauSFDDksHL4wtPjeXcEj+SMvWudIn8KdWoiFbNDY98phn4sqZQ4F6uViPQ==} + '@bufbuild/buf@1.66.0': + resolution: {integrity: sha512-JSZT6OT8uKG2frScYNOS3Y4E+7wg1KSPQMKfLlbZZFnBoXwMqDdsxQF7O5ucameU+3DKRs+yQFI8tNQjFJ5T2g==} engines: {node: '>=12'} hasBin: true - '@bufbuild/cel-spec@0.3.0': - resolution: {integrity: sha512-mN669LGlXkYNco6NzSTpFoW52UwGb0h5UJNct43nkOjk9YrgUtzcBn9PfjrwbyAe3OlUtasvXAFf1Tjs3NQLOg==} + '@bufbuild/cel-spec@0.4.0': + resolution: {integrity: sha512-dUS6f2fNt6KEumsYGE7YFxERZE5ZuyME1hQmGjtO8tkZhR6ow6/ne3v4Gik9cfdb9lSLK3AJ+vDxCdGWmDbWvA==} peerDependencies: '@bufbuild/protobuf': ^2.6.2 - '@bufbuild/cel@0.3.0': - resolution: {integrity: sha512-vIdcn0Ot6XDKakcDqEQvvlCtMlYwLlxc++SrVjjCmYIiZRH+tlr1GRYpe5R9kguSiTS3BLh7C+I7ZoektVPICQ==} + '@bufbuild/cel@0.4.0': + resolution: {integrity: sha512-CdW/JgiTJCYXqnwuaJRo7NcoYhR37AaF58MMiog0/t8nudn86ZyLXYaA1f2yGhm2U17h8pKGZNksTHVSTcpmAw==} peerDependencies: '@bufbuild/protobuf': ^2.6.2 - '@bufbuild/protobuf@2.10.2': - resolution: {integrity: sha512-uFsRXwIGyu+r6AMdz+XijIIZJYpoWeYzILt5yZ2d3mCjQrWUTVpVD9WL/jZAbvp+Ed04rOhrsk7FiTcEDseB5A==} + '@bufbuild/protobuf@2.11.0': + resolution: {integrity: sha512-sBXGT13cpmPR5BMgHE6UEEfEaShh5Ror6rfN3yEK5si7QVrtZg8LEPQb0VVhiLRUslD2yLnXtnRzG035J/mZXQ==} - '@bufbuild/protoc-gen-es@2.10.2': - resolution: {integrity: sha512-vbjPsuofbtZwZXuOP7Y16CQsxrwCjuRONffmJSBEhoC7PQu/Cabp0+Fu/poLPm9CNM0tDCQA0xvgobgudaEYxQ==} + '@bufbuild/protoc-gen-es@2.11.0': + resolution: {integrity: sha512-VzQuwEQDXipbZ1soWUuAWm1Z0C3B/IDWGeysnbX6ogJ6As91C2mdvAND/ekQ4YIWgen4d5nqLfIBOWLqCCjYUA==} engines: {node: '>=20'} hasBin: true peerDependencies: - '@bufbuild/protobuf': 2.10.2 + '@bufbuild/protobuf': 2.11.0 peerDependenciesMeta: '@bufbuild/protobuf': optional: true - '@bufbuild/protoplugin@2.10.2': - resolution: {integrity: sha512-RAWVs9tCzRqSS3tUtaFhOcauOAazCrm7tlGh0WHFq/44n5Fj6YgefdlZEPIaAK6VAA+FdOoFgtOJK2Ji5U24pw==} + '@bufbuild/protoplugin@2.11.0': + resolution: {integrity: sha512-lyZVNFUHArIOt4W0+dwYBe5GBwbKzbOy8ObaloEqsw9Mmiwv2O48TwddDoHN4itylC+BaEGqFdI1W8WQt2vWJQ==} - '@bufbuild/protovalidate@1.1.0': - resolution: {integrity: sha512-oC1sYAr9eQucZsLb0M7cIk3TftZ/cOBbKT1XBIL9Aypm5e0IcC8/HlfN+NrwPVhw9JI4bOQM1Ar1E6x7L71nbA==} + '@bufbuild/protovalidate@1.1.1': + resolution: {integrity: sha512-sE6CojU25nfeb1w88Sm+jRnmk4GvQTeEZvLDHHDPvIHbj2NsDJWFAUJdJr+RcuMnjdWmbur+rAS38VuEK/XviQ==} peerDependencies: '@bufbuild/protobuf': ^2.8.0 @@ -1964,18 +2035,12 @@ packages: '@chevrotain/utils@10.5.0': resolution: {integrity: sha512-hBzuU5+JjB2cqNZyszkDHZgOSrUUT8V3dhgRl8Q9Gp6dAj/H5+KILGjbhDpc3Iy9qmqlm/akuOI2ut9VUtzJxQ==} - '@clack/core@0.3.5': - resolution: {integrity: sha512-5cfhQNH+1VQ2xLQlmzXMqUoiaH0lRBq9/CLW9lTyMbuKLC3+xEK01tHVvyut++mLOn5urSHmkm6I0Lg9MaJSTQ==} - '@clack/core@0.5.0': resolution: {integrity: sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==} '@clack/prompts@0.11.0': resolution: {integrity: sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==} - '@clack/prompts@0.8.2': - resolution: {integrity: sha512-6b9Ab2UiZwJYA9iMyboYyW9yJvAO9V753ZhS+DHKEjZRKAxPPOb7MXXu84lsPFG+vZt6FRFniZ8rXi+zCIw4yQ==} - '@codemirror/autocomplete@6.20.0': resolution: {integrity: sha512-bOwvTOIJcG5FVo5gUUupiwYh8MioPLQ4UcqbcRf7UQ98X90tCa9E1kZ3Z7tqwpZxYyOvh1YTYbmZE9RTfTp5hg==} @@ -1988,8 +2053,8 @@ packages: '@codemirror/lang-html@6.4.11': resolution: {integrity: sha512-9NsXp7Nwp891pQchI7gPdTwBuSuT3K65NGTHWHNJ55HjYcHLllr0rbIZNdOzas9ztc1EUVBlHou85FFZS4BNnw==} - '@codemirror/lang-javascript@6.2.4': - resolution: {integrity: sha512-0WVmhp1QOqZ4Rt6GlVGwKJN3KW7Xh4H2q8ZZNGZaP6lRdxXJzmjm4FqvmOojVj6khWJHIb9sp7U/72W7xQgqAA==} + '@codemirror/lang-javascript@6.2.5': + resolution: {integrity: sha512-zD4e5mS+50htS7F+TYjBPsiIFGanfVqg4HyUz6WNFikgOPf2BgKlx+TQedI1w6n/IqRBVBbBWmGFdLB/7uxO4A==} '@codemirror/lang-json@6.0.2': resolution: {integrity: sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ==} @@ -2000,8 +2065,8 @@ packages: '@codemirror/language@6.12.1': resolution: {integrity: sha512-Fa6xkSiuGKc8XC8Cn96T+TQHYj4ZZ7RdFmXA3i9xe/3hLHfwPZdM+dqfX0Cp0zQklBKhVD8Yzc8LS45rkqcwpQ==} - '@codemirror/lint@6.9.2': - resolution: {integrity: sha512-sv3DylBiIyi+xKwRCJAAsBZZZWo82shJ/RTMymLabAdtbkV5cSKwWDeCgtUq3v8flTaXS2y1kKkICuRYtUswyQ==} + '@codemirror/lint@6.9.5': + resolution: {integrity: sha512-GElsbU9G7QT9xXhpUg1zWGmftA/7jamh+7+ydKRuT0ORpWS3wOSP0yT1FOlIZa7mIJjpVPipErsyvVqB9cfTFA==} '@codemirror/search@6.5.11': resolution: {integrity: sha512-KmWepDE6jUdL6n8cAAqIpRmLPBZ5ZKnicE8oGU/s3QrAVID+0VhLFrzUucVKHG5035/BSykhExDL/Xm7dHthiA==} @@ -2061,28 +2126,28 @@ packages: resolution: {integrity: sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==} engines: {node: '>= 8.9.0'} - '@effect-atom/atom-react@0.4.4': - resolution: {integrity: sha512-EWT9WpB67GNCecxQXJdAZNVMhuk3VxpdDfojxg1wOgWmR5TPaGiXA74Jqa2Y9AEjSB0hMMAk7RNve2CoIikg2w==} + '@effect-atom/atom-react@0.5.0': + resolution: {integrity: sha512-aFfjWi4rEJCqfM12Oi36/EKaDm/W6n4/N6yM5vL0t/QozKhJhK05rQL/GY4XMxlH2eqkQ4ih8jBQa3Yyp0Fiqw==} peerDependencies: effect: ^3.19 react: '>=18 <20' scheduler: '*' - '@effect-atom/atom@0.4.11': - resolution: {integrity: sha512-bahWNw2xQ349HXkqshpls/t4wUu5fbMfjT6/7FhDj1uPjP9BArUAwL1Js5b7EG0ZPonS+G1O9LftpxVWAxr86g==} + '@effect-atom/atom@0.5.3': + resolution: {integrity: sha512-TRZv/i+YT3TtnN0oFORJqXdxSs1fc7lrJlH+1xZvDFyjC9hgoVnrcKbeZsDFmr6r0wYRqVo7U3IftxiQNjpNZA==} peerDependencies: - '@effect/experimental': ^0.57.0 - '@effect/platform': ^0.93.0 - '@effect/rpc': ^0.72.1 - effect: ^3.19.0 + '@effect/experimental': ^0.58.0 + '@effect/platform': ^0.94.2 + '@effect/rpc': ^0.73.0 + effect: ^3.19.15 - '@effect/cli@0.73.0': - resolution: {integrity: sha512-KkRtFjfyG52kQ6Z3ZEjwytfKZQACsLzn/RI2jKKxMJDebY9BQganOiE3VGCT4slU3Zisur6SP//ghM0vCLQs4g==} + '@effect/cli@0.73.2': + resolution: {integrity: sha512-K8IJo81+qa1LU8dhxcDU4QO/bIjL/dPd3zUOSCpLiuUNz8Y3/T+WNs3GqIXEhMfCFMSlRZERN0YgmtRlEZUREA==} peerDependencies: - '@effect/platform': ^0.94.0 + '@effect/platform': ^0.94.3 '@effect/printer': ^0.47.0 '@effect/printer-ansi': ^0.47.0 - effect: ^3.19.13 + effect: ^3.19.16 '@effect/cluster@0.56.1': resolution: {integrity: sha512-gnrsH6kfrUjn+82j/bw1IR4yFqJqV8tc7xZvrbJPRgzANycc6K1hu3LMg548uYbUkTzD8YYyqrSatMO1mkQpzw==} @@ -2112,28 +2177,28 @@ packages: '@effect/platform': ^0.94.0 effect: ^3.19.13 - '@effect/platform-node-shared@0.57.0': - resolution: {integrity: sha512-QXuvmLNlABCQLcTl+lN1YPhKosR6KqArPYjC2reU0fb5lroCo3YRb/aGpXIgLthHzQL8cLU5XMGA3Cu5hKY2Tw==} + '@effect/platform-node-shared@0.57.1': + resolution: {integrity: sha512-oX/bApMdoKsyrDiNdJxo7U9Rz1RXsjRv+ecfAPp1qGlSdGIo32wVRvJ2XCHqYj0sqaYJS0pU0/GCulRfVGuJag==} peerDependencies: - '@effect/cluster': ^0.56.0 - '@effect/platform': ^0.94.0 + '@effect/cluster': ^0.56.1 + '@effect/platform': ^0.94.2 '@effect/rpc': ^0.73.0 '@effect/sql': ^0.49.0 - effect: ^3.19.13 + effect: ^3.19.15 - '@effect/platform-node@0.104.0': - resolution: {integrity: sha512-2ZkUDDTxLD95ARdYIKBx4tdIIgqA3cwb3jlnVVBxmHUf0Pg5N2HdMuD0Q+CXQ7Q94FDwnLW3ZvaSfxDh6FvrNw==} + '@effect/platform-node@0.104.1': + resolution: {integrity: sha512-jT1a/z98niK6fnEU8pWHPPCdJMVDRCIdB65lolcOjse5rsTwVbczMjvKkhVQpF63mNWoOnol7OTRNkw5L54llg==} peerDependencies: - '@effect/cluster': ^0.56.0 - '@effect/platform': ^0.94.0 + '@effect/cluster': ^0.56.1 + '@effect/platform': ^0.94.2 '@effect/rpc': ^0.73.0 '@effect/sql': ^0.49.0 - effect: ^3.19.13 + effect: ^3.19.15 - '@effect/platform@0.94.1': - resolution: {integrity: sha512-SlL8OMTogHmMNnFLnPAHHo3ua1yrB1LNQOVQMiZsqYu9g3216xjr0gn5WoDgCxUyOdZcseegMjWJ7dhm/2vnfg==} + '@effect/platform@0.94.5': + resolution: {integrity: sha512-z05APUiDDPbodhTkH/RJqOLoCU11bU2IZLfcwLFrld03+ob1VeqRnELQlmueLIYm6NZifHAtjl32V+GRt34y4A==} peerDependencies: - effect: ^3.19.14 + effect: ^3.19.17 '@effect/printer-ansi@0.47.0': resolution: {integrity: sha512-tDEQ9XJpXDNYoWMQJHFRMxKGmEOu6z32x3Kb8YLOV5nkauEKnKmWNs7NBp8iio/pqoJbaSwqDwUg9jXVquxfWQ==} @@ -2173,6 +2238,20 @@ packages: '@effect/rpc': ^0.73.0 effect: ^3.19.13 + '@electric-sql/pglite-socket@0.0.20': + resolution: {integrity: sha512-J5nLGsicnD9wJHnno9r+DGxfcZWh+YJMCe0q/aCgtG6XOm9Z7fKeite8IZSNXgZeGltSigM9U/vAWZQWdgcSFg==} + hasBin: true + peerDependencies: + '@electric-sql/pglite': 0.3.15 + + '@electric-sql/pglite-tools@0.2.20': + resolution: {integrity: sha512-BK50ZnYa3IG7ztXhtgYf0Q7zijV32Iw1cYS8C+ThdQlwx12V5VZ9KRJ42y82Hyb4PkTxZQklVQA9JHyUlex33A==} + peerDependencies: + '@electric-sql/pglite': 0.3.15 + + '@electric-sql/pglite@0.3.15': + resolution: {integrity: sha512-Cj++n1Mekf9ETfdc16TlDi+cDDQF0W7EcbyRHYOAeZdsAe8M/FJg18itDTSwyHfar2WIezawM9o0EKaRGVKygQ==} + '@electron/asar@3.4.1': resolution: {integrity: sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA==} engines: {node: '>=10.12.0'} @@ -2186,6 +2265,10 @@ packages: resolution: {integrity: sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==} engines: {node: '>=12'} + '@electron/get@3.1.0': + resolution: {integrity: sha512-F+nKc0xW+kVbBRhFzaMgPy3KwmuNTYX1fx6+FxxoSnNgwYX6LD7AKBTWkU0MQ6IBoe7dz069CNkR673sPAgkCQ==} + engines: {node: '>=14'} + '@electron/notarize@2.5.0': resolution: {integrity: sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A==} engines: {node: '>= 10.0.0'} @@ -2200,6 +2283,11 @@ packages: engines: {node: '>=22.12.0'} hasBin: true + '@electron/rebuild@4.0.3': + resolution: {integrity: sha512-u9vpTHRMkOYCs/1FLiSVAFZ7FbjsXK+bQuzviJZa+lG7BHZl1nz52/IcGvwa3sk80/fc3llutBkbCq10Vh8WQA==} + engines: {node: '>=22.12.0'} + hasBin: true + '@electron/universal@2.0.3': resolution: {integrity: sha512-Wn9sPYIVFRFl5HmwMJkARCCf7rqK/EurkfQ/rJZ14mHP3iYTjZSIOSVonEAnhWeAXwtw7zOekGRlc6yTtZ0t+g==} engines: {node: '>=16.4'} @@ -2278,8 +2366,8 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.27.2': - resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} + '@esbuild/aix-ppc64@0.27.3': + resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] @@ -2290,8 +2378,8 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.27.2': - resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} + '@esbuild/android-arm64@0.27.3': + resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==} engines: {node: '>=18'} cpu: [arm64] os: [android] @@ -2302,8 +2390,8 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.27.2': - resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} + '@esbuild/android-arm@0.27.3': + resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==} engines: {node: '>=18'} cpu: [arm] os: [android] @@ -2314,8 +2402,8 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.27.2': - resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} + '@esbuild/android-x64@0.27.3': + resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==} engines: {node: '>=18'} cpu: [x64] os: [android] @@ -2326,8 +2414,8 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.27.2': - resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} + '@esbuild/darwin-arm64@0.27.3': + resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] @@ -2338,8 +2426,8 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.27.2': - resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} + '@esbuild/darwin-x64@0.27.3': + resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==} engines: {node: '>=18'} cpu: [x64] os: [darwin] @@ -2350,8 +2438,8 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.27.2': - resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} + '@esbuild/freebsd-arm64@0.27.3': + resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] @@ -2362,8 +2450,8 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.27.2': - resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} + '@esbuild/freebsd-x64@0.27.3': + resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] @@ -2374,8 +2462,8 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.27.2': - resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} + '@esbuild/linux-arm64@0.27.3': + resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==} engines: {node: '>=18'} cpu: [arm64] os: [linux] @@ -2386,8 +2474,8 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.27.2': - resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} + '@esbuild/linux-arm@0.27.3': + resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==} engines: {node: '>=18'} cpu: [arm] os: [linux] @@ -2398,8 +2486,8 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.27.2': - resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} + '@esbuild/linux-ia32@0.27.3': + resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==} engines: {node: '>=18'} cpu: [ia32] os: [linux] @@ -2410,8 +2498,8 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.27.2': - resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} + '@esbuild/linux-loong64@0.27.3': + resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==} engines: {node: '>=18'} cpu: [loong64] os: [linux] @@ -2422,8 +2510,8 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.27.2': - resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} + '@esbuild/linux-mips64el@0.27.3': + resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] @@ -2434,8 +2522,8 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.27.2': - resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} + '@esbuild/linux-ppc64@0.27.3': + resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] @@ -2446,8 +2534,8 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.27.2': - resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} + '@esbuild/linux-riscv64@0.27.3': + resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] @@ -2458,8 +2546,8 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.27.2': - resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} + '@esbuild/linux-s390x@0.27.3': + resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] @@ -2470,8 +2558,8 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.27.2': - resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} + '@esbuild/linux-x64@0.27.3': + resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==} engines: {node: '>=18'} cpu: [x64] os: [linux] @@ -2482,8 +2570,8 @@ packages: cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-arm64@0.27.2': - resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} + '@esbuild/netbsd-arm64@0.27.3': + resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] @@ -2494,8 +2582,8 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.27.2': - resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} + '@esbuild/netbsd-x64@0.27.3': + resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] @@ -2506,8 +2594,8 @@ packages: cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-arm64@0.27.2': - resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} + '@esbuild/openbsd-arm64@0.27.3': + resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] @@ -2518,8 +2606,8 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.27.2': - resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} + '@esbuild/openbsd-x64@0.27.3': + resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] @@ -2530,8 +2618,8 @@ packages: cpu: [arm64] os: [openharmony] - '@esbuild/openharmony-arm64@0.27.2': - resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} + '@esbuild/openharmony-arm64@0.27.3': + resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] @@ -2542,8 +2630,8 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.27.2': - resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} + '@esbuild/sunos-x64@0.27.3': + resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] @@ -2554,8 +2642,8 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.27.2': - resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} + '@esbuild/win32-arm64@0.27.3': + resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] @@ -2566,8 +2654,8 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.27.2': - resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} + '@esbuild/win32-ia32@0.27.3': + resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==} engines: {node: '>=18'} cpu: [ia32] os: [win32] @@ -2578,8 +2666,8 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.27.2': - resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} + '@esbuild/win32-x64@0.27.3': + resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -2594,11 +2682,11 @@ packages: resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/compat@2.0.0': - resolution: {integrity: sha512-T9AfE1G1uv4wwq94ozgTGio5EUQBqAVe1X9qsQtSNVEYW6j3hvtZVm8Smr4qL1qDPFg+lOB2cL5RxTRMzq4CTA==} + '@eslint/compat@2.0.2': + resolution: {integrity: sha512-pR1DoD0h3HfF675QZx0xsyrsU8q70Z/plx7880NOhS02NuWLgBCOMDL787nUeQ7EWLkxv3bPQJaarjcPQb2Dwg==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} peerDependencies: - eslint: ^8.40 || 9 + eslint: ^8.40 || 9 || 10 peerDependenciesMeta: eslint: optional: true @@ -2615,16 +2703,16 @@ packages: resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@1.0.0': - resolution: {integrity: sha512-PRfWP+8FOldvbApr6xL7mNCw4cJcSTq4GA7tYbgq15mRb0kWKO/wEB2jr+uwjFH3sZvEZneZyCUGTxsv4Sahyw==} + '@eslint/core@1.1.0': + resolution: {integrity: sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/css-tree@3.6.8': - resolution: {integrity: sha512-s0f40zY7dlMp8i0Jf0u6l/aSswS0WRAgkhgETgiCJRcxIWb4S/Sp9uScKHWbkM3BnoFLbJbmOYk5AZUDFVxaLA==} + '@eslint/css-tree@3.6.9': + resolution: {integrity: sha512-3D5/OHibNEGk+wKwNwMbz63NMf367EoR4mVNNpxddCHKEb2Nez7z62J2U6YjtErSsZDoY0CsccmoUpdEbkogNA==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} - '@eslint/eslintrc@3.3.3': - resolution: {integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==} + '@eslint/eslintrc@3.3.4': + resolution: {integrity: sha512-4h4MVF8pmBsncB60r0wSJiIeUKTSD4m7FmTFThG8RHlsg9ajqckLm9OraguFGZE4vVdpiI1Q4+hFnisopmG6gQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/js@9.39.2': @@ -2639,8 +2727,8 @@ packages: resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@faker-js/faker@10.2.0': - resolution: {integrity: sha512-rTXwAsIxpCqzUnZvrxVh3L0QA0NzToqWBLAhV+zDV3MIIwiQhAZHMdPCIaj5n/yADu/tyk12wIPgL6YHGXJP+g==} + '@faker-js/faker@10.3.0': + resolution: {integrity: sha512-It0Sne6P3szg7JIi6CgKbvTZoMjxBZhcv91ZrqrNuaZQfB5WoqYYbzCUOq89YR+VY8juY9M1vDWmDDa2TzfXCw==} engines: {node: ^20.19.0 || ^22.13.0 || ^23.5.0 || >=24.0.0, npm: '>=10'} '@fontsource-variable/dm-sans@5.2.8': @@ -2664,6 +2752,12 @@ packages: '@formatjs/intl-localematcher@0.6.2': resolution: {integrity: sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA==} + '@hono/node-server@1.19.9': + resolution: {integrity: sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==} + engines: {node: '>=18.14.1'} + peerDependencies: + hono: ^4 + '@hookform/devtools@4.4.0': resolution: {integrity: sha512-Mtlic+uigoYBPXlfvPBfiYYUZuyMrD3pTjDpVIhL6eCZTvQkHsKBSKeZCvXWUZr8fqrkzDg27N+ZuazLKq6Vmg==} peerDependencies: @@ -2691,12 +2785,12 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} - '@inquirer/ansi@2.0.2': - resolution: {integrity: sha512-SYLX05PwJVnW+WVegZt1T4Ip1qba1ik+pNJPDiqvk6zS5Y/i8PhRzLpGEtVd7sW0G8cMtkD8t4AZYhQwm8vnww==} + '@inquirer/ansi@2.0.3': + resolution: {integrity: sha512-g44zhR3NIKVs0zUesa4iMzExmZpLUdTLRMCStqX3GE5NT6VkPcxQGJ+uC8tDgBUC/vB1rUhUd55cOf++4NZcmw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - '@inquirer/checkbox@5.0.3': - resolution: {integrity: sha512-xtQP2eXMFlOcAhZ4ReKP2KZvDIBb1AnCfZ81wWXG3DXLVH0f0g4obE0XDPH+ukAEMRcZT0kdX2AS1jrWGXbpxw==} + '@inquirer/checkbox@5.1.0': + resolution: {integrity: sha512-/HjF1LN0a1h4/OFsbGKHNDtWICFU/dqXCdym719HFTyJo9IG7Otr+ziGWc9S0iQuohRZllh+WprSgd5UW5Fw0g==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2704,8 +2798,8 @@ packages: '@types/node': optional: true - '@inquirer/confirm@6.0.3': - resolution: {integrity: sha512-lyEvibDFL+NA5R4xl8FUmNhmu81B+LDL9L/MpKkZlQDJZXzG8InxiqYxiAlQYa9cqLLhYqKLQwZqXmSTqCLjyw==} + '@inquirer/confirm@6.0.8': + resolution: {integrity: sha512-Di6dgmiZ9xCSUxWUReWTqDtbhXCuG2MQm2xmgSAIruzQzBqNf49b8E07/vbCYY506kDe8BiwJbegXweG8M1klw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2713,8 +2807,8 @@ packages: '@types/node': optional: true - '@inquirer/core@11.1.0': - resolution: {integrity: sha512-+jD/34T1pK8M5QmZD/ENhOfXdl9Zr+BrQAUc5h2anWgi7gggRq15ZbiBeLoObj0TLbdgW7TAIQRU2boMc9uOKQ==} + '@inquirer/core@11.1.5': + resolution: {integrity: sha512-QQPAX+lka8GyLcZ7u7Nb1h6q72iZ/oy0blilC3IB2nSt1Qqxp7akt94Jqhi/DzARuN3Eo9QwJRvtl4tmVe4T5A==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2722,8 +2816,8 @@ packages: '@types/node': optional: true - '@inquirer/editor@5.0.3': - resolution: {integrity: sha512-wYyQo96TsAqIciP/r5D3cFeV8h4WqKQ/YOvTg5yOfP2sqEbVVpbxPpfV3LM5D0EP4zUI3EZVHyIUIllnoIa8OQ==} + '@inquirer/editor@5.0.8': + resolution: {integrity: sha512-sLcpbb9B3XqUEGrj1N66KwhDhEckzZ4nI/W6SvLXyBX8Wic3LDLENlWRvkOGpCPoserabe+MxQkpiMoI8irvyA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2731,8 +2825,8 @@ packages: '@types/node': optional: true - '@inquirer/expand@5.0.3': - resolution: {integrity: sha512-2oINvuL27ujjxd95f6K2K909uZOU2x1WiAl7Wb1X/xOtL8CgQ1kSxzykIr7u4xTkXkXOAkCuF45T588/YKee7w==} + '@inquirer/expand@5.0.8': + resolution: {integrity: sha512-QieW3F1prNw3j+hxO7/NKkG1pk3oz7pOB6+5Upwu3OIwADfPX0oZVppsqlL+Vl/uBHHDSOBY0BirLctLnXwGGg==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2740,8 +2834,8 @@ packages: '@types/node': optional: true - '@inquirer/external-editor@2.0.2': - resolution: {integrity: sha512-X/fMXK7vXomRWEex1j8mnj7s1mpnTeP4CO/h2gysJhHLT2WjBnLv4ZQEGpm/kcYI8QfLZ2fgW+9kTKD+jeopLg==} + '@inquirer/external-editor@2.0.3': + resolution: {integrity: sha512-LgyI7Agbda74/cL5MvA88iDpvdXI2KuMBCGRkbCl2Dg1vzHeOgs+s0SDcXV7b+WZJrv2+ERpWSM65Fpi9VfY3w==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2749,12 +2843,12 @@ packages: '@types/node': optional: true - '@inquirer/figures@2.0.2': - resolution: {integrity: sha512-qXm6EVvQx/FmnSrCWCIGtMHwqeLgxABP8XgcaAoywsL0NFga9gD5kfG0gXiv80GjK9Hsoz4pgGwF/+CjygyV9A==} + '@inquirer/figures@2.0.3': + resolution: {integrity: sha512-y09iGt3JKoOCBQ3w4YrSJdokcD8ciSlMIWsD+auPu+OZpfxLuyz+gICAQ6GCBOmJJt4KEQGHuZSVff2jiNOy7g==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - '@inquirer/input@5.0.3': - resolution: {integrity: sha512-4R0TdWl53dtp79Vs6Df2OHAtA2FVNqya1hND1f5wjHWxZJxwDMSNB1X5ADZJSsQKYAJ5JHCTO+GpJZ42mK0Otw==} + '@inquirer/input@5.0.8': + resolution: {integrity: sha512-p0IJslw0AmedLEkOU+yrEX3Aj2RTpQq7ZOf8nc1DIhjzaxRWrrgeuE5Kyh39fVRgtcACaMXx/9WNo8+GjgBOfw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2762,8 +2856,8 @@ packages: '@types/node': optional: true - '@inquirer/number@4.0.3': - resolution: {integrity: sha512-TjQLe93GGo5snRlu83JxE38ZPqj5ZVggL+QqqAF2oBA5JOJoxx25GG3EGH/XN/Os5WOmKfO8iLVdCXQxXRZIMQ==} + '@inquirer/number@4.0.8': + resolution: {integrity: sha512-uGLiQah9A0F9UIvJBX52m0CnqtLaym0WpT9V4YZrjZ+YRDKZdwwoEPz06N6w8ChE2lrnsdyhY9sL+Y690Kh9gQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2771,8 +2865,8 @@ packages: '@types/node': optional: true - '@inquirer/password@5.0.3': - resolution: {integrity: sha512-rCozGbUMAHedTeYWEN8sgZH4lRCdgG/WinFkit6ZPsp8JaNg2T0g3QslPBS5XbpORyKP/I+xyBO81kFEvhBmjA==} + '@inquirer/password@5.0.8': + resolution: {integrity: sha512-zt1sF4lYLdvPqvmvHdmjOzuUUjuCQ897pdUCO8RbXMUDKXJTTyOQgtn23le+jwcb+MpHl3VAFvzIdxRAf6aPlA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2780,8 +2874,8 @@ packages: '@types/node': optional: true - '@inquirer/prompts@8.1.0': - resolution: {integrity: sha512-LsZMdKcmRNF5LyTRuZE5nWeOjganzmN3zwbtNfcs6GPh3I2TsTtF1UYZlbxVfhxd+EuUqLGs/Lm3Xt4v6Az1wA==} + '@inquirer/prompts@8.3.0': + resolution: {integrity: sha512-JAj66kjdH/F1+B7LCigjARbwstt3SNUOSzMdjpsvwJmzunK88gJeXmcm95L9nw1KynvFVuY4SzXh/3Y0lvtgSg==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2789,8 +2883,8 @@ packages: '@types/node': optional: true - '@inquirer/rawlist@5.1.0': - resolution: {integrity: sha512-yUCuVh0jW026Gr2tZlG3kHignxcrLKDR3KBp+eUgNz+BAdSeZk0e18yt2gyBr+giYhj/WSIHCmPDOgp1mT2niQ==} + '@inquirer/rawlist@5.2.4': + resolution: {integrity: sha512-fTuJ5Cq9W286isLxwj6GGyfTjx1Zdk4qppVEPexFuA6yioCCXS4V1zfKroQqw7QdbDPN73xs2DiIAlo55+kBqg==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2798,8 +2892,8 @@ packages: '@types/node': optional: true - '@inquirer/search@4.0.3': - resolution: {integrity: sha512-lzqVw0YwuKYetk5VwJ81Ba+dyVlhseHPx9YnRKQgwXdFS0kEavCz2gngnNhnMIxg8+j1N/rUl1t5s1npwa7bqg==} + '@inquirer/search@4.1.4': + resolution: {integrity: sha512-9yPTxq7LPmYjrGn3DRuaPuPbmC6u3fiWcsE9ggfLcdgO/ICHYgxq7mEy1yJ39brVvgXhtOtvDVjDh9slJxE4LQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2807,8 +2901,8 @@ packages: '@types/node': optional: true - '@inquirer/select@5.0.3': - resolution: {integrity: sha512-M+ynbwS0ecQFDYMFrQrybA0qL8DV0snpc4kKevCCNaTpfghsRowRY7SlQBeIYNzHqXtiiz4RG9vTOeb/udew7w==} + '@inquirer/select@5.1.0': + resolution: {integrity: sha512-OyYbKnchS1u+zRe14LpYrN8S0wH1vD0p2yKISvSsJdH2TpI87fh4eZdWnpdbrGauCRWDph3NwxRmM4Pcm/hx1Q==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2816,8 +2910,8 @@ packages: '@types/node': optional: true - '@inquirer/type@4.0.2': - resolution: {integrity: sha512-cae7mzluplsjSdgFA6ACLygb5jC8alO0UUnFPyu0E7tNRPrL+q/f8VcSXp+cjZQ7l5CMpDpi2G1+IQvkOiL1Lw==} + '@inquirer/type@4.0.3': + resolution: {integrity: sha512-cKZN7qcXOpj1h+1eTTcGDVLaBIHNMT1Rz9JqJP5MnEJ0JhgVWllx7H/tahUp5YEK1qaByH2Itb8wLG/iScD5kw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2825,8 +2919,8 @@ packages: '@types/node': optional: true - '@internationalized/date@3.10.1': - resolution: {integrity: sha512-oJrXtQiAXLvT9clCf1K4kxp3eKsQhIaZqxEyowkBcsvZDdZkbWrVmnGknxs5flTD0VGsxrxKgBCZty1EzoiMzA==} + '@internationalized/date@3.12.0': + resolution: {integrity: sha512-/PyIMzK29jtXaGU23qTvNZxvBXRtKbNnGDFD+PY6CZw/Y8Ex8pFUzkuCJCG9aOqmShjqhS9mPqP6Dk5onQY8rQ==} '@internationalized/message@3.1.8': resolution: {integrity: sha512-Rwk3j/TlYZhn3HQ6PyXUV0XP9Uv42jqZGNegt0BXlxjE6G3+LwHjbQZAGHhCnCPdaA6Tvd3ma/7QzLlLkJxAWA==} @@ -2837,22 +2931,10 @@ packages: '@internationalized/string@3.2.7': resolution: {integrity: sha512-D4OHBjrinH+PFZPvfCXvG28n2LSykWcJ7GIioQL+ok0LON15SdfoUssoHzzOUmVZLbRoREsQXVzA6r8JKsbP6A==} - '@isaacs/balanced-match@4.0.1': - resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} - engines: {node: 20 || >=22} - - '@isaacs/brace-expansion@5.0.0': - resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} - engines: {node: 20 || >=22} - '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} - '@isaacs/cliui@9.0.0': - resolution: {integrity: sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==} - engines: {node: '>=18'} - '@isaacs/fs-minipass@4.0.1': resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} engines: {node: '>=18.0.0'} @@ -2869,8 +2951,8 @@ packages: resolution: {integrity: sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@joshwooding/vite-plugin-react-docgen-typescript@0.6.3': - resolution: {integrity: sha512-9TGZuAX+liGkNKkwuo3FYJu7gHWT0vkBcf7GkOe7s7fmC19XwH/4u5u7sDIFrMooe558ORcmuBvBz7Ur5PlbHw==} + '@joshwooding/vite-plugin-react-docgen-typescript@0.6.4': + resolution: {integrity: sha512-6PyZBYKnnVNqOSB0YFly+62R7dmov8segT27A+RVTBVd4iAE6kbW9QBJGlyR2yG4D4ohzhZSTIu7BK1UTtmFFA==} peerDependencies: typescript: '>= 4.3.x' vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 @@ -2900,14 +2982,11 @@ packages: '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - '@lezer/common@1.5.0': - resolution: {integrity: sha512-PNGcolp9hr4PJdXR4ix7XtixDrClScvtSCYW3rQG106oVMOOI+jFb+0+J3mbeL/53g1Zd6s0kJzaw6Ri68GmAA==} - '@lezer/common@1.5.1': resolution: {integrity: sha512-6YRVG9vBkaY7p1IVxL4s44n5nUnaNnGM2/AckNgYOnxTG2kWh1vR8BMxPseWPjRNpb5VtXnMpeYAEAADoRV1Iw==} - '@lezer/css@1.3.0': - resolution: {integrity: sha512-pBL7hup88KbI7hXnZV3PQsn43DHy6TWyzuyk2AO9UyoXcDltvIdqWKE1dLL/45JVZ+YZkHe1WVHqO6wugZZWcw==} + '@lezer/css@1.3.1': + resolution: {integrity: sha512-PYAKeUVBo3HFThruRyp/iK91SwiZJnzXh8QzkQlwijB5y+N5iB28+iLk78o2zmKqqV0uolNhCwFqB8LA7b0Svg==} '@lezer/generator@1.8.0': resolution: {integrity: sha512-/SF4EDWowPqV1jOgoGSGTIFsE7Ezdr7ZYxyihl5eMKVO5tlnpIhFcDavgm1hHY5GEonoOAEnJ0CU0x+tvuAuUg==} @@ -2925,8 +3004,8 @@ packages: '@lezer/json@1.0.3': resolution: {integrity: sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==} - '@lezer/lr@1.4.7': - resolution: {integrity: sha512-wNIFWdSUfX9Jc6ePMzxSPVgTVB4EOfDIwLQLWASyiUdHKaMsiilj9bYiGkGQCKVodd0x6bgQCV207PILGFCF9Q==} + '@lezer/lr@1.4.8': + resolution: {integrity: sha512-bPWa0Pgx69ylNlMlPvBPryqeLYQjyJjqPx+Aupm5zydLIF3NE+6MMLT8Yi23Bd9cif9VS00aUebn+6fDIGBcDA==} '@lezer/xml@1.0.6': resolution: {integrity: sha512-CdDwirL0OEaStFue/66ZmFSeppuL6Dwjlk8qk153mSQwiSH/Dlri4GNymrNWnUmPl2Um7QfV1FO9KFUyX3Twww==} @@ -3002,16 +3081,16 @@ packages: '@module-federation/bridge-react-webpack-plugin@0.21.6': resolution: {integrity: sha512-lJMmdhD4VKVkeg8RHb+Jwe6Ou9zKVgjtb1inEURDG/sSS2ksdZA8pVKLYbRPRbdmjr193Y8gJfqFbI2dqoyc/g==} - '@module-federation/bridge-react-webpack-plugin@0.22.0': - resolution: {integrity: sha512-OzMBBbUhOMbDVX/wkVDxaOshgyUdxv+kRQDtxl1/ipV5GXTjs1tpS4NHtDwiJi0qKeG0AvnvGCrPu7bjMOcAVw==} + '@module-federation/bridge-react-webpack-plugin@2.1.0': + resolution: {integrity: sha512-c/iiwLwxHDG5i227v2GQ84JRPWHU+d2uhxhZhbxIAQ5uRe6kbtj8O4uPUfEq+iabiqqtUwTLbcpUFFy1bLllYA==} '@module-federation/cli@0.21.6': resolution: {integrity: sha512-qNojnlc8pTyKtK7ww3i/ujLrgWwgXqnD5DcDPsjADVIpu7STaoaVQ0G5GJ7WWS/ajXw6EyIAAGW/AMFh4XUxsQ==} engines: {node: '>=16.0.0'} hasBin: true - '@module-federation/cli@0.22.0': - resolution: {integrity: sha512-kdeDg6HuOqJYKtPeoupWQg6wLZT7B+AwMDwMjwhcKHxKEmKFPImbJLymBWEgmKTktZKh1ERtEOplwFt9u5iEBA==} + '@module-federation/cli@2.1.0': + resolution: {integrity: sha512-VbMJMEfP1vp/693HbQTMYqMu73Qbv23aJEW9/NhmVkRXkfjBtNfP+mROSFjJVQsWhYyU5vy8kBX7DQS/mvZGBg==} engines: {node: '>=16.0.0'} hasBin: true @@ -3021,11 +3100,16 @@ packages: react: '>=16.9.0' react-dom: '>=16.9.0' - '@module-federation/data-prefetch@0.22.0': - resolution: {integrity: sha512-NESR/5Wcn9unPY18oQSSXlbXTnMbUFwqqvSZnpJt5vBb/8QlcJEiPnxERZqKhKrIS6GTD8KneHPRCOQsP6Xcqw==} + '@module-federation/data-prefetch@2.1.0': + resolution: {integrity: sha512-/rHwtZEknzujpCoXChZcy29vD7zNY2b/XfAcOpCkMVfWyQiNhppKxeyjA6FnPEp64NAOLzj2XxaadceXa1eFeA==} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true '@module-federation/dts-plugin@0.21.6': resolution: {integrity: sha512-YIsDk8/7QZIWn0I1TAYULniMsbyi2LgKTi9OInzVmZkwMC6644x/ratTWBOUDbdY1Co+feNkoYeot1qIWv2L7w==} @@ -3036,8 +3120,8 @@ packages: vue-tsc: optional: true - '@module-federation/dts-plugin@0.22.0': - resolution: {integrity: sha512-lj5YtUZz0moaT1XziM0OyizE0mIhMa8W65RUiX/+UZ4iNK/KMs4e/CGpfhEt2Lj9+j6KYSzI2+676d+73j/kag==} + '@module-federation/dts-plugin@2.1.0': + resolution: {integrity: sha512-2ubWFjF72i3Z5TM2G8hg6SOS6dB0v7PRLXPUMNoVMBxHGxiFG/F0xryZ2UYFwLA2hcNmf60LNP30F1tJhsH4wg==} peerDependencies: typescript: ^4.9.0 || ^5.0.0 vue-tsc: '>=1.0.24' @@ -3060,8 +3144,8 @@ packages: webpack: optional: true - '@module-federation/enhanced@0.22.0': - resolution: {integrity: sha512-OysyO6xbhpP+CeOEDp2v6HyFcVT5wWAdQrfga3jhlFUAdIR7nZZ2albysnF2CGn/xyU050Ss74ttgy7GiKi5fQ==} + '@module-federation/enhanced@2.1.0': + resolution: {integrity: sha512-nWCe31vzYLGsT3DYf2cKtxSjUDLWVgErZeDEB8cddtuA3c4npSdKeG8P/bI9GtRph5ybIUFbyAMtuKPPhMahOw==} hasBin: true peerDependencies: typescript: ^4.9.0 || ^5.0.0 @@ -3078,44 +3162,37 @@ packages: '@module-federation/error-codes@0.21.6': resolution: {integrity: sha512-MLJUCQ05KnoVl8xd6xs9a5g2/8U+eWmVxg7xiBMeR0+7OjdWUbHwcwgVFatRIwSZvFgKHfWEiI7wsU1q1XbTRQ==} - '@module-federation/error-codes@0.22.0': - resolution: {integrity: sha512-xF9SjnEy7vTdx+xekjPCV5cIHOGCkdn3pIxo9vU7gEZMIw0SvAEdsy6Uh17xaCpm8V0FWvR0SZoK9Ik6jGOaug==} + '@module-federation/error-codes@2.1.0': + resolution: {integrity: sha512-W+uCmPsFuV+15E1S7JUB1AeUDBFqKjJ2hImXdBNYx7T1CGM6awS/veooXqNoP7iM/kwKjtpTQPIeccWLrq76Mg==} '@module-federation/inject-external-runtime-core-plugin@0.21.6': resolution: {integrity: sha512-DJQne7NQ988AVi3QB8byn12FkNb+C2lBeU1NRf8/WbL0gmHsr6kW8hiEJCm8LYaURwtsQqtsEV7i+8+51qjSmQ==} peerDependencies: '@module-federation/runtime-tools': 0.21.6 - '@module-federation/inject-external-runtime-core-plugin@0.22.0': - resolution: {integrity: sha512-zeN6XiLV9l0tAsZzQxHLEQM28sWiijmIBp9CiIDc4iqk2f/kgCSqiBWTiNcS4sZODzupPkktaWsC5+5eWk0ENQ==} + '@module-federation/inject-external-runtime-core-plugin@2.1.0': + resolution: {integrity: sha512-okAVRH/9rROh1fBSKF7Li/Ia8bQhgz38AfVvUSzVu32/HCvdjpfddQtPFFxvmi2oayPgUDY4Qy8RXT1pUlBqpA==} peerDependencies: - '@module-federation/runtime-tools': 0.22.0 + '@module-federation/runtime-tools': 2.1.0 '@module-federation/managers@0.21.6': resolution: {integrity: sha512-BeV6m2/7kF5MDVz9JJI5T8h8lMosnXkH2bOxxFewcra7ZjvDOgQu7WIio0mgk5l1zjNPvnEVKhnhrenEdcCiWg==} - '@module-federation/managers@0.22.0': - resolution: {integrity: sha512-Ptv8gEUihPBeoQEpsKq3GZUEB4y/hqG83mKw5NrKpXMIfcoF6SZjcknXz5LuN7NF3xMi1XHYU74z/nKzr+izew==} + '@module-federation/managers@2.1.0': + resolution: {integrity: sha512-8HX721e3uuDSURtnOpj6Zy/+Qc4IM5no9hMPODYdGjrYe2YUmXY4/5JScSVnFeYm+zBPw6y9QoufeG9g2jrWBg==} '@module-federation/manifest@0.21.6': resolution: {integrity: sha512-yg93+I1qjRs5B5hOSvjbjmIoI2z3th8/yst9sfwvx4UDOG1acsE3HHMyPN0GdoIGwplC/KAnU5NmUz4tREUTGQ==} - '@module-federation/manifest@0.22.0': - resolution: {integrity: sha512-Exv+frMkRGKDs3KKXeBBKcHvL7nNTk5Yt2ftEvxCUIRPC16Ebvy6RcQvFFvbvmOhuM/If6j6E/aZu5Z9oau6xw==} + '@module-federation/manifest@2.1.0': + resolution: {integrity: sha512-icIUhMG4FwaFZyBmVjadkdqscNb98iXrITTVeMeAxJcrnZltSBBSEHepfpfeW+tHW+wMmr+lWFnAbSCepV73+A==} - '@module-federation/node@2.7.26': - resolution: {integrity: sha512-C7aIABSxbZKOvVDMIivmV9Q/aOVh9xpUv+y+nwSWuQr9v2pgmMzVK3rxWoeusmkpaENia8h5AWNpYjcrMi+O9g==} + '@module-federation/node@2.7.33': + resolution: {integrity: sha512-ATR5zu7qUb8wasOyIYrbVfoPb00c7wC9F66g/GeSJwV1O9SvhR5r4rsfCSQ3uB8/Y7VCeHz0w8DZSqMRkuoHYQ==} peerDependencies: - next: '*' - react: ^16||^17||^18||^19 - react-dom: ^16||^17||^18||^19 webpack: ^5.40.0 peerDependenciesMeta: - next: - optional: true - react: - optional: true - react-dom: + webpack: optional: true '@module-federation/rspack@0.21.6': @@ -3130,10 +3207,10 @@ packages: vue-tsc: optional: true - '@module-federation/rspack@0.22.0': - resolution: {integrity: sha512-PvDlFxzCbufArZvt6wSLsJNm20hdDsz/4X04YAxAZfp/dTECZghZsebLcR7nHOzOwR2gCX8vv+gB3r+5MheobA==} + '@module-federation/rspack@2.1.0': + resolution: {integrity: sha512-bojG6yIoWsta7CDdKZ3nrTn1IKT98algUGG5/uyR6nhyOxsu7CJpf17kcLUqTKdBwN9S8qZOjycXGDeEX//N3w==} peerDependencies: - '@rspack/core': '>=0.7' + '@rspack/core': ^0.7.0 || ^1.0.0 || ^2.0.0-0 typescript: ^4.9.0 || ^5.0.0 vue-tsc: '>=1.0.24' peerDependenciesMeta: @@ -3145,38 +3222,41 @@ packages: '@module-federation/runtime-core@0.21.6': resolution: {integrity: sha512-5Hd1Y5qp5lU/aTiK66lidMlM/4ji2gr3EXAtJdreJzkY+bKcI5+21GRcliZ4RAkICmvdxQU5PHPL71XmNc7Lsw==} - '@module-federation/runtime-core@0.22.0': - resolution: {integrity: sha512-GR1TcD6/s7zqItfhC87zAp30PqzvceoeDGYTgF3Vx2TXvsfDrhP6Qw9T4vudDQL3uJRne6t7CzdT29YyVxlgIA==} + '@module-federation/runtime-core@2.1.0': + resolution: {integrity: sha512-9W+wV5s7PTMnSFCmyNvItnOf3VRYSxAPMZQ91bOT4GdwHTO23dfmC57o0SiqXw+ri/XOQVA8gd/p8TDwDDYx6A==} '@module-federation/runtime-tools@0.21.6': resolution: {integrity: sha512-fnP+ZOZTFeBGiTAnxve+axGmiYn2D60h86nUISXjXClK3LUY1krUfPgf6MaD4YDJ4i51OGXZWPekeMe16pkd8Q==} - '@module-federation/runtime-tools@0.22.0': - resolution: {integrity: sha512-4ScUJ/aUfEernb+4PbLdhM/c60VHl698Gn1gY21m9vyC1Ucn69fPCA1y2EwcCB7IItseRMoNhdcWQnzt/OPCNA==} + '@module-federation/runtime-tools@2.1.0': + resolution: {integrity: sha512-2pOyGOiWIGG0+fE0jBY6pRYVH4+G/gFiP9KnyVDp6zj3leFRdePtlIZDa4O0X1dQcMOMmOORrx+TLRZeygbCnw==} '@module-federation/runtime@0.21.6': resolution: {integrity: sha512-+caXwaQqwTNh+CQqyb4mZmXq7iEemRDrTZQGD+zyeH454JAYnJ3s/3oDFizdH6245pk+NiqDyOOkHzzFQorKhQ==} - '@module-federation/runtime@0.22.0': - resolution: {integrity: sha512-38g5iPju2tPC3KHMPxRKmy4k4onNp6ypFPS1eKGsNLUkXgHsPMBFqAjDw96iEcjri91BrahG4XcdyKi97xZzlA==} + '@module-federation/runtime@2.1.0': + resolution: {integrity: sha512-Cs6H6vAQrLeD7tWW3nI7Z9EdvhcFcbqQdYWJ2SaN1X/eX2YvgHJe8sRxa7K7zlVRV5QZEPKgQCbrUfef+d5xqQ==} '@module-federation/sdk@0.21.6': resolution: {integrity: sha512-x6hARETb8iqHVhEsQBysuWpznNZViUh84qV2yE7AD+g7uIzHKiYdoWqj10posbo5XKf/147qgWDzKZoKoEP2dw==} - '@module-federation/sdk@0.22.0': - resolution: {integrity: sha512-x4aFNBKn2KVQRuNVC5A7SnrSCSqyfIWmm1DvubjbO9iKFe7ith5niw8dqSFBekYBg2Fwy+eMg4sEFNVvCAdo6g==} + '@module-federation/sdk@2.1.0': + resolution: {integrity: sha512-HhiSo1X+t2+r5lxU+JBVsJdE2IJZOaD1e0linw+4bLlEy8uIgXhGttF9+9rAnRKWlhn6R8E23ionwBCuSLVeXQ==} '@module-federation/third-party-dts-extractor@0.21.6': resolution: {integrity: sha512-Il6x4hLsvCgZNk1DFwuMBNeoxD1BsZ5AW2BI/nUgu0k5FiAvfcz1OFawRFEHtaM/kVrCsymMOW7pCao90DaX3A==} - '@module-federation/third-party-dts-extractor@0.22.0': - resolution: {integrity: sha512-3y2DZdeEjArNKDqA1Ds32Q6A5RATcsmywCXyQaWcfaScprpmzfEWiDkeD/nzoA/0+4ePY8OEinJ4hLtoMNLbLQ==} + '@module-federation/third-party-dts-extractor@2.1.0': + resolution: {integrity: sha512-w/hn0J+gw+lEfsXTR3DsbtcxpAndMZJ2PHnQTFn2s5BujNL18FcStaoz0tDpcJAVxi2iQZATJ3bGrlO2t2aDjQ==} '@module-federation/webpack-bundler-runtime@0.21.6': resolution: {integrity: sha512-7zIp3LrcWbhGuFDTUMLJ2FJvcwjlddqhWGxi/MW3ur1a+HaO8v5tF2nl+vElKmbG1DFLU/52l3PElVcWf/YcsQ==} - '@module-federation/webpack-bundler-runtime@0.22.0': - resolution: {integrity: sha512-aM8gCqXu+/4wBmJtVeMeeMN5guw3chf+2i6HajKtQv7SJfxV/f4IyNQJUeUQu9HfiAZHjqtMV5Lvq/Lvh8LdyA==} + '@module-federation/webpack-bundler-runtime@2.1.0': + resolution: {integrity: sha512-yThI7cPanvH5eobaeFUsQ51sjllA3nyN/8OxfSdlbeTogLF4K8tkCr6H7QW+alE9lXxOzI2BTCxMV6NJBKWmTQ==} + + '@mongodb-js/saslprep@1.4.6': + resolution: {integrity: sha512-y+x3H1xBZd38n10NZF/rEBlvDOOMQ6LKUTHqr8R9VkJ+mmQOYtJFxIlkkK8fZrtOiL6VixbOBWMbZGBdal3Z1g==} '@mrleebo/prisma-ast@0.13.1': resolution: {integrity: sha512-XyroGQXcHrZdvmrGJvsA9KNeOOgGMg1Vg9OlheUsBOSKznLMDl+YChxbkboRHvtFYJEMRYmlV3uoo/njCw05iw==} @@ -3267,108 +3347,108 @@ packages: resolution: {integrity: sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q==} engines: {node: ^20.17.0 || >=22.9.0} - '@nx/cypress@22.3.3': - resolution: {integrity: sha512-HWy05q0GSnbxljq1fBVfXPGw8quG9zvu4UaLErNqPHh46oWmUoWuR2TkDkpWEZn9JvYxx+m4QhsGpXzHXioeXg==} + '@nx/cypress@22.5.4': + resolution: {integrity: sha512-mKh8BOLDKGRSCRCd5PtRwdio9djpX7Nu5fvWmXNnbMXq37MFlh/L3xlFP2cxLMmugSibJbz19GYBkkjmjf8ZDw==} peerDependencies: cypress: '>= 13 < 16' peerDependenciesMeta: cypress: optional: true - '@nx/devkit@22.3.3': - resolution: {integrity: sha512-/hxcdhE+QDalsWEbJurHtZh9aY27taHeImbCVJnogwv85H3RbAE+0YuKXGInutfLszAs7phwzli71yq+d2P45Q==} + '@nx/devkit@22.5.4': + resolution: {integrity: sha512-+QCmpQZQmEGvi8IurC6bOgUTk+Q0dQo7wkp6V04lskXBztSyasBS0BGy5ic90kY05UlQUd++zRA1VY0jc+Yz5Q==} peerDependencies: nx: '>= 21 <= 23 || ^22.0.0-0' - '@nx/eslint@22.3.3': - resolution: {integrity: sha512-iG/LvrYf2CFAm2A0kfmRU4VeCTAN5PjUw8xc6oD1zfQ/KTmE/gFG2P1aJBo2mTIyzk9k8ZI0dqIhPLdl/AAtxg==} + '@nx/eslint@22.5.4': + resolution: {integrity: sha512-LMFpyep6N5Se7v5Ck2icZPBa3krWcuGYpubzjEuG35dQm2f/Fr+vLNfQWvfHiF+gP3eSYuJJPI/E38ifTZ/J5A==} peerDependencies: '@zkochan/js-yaml': 0.0.7 - eslint: ^8.0.0 || ^9.0.0 + eslint: ^8.0.0 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: '@zkochan/js-yaml': optional: true - '@nx/js@22.3.3': - resolution: {integrity: sha512-L3MOb8cLc2TIg2R3hGC9FLlcuVqlqST/fztmOihw9wS3lo52E4v2gP/BpYGfRh/u9r6Ekm6LF03Or+VwYzPuzA==} + '@nx/js@22.5.4': + resolution: {integrity: sha512-RPGDQjPm68ml5vKOk2RhRgNUM51qyMfIkRsKSxTWy0EpMOa7ud0I2bPQyNDMkqP04w8I5GZPD8O8opesDrdmtg==} peerDependencies: verdaccio: ^6.0.5 peerDependenciesMeta: verdaccio: optional: true - '@nx/module-federation@22.3.3': - resolution: {integrity: sha512-bo0qsW0hDhuyS/WnHQ1nndHcd7VeuMS3bxCwPJkPm8+qsVhWT88GO9WoYnlvdpx/LfTT/N6k1AOVOKAygRuUNQ==} + '@nx/module-federation@22.5.4': + resolution: {integrity: sha512-rjYSxbKMrrRHQOh+25GlNI91cads+PyHe1LVNn3/S1NTZH20PObtt+KRuppj6L2Mjg3/gK0WfQoMrvFNRiV48A==} - '@nx/nx-darwin-arm64@22.3.3': - resolution: {integrity: sha512-zBAGFGLal09CxhQkdMpOVwcwa9Y01aFm88jTTn35s/DdIWsfngmPzz0t4mG7u2D05q7TJfGQ31pIf5GkNUjo6g==} + '@nx/nx-darwin-arm64@22.5.4': + resolution: {integrity: sha512-Ib9znwSLQZSZ/9hhg5ODplpNhE/RhGVXzdfRj6YonTuWSj/kH3dLMio+4JEkjRdTQVm06cDW0KdwSgnwovqMGg==} cpu: [arm64] os: [darwin] - '@nx/nx-darwin-x64@22.3.3': - resolution: {integrity: sha512-6ZQ6rMqH8NY4Jz+Gc89D5bIH2NxZb5S/vaA4yJ9RrqAfl4QWchNFD5na+aRivSd+UdsYLPKKl6qohet5SE6vOg==} + '@nx/nx-darwin-x64@22.5.4': + resolution: {integrity: sha512-DjyXuQMc93MPU2XdRsJYjzbv1tgCzMi+zm7O0gc4x3h+ECFjKkjzQBg67pqGdhE3TV27MAlVRKrgHStyK9iigg==} cpu: [x64] os: [darwin] - '@nx/nx-freebsd-x64@22.3.3': - resolution: {integrity: sha512-J/PP5pIOQtR7ZzrFwP6d6h0yfY7r9EravG2m940GsgzGbtZGYIDqnh5Wdt+4uBWPH8VpdNOwFqH0afELtJA3MA==} + '@nx/nx-freebsd-x64@22.5.4': + resolution: {integrity: sha512-DhxdP8AhIfN0yCtFhZQcbp32MVN3L7UiTotYqqnOgwW922NRGSd5e+KEAWiJVrIO6TdgnI7prxpg1hfQQK0WDw==} cpu: [x64] os: [freebsd] - '@nx/nx-linux-arm-gnueabihf@22.3.3': - resolution: {integrity: sha512-/zn0altzM15S7qAgXMaB41vHkEn18HyTVUvRrjmmwaVqk9WfmDmqOQlGWoJ6XCbpvKQ8bh14RyhR9LGw1JJkNA==} + '@nx/nx-linux-arm-gnueabihf@22.5.4': + resolution: {integrity: sha512-pv1x1afTaLAOxPxVhQneLeXgjclp11f9ORxR7jA4E86bSgc9OL92dLSCkXtLQzqPNOej6SZ2fO+PPHVMZwtaPQ==} cpu: [arm] os: [linux] - '@nx/nx-linux-arm64-gnu@22.3.3': - resolution: {integrity: sha512-NmPeCexWIZHW9RM3lDdFENN9C3WtlQ5L4RSNFESIjreS921rgePhulsszYdGnHdcnKPYlBBJnX/NxVsfioBbnQ==} + '@nx/nx-linux-arm64-gnu@22.5.4': + resolution: {integrity: sha512-mPji9PzleWPvXpmFDKaXpTymRgZkk/hW8JHGhvEZpKHHXMYgTGWC+BqOEM2A4dYC4bu4fi9RrteL7aouRRWJoQ==} cpu: [arm64] os: [linux] - '@nx/nx-linux-arm64-musl@22.3.3': - resolution: {integrity: sha512-K02U88Q0dpvCfmSXXvY7KbYQSa1m+mkYeqDBRHp11yHk1GoIqaHp8oEWda7FV4gsriNExPSS5tX1/QGVoLZrCw==} + '@nx/nx-linux-arm64-musl@22.5.4': + resolution: {integrity: sha512-hF/HvEhbCjcFpTgY7RbP1tUTbp0M1adZq4ckyW8mwhDWQ/MDsc8FnOHwCO3Bzy9ZeJM0zQUES6/m0Onz8geaEA==} cpu: [arm64] os: [linux] - '@nx/nx-linux-x64-gnu@22.3.3': - resolution: {integrity: sha512-04TEbvgwRaB9ifr39YwJmWh3RuXb4Ry4m84SOJyjNXAfPrepcWgfIQn1VL2ul1Ybq+P023dLO9ME8uqFh6j1YQ==} + '@nx/nx-linux-x64-gnu@22.5.4': + resolution: {integrity: sha512-1+vicSYEOtc7CNMoRCjo59no4gFe8w2nGIT127wk1yeW3EJzRVNlOA7Deu10NUUbzLeOvHc8EFOaU7clT+F7XQ==} cpu: [x64] os: [linux] - '@nx/nx-linux-x64-musl@22.3.3': - resolution: {integrity: sha512-uxBXx5q+S5OGatbYDxnamsKXRKlYn+Eq1nrCAHaf8rIfRoHlDiRV2PqtWuF+O2pxR5FWKpvr+/sZtt9rAf7KMw==} + '@nx/nx-linux-x64-musl@22.5.4': + resolution: {integrity: sha512-/KjndxVB14yU0SJOhqADHOWoTy4Y45h5RjW3cxcXlPSJZz7ar1FnlLne1rWMMMUttepc8ku+3T//SGKi2eu+Nw==} cpu: [x64] os: [linux] - '@nx/nx-win32-arm64-msvc@22.3.3': - resolution: {integrity: sha512-aOwlfD6ZA1K6hjZtbhBSp7s1yi3sHbMpLCa4stXzfhCCpKUv46HU/EdiWdE1N8AsyNFemPZFq81k1VTowcACdg==} + '@nx/nx-win32-arm64-msvc@22.5.4': + resolution: {integrity: sha512-CrYt9FwhjOI6ZNy/G6YHLJmZuXCFJ24BCxugPXiZ7knDx7eGrr7owGgfht4SSiK3KCX40CvWCBJfqR4ZSgaSUA==} cpu: [arm64] os: [win32] - '@nx/nx-win32-x64-msvc@22.3.3': - resolution: {integrity: sha512-EDR8BtqeDvVNQ+kPwnfeSfmerYetitU3tDkxOMIybjKJDh69U2JwTB8n9ARwNaZQbNk7sCGNRUSZFTbAAUKvuQ==} + '@nx/nx-win32-x64-msvc@22.5.4': + resolution: {integrity: sha512-g5YByv4XsYwsYZvFe24A9bvfhZA+mwtIQt6qZtEVduZTT1hfhIsq0LXGHhkGoFLYwRMXSracWOqkalY0KT4IQw==} cpu: [x64] os: [win32] - '@nx/react@22.3.3': - resolution: {integrity: sha512-rbnI34j2UwvS8K5I6KS1IkndYI5psRV+jV7+NfVhfBpDLzEW4NU7WB1IVuK7t1grrLKFfTs7GKw5cTSX33hnNg==} + '@nx/react@22.5.4': + resolution: {integrity: sha512-QWQF4rZMtSABWTRdksjK4YQaCKZW+PRfYOskebwb8OtaoRFeEZwPeN0RvQFRGInhZJfDQRJhKMKy5YHdVvuTaw==} - '@nx/rollup@22.3.3': - resolution: {integrity: sha512-BJdOHx0CcZ6YMvn7quKTfh9C/X7X9s1e2XAZv+LC2vxiRdxN80w4cq04yZE8i5PPpQNC6SG3OWIG6eDlkJhw5A==} + '@nx/rollup@22.5.4': + resolution: {integrity: sha512-SM4oe2qChid6gy5YynaXavHI0J5Ugfr/Su2TLFxaXNTCB6Wb0wONGhbhGFl90rma1xhAp4SMGQYxtQaReWMi9A==} - '@nx/storybook@22.3.3': - resolution: {integrity: sha512-l4f6nOjcJm2w/rH82aBaKtJyBYOD5gXkvizQQShKro0Pykjs6eTp3rpUkttwm/iT/f2torSU54ys10YFRU5Ysg==} + '@nx/storybook@22.5.4': + resolution: {integrity: sha512-ygzcYyy7XlNM9piKM12Micx95SEz5aBuJSBosSz8Xtn0ZOyLkq5aeSOG10lqWf1keTTNsXZ7j2ZFGeQHRse5cg==} peerDependencies: storybook: '>=7.0.0 <11.0.0' - '@nx/vite@22.3.3': - resolution: {integrity: sha512-JYtQeKJVID6Am65M1gDxCBLyO7pA6p/dBxnQyWEHsbJ5VLiOyCxr+W+YOE4p4roVlQxjAaCMqvtGH3cWnNQWxg==} + '@nx/vite@22.5.4': + resolution: {integrity: sha512-9HPaDp4SHzGFg1ABQQIsPjVFKPqLYrbIC8CLrsb4cLkK3BGMB+GSn4rTtP82rMmley0I2nHFkIzdXmbJvKcsPg==} peerDependencies: vite: ^5.0.0 || ^6.0.0 || ^7.0.0 vitest: ^1.3.1 || ^2.0.0 || ^3.0.0 || ^4.0.0 - '@nx/vitest@22.3.3': - resolution: {integrity: sha512-9BNwWadIfT5EAnEPXLM0n/ucuJ7IQyn+QRMUkUBt6wmms9f0OKMtLpiFxHIMrnQDf0eEk845jo21j7Og2cCZyA==} + '@nx/vitest@22.5.4': + resolution: {integrity: sha512-ppXeq3akwrwv0ftqeFK3VX2s9E70px5H335e81wnFtUmD/LZLB7CyGVM9cDJMTgXdQFcYq90C8fbsPgDSnoc/w==} peerDependencies: vite: ^5.0.0 || ^6.0.0 || ^7.0.0 vitest: ^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0 @@ -3378,11 +3458,11 @@ packages: vitest: optional: true - '@nx/web@22.3.3': - resolution: {integrity: sha512-0iuAxXCljxCAfQ5N4SffMuf0CuUFGJoO5nzOTqnZ60pRy+JIWZ+DXfh7bfHxTEcE3JQ6nT/hbZVLPMVNleoy7Q==} + '@nx/web@22.5.4': + resolution: {integrity: sha512-GH4+TLdFiw4RSUgPwn0KWcu6yHfMu23umidrgVgq9Dmj0fn3i/yfxvfdhMQ6aDiZr831b4tIbTQ7JLNd92ilIQ==} - '@nx/workspace@22.3.3': - resolution: {integrity: sha512-A7Qd1Yi/hp/VPvig6tV+JmlYVSA4WhckNkP1giYZoESpGLxRlpwINpd5ii3oafOlglUdEZ8AiS3X+RUg9QmCAQ==} + '@nx/workspace@22.5.4': + resolution: {integrity: sha512-TZeuCDy+VN/5zqMYxHw15HKe2Ppcb9WBOebz4bmXE206c8Aop3S9QeLfys00Uobt9ZaYh9QUeN0iFsZm7TNv0w==} '@octokit/auth-action@6.0.2': resolution: {integrity: sha512-gEBsz0QioHOMoEU7u2VMr2FfOvfJCrGc42K9rliS7LnlZJLcEMFccIiCiPpPNH+yXs7YYNKQ7lOX67ZTWn6Ysg==} @@ -3396,8 +3476,8 @@ packages: resolution: {integrity: sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==} engines: {node: '>= 20'} - '@octokit/endpoint@11.0.2': - resolution: {integrity: sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ==} + '@octokit/endpoint@11.0.3': + resolution: {integrity: sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==} engines: {node: '>= 20'} '@octokit/graphql@9.0.3': @@ -3429,8 +3509,8 @@ packages: resolution: {integrity: sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==} engines: {node: '>= 20'} - '@octokit/request@10.0.7': - resolution: {integrity: sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA==} + '@octokit/request@10.0.8': + resolution: {integrity: sha512-SJZNwY9pur9Agf7l87ywFi14W+Hd9Jg6Ifivsd33+/bGUQIjNujdFiXII2/qSlN2ybqUHfp5xpekMEjIBTjlSw==} engines: {node: '>= 20'} '@octokit/rest@22.0.1': @@ -3440,199 +3520,193 @@ packages: '@octokit/types@16.0.0': resolution: {integrity: sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==} - '@oxc-resolver/binding-android-arm-eabi@11.16.2': - resolution: {integrity: sha512-lVJbvydLQIDZHKUb6Zs9Rq80QVTQ9xdCQE30eC9/cjg4wsMoEOg65QZPymUAIVJotpUAWJD0XYcwE7ugfxx5kQ==} + '@oxc-resolver/binding-android-arm-eabi@11.19.1': + resolution: {integrity: sha512-aUs47y+xyXHUKlbhqHUjBABjvycq6YSD7bpxSW7vplUmdzAlJ93yXY6ZR0c1o1x5A/QKbENCvs3+NlY8IpIVzg==} cpu: [arm] os: [android] - '@oxc-resolver/binding-android-arm64@11.16.2': - resolution: {integrity: sha512-fEk+g/g2rJ6LnBVPqeLcx+/alWZ/Db1UlXG+ZVivip0NdrnOzRL48PAmnxTMGOrLwsH1UDJkwY3wOjrrQltCqg==} + '@oxc-resolver/binding-android-arm64@11.19.1': + resolution: {integrity: sha512-oolbkRX+m7Pq2LNjr/kKgYeC7bRDMVTWPgxBGMjSpZi/+UskVo4jsMU3MLheZV55jL6c3rNelPl4oD60ggYmqA==} cpu: [arm64] os: [android] - '@oxc-resolver/binding-darwin-arm64@11.16.2': - resolution: {integrity: sha512-Pkbp1qi7kdUX6k3Fk1PvAg6p7ruwaWKg1AhOlDgrg2vLXjtv9ZHo7IAQN6kLj0W771dPJZWqNxoqTPacp2oYWA==} + '@oxc-resolver/binding-darwin-arm64@11.19.1': + resolution: {integrity: sha512-nUC6d2i3R5B12sUW4O646qD5cnMXf2oBGPLIIeaRfU9doJRORAbE2SGv4eW6rMqhD+G7nf2Y8TTJTLiiO3Q/dQ==} cpu: [arm64] os: [darwin] - '@oxc-resolver/binding-darwin-x64@11.16.2': - resolution: {integrity: sha512-FYCGcU1iSoPkADGLfQbuj0HWzS+0ItjDCt9PKtu2Hzy6T0dxO4Y1enKeCOxCweOlmLEkSxUlW5UPT4wvT3LnAg==} + '@oxc-resolver/binding-darwin-x64@11.19.1': + resolution: {integrity: sha512-cV50vE5+uAgNcFa3QY1JOeKDSkM/9ReIcc/9wn4TavhW/itkDGrXhw9jaKnkQnGbjJ198Yh5nbX/Gr2mr4Z5jQ==} cpu: [x64] os: [darwin] - '@oxc-resolver/binding-freebsd-x64@11.16.2': - resolution: {integrity: sha512-1zHCoK6fMcBjE54P2EG/z70rTjcRxvyKfvk4E/QVrWLxNahuGDFZIxoEoo4kGnnEcmPj41F0c2PkrQbqlpja5g==} + '@oxc-resolver/binding-freebsd-x64@11.19.1': + resolution: {integrity: sha512-xZOQiYGFxtk48PBKff+Zwoym7ScPAIVp4c14lfLxizO2LTTTJe5sx9vQNGrBymrf/vatSPNMD4FgsaaRigPkqw==} cpu: [x64] os: [freebsd] - '@oxc-resolver/binding-linux-arm-gnueabihf@11.16.2': - resolution: {integrity: sha512-+ucLYz8EO5FDp6kZ4o1uDmhoP+M98ysqiUW4hI3NmfiOJQWLrAzQjqaTdPfIOzlCXBU9IHp5Cgxu6wPjVb8dbA==} + '@oxc-resolver/binding-linux-arm-gnueabihf@11.19.1': + resolution: {integrity: sha512-lXZYWAC6kaGe/ky2su94e9jN9t6M0/6c+GrSlCqL//XO1cxi5lpAhnJYdyrKfm0ZEr/c7RNyAx3P7FSBcBd5+A==} cpu: [arm] os: [linux] - '@oxc-resolver/binding-linux-arm-musleabihf@11.16.2': - resolution: {integrity: sha512-qq+TpNXyw1odDgoONRpMLzH4hzhwnEw55398dL8rhKGvvYbio71WrJ00jE+hGlEi7H1Gkl11KoPJRaPlRAVGPw==} + '@oxc-resolver/binding-linux-arm-musleabihf@11.19.1': + resolution: {integrity: sha512-veG1kKsuK5+t2IsO9q0DErYVSw2azvCVvWHnfTOS73WE0STdLLB7Q1bB9WR+yHPQM76ASkFyRbogWo1GR1+WbQ==} cpu: [arm] os: [linux] - '@oxc-resolver/binding-linux-arm64-gnu@11.16.2': - resolution: {integrity: sha512-xlMh4gNtplNQEwuF5icm69udC7un0WyzT5ywOeHrPMEsghKnLjXok2wZgAA7ocTm9+JsI+nVXIQa5XO1x+HPQg==} + '@oxc-resolver/binding-linux-arm64-gnu@11.19.1': + resolution: {integrity: sha512-heV2+jmXyYnUrpUXSPugqWDRpnsQcDm2AX4wzTuvgdlZfoNYO0O3W2AVpJYaDn9AG4JdM6Kxom8+foE7/BcSig==} cpu: [arm64] os: [linux] - '@oxc-resolver/binding-linux-arm64-musl@11.16.2': - resolution: {integrity: sha512-OZs33QTMi0xmHv/4P0+RAKXJTBk7UcMH5tpTaCytWRXls/DGaJ48jOHmriQGK2YwUqXl+oneuNyPOUO0obJ+Hg==} + '@oxc-resolver/binding-linux-arm64-musl@11.19.1': + resolution: {integrity: sha512-jvo2Pjs1c9KPxMuMPIeQsgu0mOJF9rEb3y3TdpsrqwxRM+AN6/nDDwv45n5ZrUnQMsdBy5gIabioMKnQfWo9ew==} cpu: [arm64] os: [linux] - '@oxc-resolver/binding-linux-ppc64-gnu@11.16.2': - resolution: {integrity: sha512-UVyuhaV32dJGtF6fDofOcBstg9JwB2Jfnjfb8jGlu3xcG+TsubHRhuTwQ6JZ1sColNT1nMxBiu7zdKUEZi1kwg==} + '@oxc-resolver/binding-linux-ppc64-gnu@11.19.1': + resolution: {integrity: sha512-vLmdNxWCdN7Uo5suays6A/+ywBby2PWBBPXctWPg5V0+eVuzsJxgAn6MMB4mPlshskYbppjpN2Zg83ArHze9gQ==} cpu: [ppc64] os: [linux] - '@oxc-resolver/binding-linux-riscv64-gnu@11.16.2': - resolution: {integrity: sha512-YZZS0yv2q5nE1uL/Fk4Y7m9018DSEmDNSG8oJzy1TJjA1jx5HL52hEPxi98XhU6OYhSO/vC1jdkJeE8TIHugug==} + '@oxc-resolver/binding-linux-riscv64-gnu@11.19.1': + resolution: {integrity: sha512-/b+WgR+VTSBxzgOhDO7TlMXC1ufPIMR6Vj1zN+/x+MnyXGW7prTLzU9eW85Aj7Th7CCEG9ArCbTeqxCzFWdg2w==} cpu: [riscv64] os: [linux] - '@oxc-resolver/binding-linux-riscv64-musl@11.16.2': - resolution: {integrity: sha512-9VYuypwtx4kt1lUcwJAH4dPmgJySh4/KxtAPdRoX2BTaZxVm/yEXHq0mnl/8SEarjzMvXKbf7Cm6UBgptm3DZw==} + '@oxc-resolver/binding-linux-riscv64-musl@11.19.1': + resolution: {integrity: sha512-YlRdeWb9j42p29ROh+h4eg/OQ3dTJlpHSa+84pUM9+p6i3djtPz1q55yLJhgW9XfDch7FN1pQ/Vd6YP+xfRIuw==} cpu: [riscv64] os: [linux] - '@oxc-resolver/binding-linux-s390x-gnu@11.16.2': - resolution: {integrity: sha512-3gbwQ+xlL5gpyzgSDdC8B4qIM4mZaPDLaFOi3c/GV7CqIdVJc5EZXW4V3T6xwtPBOpXPXfqQLbhTnUD4SqwJtA==} + '@oxc-resolver/binding-linux-s390x-gnu@11.19.1': + resolution: {integrity: sha512-EDpafVOQWF8/MJynsjOGFThcqhRHy417sRyLfQmeiamJ8qVhSKAn2Dn2VVKUGCjVB9C46VGjhNo7nOPUi1x6uA==} cpu: [s390x] os: [linux] - '@oxc-resolver/binding-linux-x64-gnu@11.16.2': - resolution: {integrity: sha512-m0WcK0j54tSwWa+hQaJMScZdWneqE7xixp/vpFqlkbhuKW9dRHykPAFvSYg1YJ3MJgu9ZzVNpYHhPKJiEQq57Q==} + '@oxc-resolver/binding-linux-x64-gnu@11.19.1': + resolution: {integrity: sha512-NxjZe+rqWhr+RT8/Ik+5ptA3oz7tUw361Wa5RWQXKnfqwSSHdHyrw6IdcTfYuml9dM856AlKWZIUXDmA9kkiBQ==} cpu: [x64] os: [linux] - '@oxc-resolver/binding-linux-x64-musl@11.16.2': - resolution: {integrity: sha512-ZjUm3w96P2t47nWywGwj1A2mAVBI/8IoS7XHhcogWCfXnEI3M6NPIRQPYAZW4s5/u3u6w1uPtgOwffj2XIOb/g==} + '@oxc-resolver/binding-linux-x64-musl@11.19.1': + resolution: {integrity: sha512-cM/hQwsO3ReJg5kR+SpI69DMfvNCp+A/eVR4b4YClE5bVZwz8rh2Nh05InhwI5HR/9cArbEkzMjcKgTHS6UaNw==} cpu: [x64] os: [linux] - '@oxc-resolver/binding-openharmony-arm64@11.16.2': - resolution: {integrity: sha512-OFVQ2x3VenTp13nIl6HcQ/7dmhFmM9dg2EjKfHcOtYfrVLQdNR6THFU7GkMdmc8DdY1zLUeilHwBIsyxv5hkwQ==} + '@oxc-resolver/binding-openharmony-arm64@11.19.1': + resolution: {integrity: sha512-QF080IowFB0+9Rh6RcD19bdgh49BpQHUW5TajG1qvWHvmrQznTZZjYlgE2ltLXyKY+qs4F/v5xuX1XS7Is+3qA==} cpu: [arm64] os: [openharmony] - '@oxc-resolver/binding-wasm32-wasi@11.16.2': - resolution: {integrity: sha512-+O1sY3RrGyA2AqDnd3yaDCsqZqCblSTEpY7TbbaOaw0X7iIbGjjRLdrQk9StG3QSiZuBy9FdFwotIiSXtwvbAQ==} + '@oxc-resolver/binding-wasm32-wasi@11.19.1': + resolution: {integrity: sha512-w8UCKhX826cP/ZLokXDS6+milN8y4X7zidsAttEdWlVoamTNf6lhBJldaWr3ukTDiye7s4HRcuPEPOXNC432Vg==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@oxc-resolver/binding-win32-arm64-msvc@11.16.2': - resolution: {integrity: sha512-jMrMJL+fkx6xoSMFPOeyQ1ctTFjavWPOSZEKUY5PebDwQmC9cqEr4LhdTnGsOtFrWYLXlEU4xWeMdBoc/XKkOA==} + '@oxc-resolver/binding-win32-arm64-msvc@11.19.1': + resolution: {integrity: sha512-nJ4AsUVZrVKwnU/QRdzPCCrO0TrabBqgJ8pJhXITdZGYOV28TIYystV1VFLbQ7DtAcaBHpocT5/ZJnF78YJPtQ==} cpu: [arm64] os: [win32] - '@oxc-resolver/binding-win32-ia32-msvc@11.16.2': - resolution: {integrity: sha512-tl0xDA5dcQplG2yg2ZhgVT578dhRFafaCfyqMEAXq8KNpor85nJ53C3PLpfxD2NKzPioFgWEexNsjqRi+kW2Mg==} + '@oxc-resolver/binding-win32-ia32-msvc@11.19.1': + resolution: {integrity: sha512-EW+ND5q2Tl+a3pH81l1QbfgbF3HmqgwLfDfVithRFheac8OTcnbXt/JxqD2GbDkb7xYEqy1zNaVFRr3oeG8npA==} cpu: [ia32] os: [win32] - '@oxc-resolver/binding-win32-x64-msvc@11.16.2': - resolution: {integrity: sha512-M7z0xjYQq1HdJk2DxTSLMvRMyBSI4wn4FXGcVQBsbAihgXevAReqwMdb593nmCK/OiFwSNcOaGIzUvzyzQ+95w==} + '@oxc-resolver/binding-win32-x64-msvc@11.19.1': + resolution: {integrity: sha512-6hIU3RQu45B+VNTY4Ru8ppFwjVS/S5qwYyGhBotmjxfEKk41I2DlGtRfGJndZ5+6lneE2pwloqunlOyZuX/XAw==} cpu: [x64] os: [win32] - '@parcel/watcher-android-arm64@2.5.1': - resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==} + '@parcel/watcher-android-arm64@2.5.6': + resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [android] - '@parcel/watcher-darwin-arm64@2.5.1': - resolution: {integrity: sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==} + '@parcel/watcher-darwin-arm64@2.5.6': + resolution: {integrity: sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [darwin] - '@parcel/watcher-darwin-x64@2.5.1': - resolution: {integrity: sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==} + '@parcel/watcher-darwin-x64@2.5.6': + resolution: {integrity: sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [darwin] - '@parcel/watcher-freebsd-x64@2.5.1': - resolution: {integrity: sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==} + '@parcel/watcher-freebsd-x64@2.5.6': + resolution: {integrity: sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [freebsd] - '@parcel/watcher-linux-arm-glibc@2.5.1': - resolution: {integrity: sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==} + '@parcel/watcher-linux-arm-glibc@2.5.6': + resolution: {integrity: sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==} engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] - '@parcel/watcher-linux-arm-musl@2.5.1': - resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==} + '@parcel/watcher-linux-arm-musl@2.5.6': + resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==} engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] - '@parcel/watcher-linux-arm64-glibc@2.5.1': - resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==} + '@parcel/watcher-linux-arm64-glibc@2.5.6': + resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] - '@parcel/watcher-linux-arm64-musl@2.5.1': - resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==} + '@parcel/watcher-linux-arm64-musl@2.5.6': + resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] - '@parcel/watcher-linux-x64-glibc@2.5.1': - resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==} + '@parcel/watcher-linux-x64-glibc@2.5.6': + resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] - '@parcel/watcher-linux-x64-musl@2.5.1': - resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==} + '@parcel/watcher-linux-x64-musl@2.5.6': + resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] - '@parcel/watcher-win32-arm64@2.5.1': - resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==} + '@parcel/watcher-win32-arm64@2.5.6': + resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [win32] - '@parcel/watcher-win32-ia32@2.5.1': - resolution: {integrity: sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==} + '@parcel/watcher-win32-ia32@2.5.6': + resolution: {integrity: sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==} engines: {node: '>= 10.0.0'} cpu: [ia32] os: [win32] - '@parcel/watcher-win32-x64@2.5.1': - resolution: {integrity: sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==} + '@parcel/watcher-win32-x64@2.5.6': + resolution: {integrity: sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [win32] - '@parcel/watcher@2.5.1': - resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} + '@parcel/watcher@2.5.6': + resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==} engines: {node: '>= 10.0.0'} - '@phenomnomnominal/tsquery@5.0.1': - resolution: {integrity: sha512-3nVv+e2FQwsW8Aw6qTU6f+1rfcJ3hrcnvH/mu9i8YhxO+9sqbOfpL8m6PbET5+xKOlz/VSbp0RoYWYCtIsnmuA==} + '@phenomnomnominal/tsquery@6.1.4': + resolution: {integrity: sha512-3tHlGy/fxjJCHqIV8nelAzbRTNkCUY+k7lqBGKNuQz99H2OKGRt6oU+U2SZs6LYrbOe8mxMFl6kq6gzHapFRkw==} peerDependencies: typescript: ^3 || ^4 || ^5 - '@pivanov/utils@0.0.2': - resolution: {integrity: sha512-q9CN0bFWxWgMY5hVVYyBgez1jGiLBa6I+LkG37ycylPhFvEGOOeaADGtUSu46CaZasPnlY8fCdVJZmrgKb1EPA==} - peerDependencies: - react: '>=18' - react-dom: '>=18' - '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -3641,11 +3715,11 @@ packages: resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@preact/signals-core@1.12.1': - resolution: {integrity: sha512-BwbTXpj+9QutoZLQvbttRg5x3l5468qaV2kufh+51yha1c53ep5dY4kTuZR35+3pAZxpfQerGJiQqg34ZNZ6uA==} + '@preact/signals-core@1.13.0': + resolution: {integrity: sha512-slT6XeTCAbdql61GVLlGU4x7XHI7kCZV5Um5uhE4zLX4ApgiiXc0UYFvVOKq06xcovzp7p+61l68oPi563ARKg==} - '@preact/signals@1.3.2': - resolution: {integrity: sha512-naxcJgUJ6BTOROJ7C3QML7KvwKwCXQJYTc5L/b0eEsdYgPB6SxwoQ1vDGcS0Q7GVjAenVq/tXrybVdFShHYZWg==} + '@preact/signals@1.3.4': + resolution: {integrity: sha512-TPMkStdT0QpSc8FpB63aOwXoSiZyIrPsP9Uj347KopdS6olZdAYeeird/5FZv/M1Yc1ge5qstub2o8VDbvkT4g==} peerDependencies: preact: 10.x @@ -3663,134 +3737,171 @@ packages: prisma: optional: true - '@react-aria/autocomplete@3.0.0-rc.4': - resolution: {integrity: sha512-4bMMVNaCuYDZX9HM4ZNSAImZMcL/orwhLLe818+lyzmSrvGmW9h433PZxTolb0d+FnJVfn1MDY0zEWLiyI86GA==} + '@prisma/config@7.4.2': + resolution: {integrity: sha512-CftBjWxav99lzY1Z4oDgomdb1gh9BJFAOmWF6P2v1xRfXqQb56DfBub+QKcERRdNoAzCb3HXy3Zii8Vb4AsXhg==} + + '@prisma/debug@7.2.0': + resolution: {integrity: sha512-YSGTiSlBAVJPzX4ONZmMotL+ozJwQjRmZweQNIq/ER0tQJKJynNkRB3kyvt37eOfsbMCXk3gnLF6J9OJ4QWftw==} + + '@prisma/debug@7.4.2': + resolution: {integrity: sha512-aP7qzu+g/JnbF6U69LMwHoUkELiserKmWsE2shYuEpNUJ4GrtxBCvZwCyCBHFSH2kLTF2l1goBlBh4wuvRq62w==} + + '@prisma/dev@0.20.0': + resolution: {integrity: sha512-ovlBYwWor0OzG+yH4J3Ot+AneD818BttLA+Ii7wjbcLHUrnC4tbUPVGyNd3c/+71KETPKZfjhkTSpdS15dmXNQ==} + + '@prisma/engines-version@7.5.0-10.94a226be1cf2967af2541cca5529f0f7ba866919': + resolution: {integrity: sha512-5FIKY3KoYQlBuZC2yc16EXfVRQ8HY+fLqgxkYfWCtKhRb3ajCRzP/rPeoSx11+NueJDANdh4hjY36mdmrTcGSg==} + + '@prisma/engines@7.4.2': + resolution: {integrity: sha512-B+ZZhI4rXlzjVqRw/93AothEKOU5/x4oVyJFGo9RpHPnBwaPwk4Pi0Q4iGXipKxeXPs/dqljgNBjK0m8nocOJA==} + + '@prisma/fetch-engine@7.4.2': + resolution: {integrity: sha512-f/c/MwYpdJO7taLETU8rahEstLeXfYgQGlz5fycG7Fbmva3iPdzGmjiSWHeSWIgNnlXnelUdCJqyZnFocurZuA==} + + '@prisma/get-platform@7.2.0': + resolution: {integrity: sha512-k1V0l0Td1732EHpAfi2eySTezyllok9dXb6UQanajkJQzPUGi3vO2z7jdkz67SypFTdmbnyGYxvEvYZdZsMAVA==} + + '@prisma/get-platform@7.4.2': + resolution: {integrity: sha512-UTnChXRwiauzl/8wT4hhe7Xmixja9WE28oCnGpBtRejaHhvekx5kudr3R4Y9mLSA0kqGnAMeyTiKwDVMjaEVsw==} + + '@prisma/query-plan-executor@7.2.0': + resolution: {integrity: sha512-EOZmNzcV8uJ0mae3DhTsiHgoNCuu1J9mULQpGCh62zN3PxPTd+qI9tJvk5jOst8WHKQNwJWR3b39t0XvfBB0WQ==} + + '@prisma/studio-core@0.13.1': + resolution: {integrity: sha512-agdqaPEePRHcQ7CexEfkX1RvSH9uWDb6pXrZnhCRykhDFAV0/0P3d07WtfiY8hZWb7oRU4v+NkT4cGFHkQJIPg==} + peerDependencies: + '@types/react': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@react-aria/autocomplete@3.0.0-rc.6': + resolution: {integrity: sha512-uymUNJ8NW+dX7lmgkHE+SklAbxwktycAJcI5lBBw6KPZyc0EdMHC+/Fc5CUz3enIAhNwd2oxxogcSHknquMzQA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/breadcrumbs@3.5.30': - resolution: {integrity: sha512-DZymglA70SwvDJA7GB147sUexvdDy6vWcriGrlEHhMMzBLhGB30I5J96R4pPzURLxXISrWFH56KC5rRgIqsqqg==} + '@react-aria/breadcrumbs@3.5.32': + resolution: {integrity: sha512-S61vh5DJ2PXiXUwD7gk+pvS/b4VPrc3ZJOUZ0yVRLHkVESr5LhIZH+SAVgZkm1lzKyMRG+BH+fiRH/DZRSs7SA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/button@3.14.3': - resolution: {integrity: sha512-iJTuEECs9im7TwrCRZ0dvuwp8Gao0+I1IuYs1LQvJQgKLpgRH2/6jAiqb2bdAcoAjdbaMs7Xe0xUwURpVNkEyA==} + '@react-aria/button@3.14.5': + resolution: {integrity: sha512-ZuLx+wQj9VQhH9BYe7t0JowmKnns2XrFHFNvIVBb5RwxL+CIycIOL7brhWKg2rGdxvlOom7jhVbcjSmtAaSyaQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/calendar@3.9.3': - resolution: {integrity: sha512-F12UQ4zd8GIxpJxs9GAHzDD9Lby2hESHm0LF5tjsYBIOBJc5K7ICeeE5UqLMBPzgnEP5nfh1CKS8KhCB0mS7PA==} + '@react-aria/calendar@3.9.5': + resolution: {integrity: sha512-k0kvceYdZZu+DoeqephtlmIvh1CxqdFyoN52iqVzTz9O0pe5Xfhq7zxPGbeCp4pC61xzp8Lu/6uFA/YNfQQNag==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/checkbox@3.16.3': - resolution: {integrity: sha512-2p1haCUtERo5XavBAWNaX//dryNVnOOWfSKyzLs4UiCZR/NL0ttN+Nu/i445q0ipjLqZ6bBJtx0g0NNrubbU7Q==} + '@react-aria/checkbox@3.16.5': + resolution: {integrity: sha512-ZhUT7ELuD52hb+Zpzw0ElLQiVOd5sKYahrh+PK3vq13Wk5TedBscALpjuXetI4pwFfdmAM1Lhgcsrd8+6AmyvA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/collections@3.0.1': - resolution: {integrity: sha512-C8KBQGXzVefR4I+hQmkb10t09Jt1Ivl12qgQKshmT0hV2yBESXEYWMZUxV4ggOgWDreAgCtr+Ho3X+7MzBQT8Q==} + '@react-aria/collections@3.0.3': + resolution: {integrity: sha512-lbC5DEbHeVFvVr4ke9y8D9Nynnr8G8UjVEBoFGRylpAaScU7SX1TN84QI+EjMbsdZ0/5P2H7gUTS+MYd+6U3Rg==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/color@3.1.3': - resolution: {integrity: sha512-EHzsFbqzFrO1/3irEa8E8wawlQg7hRd4/Jscvl9zhplAcrWFd6L5TWl8463Z6h0J6zN1eH9T2QDEn6rivDLkkg==} + '@react-aria/color@3.1.5': + resolution: {integrity: sha512-eysWdBRzE8WDhBzh1nfjyUgzseMokXGHjIoJo880T7IPJ8tTavfQni49pU1B2qWrNOWPyrwx4Bd9pzHyboxJSA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/combobox@3.14.1': - resolution: {integrity: sha512-wuP/4UQrGsYXLw1Gk8G/FcnUlHuoViA9G6w3LhtUgu5Q3E5DvASJalxej3NtyYU+4w4epD1gJidzosAL0rf8Ug==} + '@react-aria/combobox@3.15.0': + resolution: {integrity: sha512-qSjQTFwKl3x1jCP2NRSJ6doZqAp6c2GTfoiFwWjaWg1IewwLsglaW6NnzqRDFiqFbDGgXPn4MqtC1VYEJ3NEjA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/datepicker@3.15.3': - resolution: {integrity: sha512-0KkLYeLs+IubHXb879n8dzzKU/NWcxC9DXtv7M/ofL7vAvMSTmaceYJcMW+2gGYhJVpyYz8B6bk0W7kTxgB3jg==} + '@react-aria/datepicker@3.16.1': + resolution: {integrity: sha512-6BltCVWt09yefTkGjb2gViGCwoddx9HKJiZbY9u6Es/Q+VhwNJQRtczbnZ3K32p262hIknukNf/5nZaCOI1AKA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/dialog@3.5.32': - resolution: {integrity: sha512-2puMjsJS2FtB8LiFuQDAdBSU4dt3lqdJn4FWt/8GL6l91RZBqp2Dnm5Obuee6rV2duNJZcSAUWsQZ/S1iW8Y2g==} + '@react-aria/dialog@3.5.34': + resolution: {integrity: sha512-/x53Q5ynpW5Kv9637WYu7SrDfj3woSp6jJRj8l6teGnWW/iNZWYJETgzHfbxx+HPKYATCZesRoIeO2LnYIXyEA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/disclosure@3.1.1': - resolution: {integrity: sha512-4k8Y3CZEl+Qhou0fH7Sj7BbzvwAfi1JDL+hG7U20ZL5+MJ/VbDYuYX2gYK2KqdlbeuuzGcov3ZFQbyIVHMY+/A==} + '@react-aria/disclosure@3.1.3': + resolution: {integrity: sha512-S3k7Wqrj+x0sWcP88Z1stSr5TIZmKEmx2rU7RB1O1/jPpbw5mgKnjtiriOlTh+kwdK11FkeqgxyHzAcBAR+FMQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/dnd@3.11.4': - resolution: {integrity: sha512-dBrnM33Kmk76F+Pknh2WfSLIX4dsYwFzWJUIABJCPmPc80hTG0so7mfqH45ba759/6ERMfXXoodZPLtypOjYPg==} + '@react-aria/dnd@3.11.6': + resolution: {integrity: sha512-4YLHUeYJleF+moAYaYt8UZqujudPvpoaHR+QMkWIFzhfridVUhCr6ZjGWrzpSZY3r68k46TG7YCsi4IEiNnysw==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/focus@3.21.3': - resolution: {integrity: sha512-FsquWvjSCwC2/sBk4b+OqJyONETUIXQ2vM0YdPAuC+QFQh2DT6TIBo6dOZVSezlhudDla69xFBd6JvCFq1AbUw==} + '@react-aria/focus@3.21.5': + resolution: {integrity: sha512-V18fwCyf8zqgJdpLQeDU5ZRNd9TeOfBbhLgmX77Zr5ae9XwaoJ1R3SFJG1wCJX60t34AW+aLZSEEK+saQElf3Q==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/form@3.1.3': - resolution: {integrity: sha512-HAKnPjMiqTxoGLVbfZyGYcZQ1uu6aSeCi9ODmtZuKM5DWZZnTUjDmM1i2L6IXvF+d1kjyApyJC7VTbKZ8AI77g==} + '@react-aria/form@3.1.5': + resolution: {integrity: sha512-BWlONgHn8hmaMkcS6AgMSLQeNqVBwqPNLhdqjDO/PCfzvV7O8NZw/dFeIzJwfG4aBfSpbHHRdXGdfrk3d8dylQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/grid@3.14.6': - resolution: {integrity: sha512-xagBKHNPu4Ovt/I5He7T/oIEq82MDMSrRi5Sw3oxSCwwtZpv+7eyKRSrFz9vrNUzNgWCcx5VHLE660bLdeVNDQ==} + '@react-aria/grid@3.14.8': + resolution: {integrity: sha512-X6rRFKDu/Kh6Sv8FBap3vjcb+z4jXkSOwkYnexIJp5kMTo5/Dqo55cCBio5B70Tanfv32Ev/6SpzYG7ryxnM9w==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/gridlist@3.14.2': - resolution: {integrity: sha512-c51ip0bc/lKppfrPNFHbWu1n/r0NHd9Xl114904cDxuRcElJ3H/V/3e3U9HyDy+4xioiXZIdZ75CNxtEoTmrxw==} + '@react-aria/gridlist@3.14.4': + resolution: {integrity: sha512-C/SbwC0qagZatoBrCjx8iZUex9apaJ8o8iRJ9eVHz0cpj7mXg6HuuotYGmDy9q67A2hve4I693RM1Cuwqwm+PQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/i18n@3.12.14': - resolution: {integrity: sha512-zYvs1FlLamFD49uneX3i5mPHrAsB3OjVpSWApTcPw8ydxOaphQDp/Q1aqrbcxlrQCcxZdXWHuvLlbkNR4+8jzw==} + '@react-aria/i18n@3.12.16': + resolution: {integrity: sha512-Km2CAz6MFQOUEaattaW+2jBdWOHUF8WX7VQoNbjlqElCP58nSaqi9yxTWUDRhAcn8/xFUnkFh4MFweNgtrHuEA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/interactions@3.26.0': - resolution: {integrity: sha512-AAEcHiltjfbmP1i9iaVw34Mb7kbkiHpYdqieWufldh4aplWgsF11YQZOfaCJW4QoR2ML4Zzoa9nfFwLXA52R7Q==} + '@react-aria/interactions@3.27.1': + resolution: {integrity: sha512-M3wLpTTmDflI0QGNK0PJNUaBXXfeBXue8ZxLMngfc1piHNiH4G5lUvWd9W14XVbqrSCVY8i8DfGrNYpyyZu0tw==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/label@3.7.23': - resolution: {integrity: sha512-dRkuCJfsyBHPTq3WOJVHNRvNyQL4cRRLELmjYfUX9/jQKIsUW2l71YnUHZTRCSn2ZjhdAcdwq96fNcQo0hncBQ==} + '@react-aria/label@3.7.25': + resolution: {integrity: sha512-oNK3Pqj4LDPwEbQaoM/uCip4QvQmmwGOh08VeW+vzSi6TAwf+KoWTyH/tiAeB0CHWNDK0k3e1iTygTAt4wzBmg==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/landmark@3.0.8': - resolution: {integrity: sha512-xuY8kYxCrF9C0h0Pj2lZHoxCidNfQ/SrkYWXuiN+LuBTJGCmPVif93gt7TklQ0rKJ+pKJsUgh8AC0pgwI3QP7A==} + '@react-aria/landmark@3.0.10': + resolution: {integrity: sha512-GpNjJaI8/a6WxYDZgzTCLYSzPM6xp2pxCIQ4udiGbTCtxx13Trmm0cPABvPtzELidgolCf05em9Phr+3G0eE8A==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/link@3.8.7': - resolution: {integrity: sha512-TOC6Hf/x3N0P8SLR1KD/dGiJ9PmwAq8H57RiwbFbdINnG/HIvIQr5MxGTjwBvOOWcJu9brgWL5HkQaZK7Q/4Yw==} + '@react-aria/link@3.8.9': + resolution: {integrity: sha512-UaAFBfs84/Qq6TxlMWkREqqNY6SFLukot+z2Aa1kC+VyStv1kWG6sE5QLjm4SBn1Q3CGRsefhB/5+taaIbB4Pw==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/listbox@3.15.1': - resolution: {integrity: sha512-81iDLFhmPXvLOtkI0SKzgrngfzwfR2o9oFDAYRfpYCOxgT7jjh8SaB4wCteJXRiMwymRGmgyTvD4yxWTluEeXA==} + '@react-aria/listbox@3.15.3': + resolution: {integrity: sha512-C6YgiyrHS5sbS5UBdxGMhEs+EKJYotJgGVtl9l0ySXpBUXERiHJWLOyV7a8PwkUOmepbB4FaLD7Y9EUzGkrGlw==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 @@ -3798,74 +3909,74 @@ packages: '@react-aria/live-announcer@3.4.4': resolution: {integrity: sha512-PTTBIjNRnrdJOIRTDGNifY2d//kA7GUAwRFJNOEwSNG4FW+Bq9awqLiflw0JkpyB0VNIwou6lqKPHZVLsGWOXA==} - '@react-aria/menu@3.19.4': - resolution: {integrity: sha512-0A0DUEkEvZynmaD3zktHavM+EmgZSR/ht+g1ExS2jXe73CegA+dbSRfPl9eIKcHxaRrWOV96qMj2pTf0yWTBDg==} + '@react-aria/menu@3.21.0': + resolution: {integrity: sha512-CKTVZ4izSE1eKIti6TbTtzJAUo+WT8O4JC0XZCYDBpa0f++lD19Kz9aY+iY1buv5xGI20gAfpO474E9oEd4aQA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/meter@3.4.28': - resolution: {integrity: sha512-elACITUBOf4Dp+BQ2aIgHIe58fjWYjspxhVcE5BMiqePktOfRkpb9ESj8nWcNXO8eqCYwrFJpElHvXkjYLWemw==} + '@react-aria/meter@3.4.30': + resolution: {integrity: sha512-ZmANKW7s/Z4QGylHi46nhwtQ47T1bfMsU9MysBu7ViXXNJ03F4b6JXCJlKL5o2goQ3NbfZ68GeWamIT0BWSgtw==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/numberfield@3.12.3': - resolution: {integrity: sha512-70LRXWPEuj2X8mbQXUx6l6We+RGs49Kb+2eUiSSLArHK4RvTWJWEfSjHL5IHHJ+j2AkbORdryD7SR3gcXSX+5w==} + '@react-aria/numberfield@3.12.5': + resolution: {integrity: sha512-Fi41IUWXEHLFIeJ/LHuZ9Azs8J/P563fZi37GSBkIq5P1pNt1rPgJJng5CNn4KsHxwqadTRUlbbZwbZraWDtRg==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/overlays@3.31.0': - resolution: {integrity: sha512-Vq41X1s8XheGIhGbbuqRJslJEX08qmMVX//dwuBaFX9T18mMR04tumKOMxp8Lz+vqwdGLvjNUYDMcgolL+AMjw==} + '@react-aria/overlays@3.31.2': + resolution: {integrity: sha512-78HYI08r6LvcfD34gyv19ArRIjy1qxOKuXl/jYnjLDyQzD4pVb634IQWcm0zt10RdKgyuH6HTqvuDOgZTLet7Q==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/progress@3.4.28': - resolution: {integrity: sha512-3NUUAu+rwf1M7pau9WFkrxe/PlBPiqCl/1maGU7iufVveHnz+SVVqXdNkjYx+WkPE0ViwG86Zx6OU4AYJ1pjNw==} + '@react-aria/progress@3.4.30': + resolution: {integrity: sha512-S6OWVGgluSWYSd/A6O8CVjz83eeMUfkuWSra0ewAV9bmxZ7TP9pUmD3bGdqHZEl97nt5vHGjZ3eq/x8eCmzKhA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/radio@3.12.3': - resolution: {integrity: sha512-noucVX++9J3VYWg7dB+r09NVX8UZSR1TWUMCbT/MffzhltOsmiLJVvgJ0uEeeVRuu3+ZM63jOshrzG89anX4TQ==} + '@react-aria/radio@3.12.5': + resolution: {integrity: sha512-8CCJKJzfozEiWBPO9QAATG1rBGJEJ+xoqvHf9LKU2sPFGsA2/SRnLs6LB9fCG5R3spvaK1xz0any1fjWPl7x8A==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/searchfield@3.8.10': - resolution: {integrity: sha512-1wMoSjXoekcETC4ZP5AUcWoaK96FssVuF9MgqQNqE5VnauQDjZBpPCfz6GSZwRHTGwoqb7CI4iEi7433kd50xg==} + '@react-aria/searchfield@3.8.12': + resolution: {integrity: sha512-kYlUHD/+mWzNroHoR8ojUxYBoMviRZn134WaKPFjfNUGZDOEuh4XzOoj+cjdJfe6N3mwTaYu6rJQtunSHIAfhA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/select@3.17.1': - resolution: {integrity: sha512-jPMuaSp+4SbdE9G5UrrTer2CPbbUnUSLd8I2wgRgGcyk3wFw9DtnUNfms+UBA/2SrVnAEJ6KCQAI0oiMK2m+tQ==} + '@react-aria/select@3.17.3': + resolution: {integrity: sha512-u0UFWw0S7q9oiSbjetDpRoLLIcC+L89uYlm+YfCrdT8ntbQgABNiJRxdVvxnhR0fR6MC9ASTTvuQnNHNn52+1A==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/selection@3.27.0': - resolution: {integrity: sha512-4zgreuCu4QM4t2U7aF3mbMvIKCEkTEo6h6nGJvbyZALZ/eFtLTvUiV8/5CGDJRLGvgMvi3XxUeF9PZbpk5nMJg==} + '@react-aria/selection@3.27.2': + resolution: {integrity: sha512-GbUSSLX/ciXix95KW1g+SLM9np7iXpIZrFDSXkC6oNx1uhy18eAcuTkeZE25+SY5USVUmEzjI3m/3JoSUcebbg==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/separator@3.4.14': - resolution: {integrity: sha512-a32OB5HMAmXEdExyDvsadsnlmNcVxxpx3tt+Jxxl6H9CHsLO+Ak077KGFJteGVg4bTfhWGAgczOsnvIioR88xw==} + '@react-aria/separator@3.4.16': + resolution: {integrity: sha512-RCUtQhDGnPxKzyG8KM79yOB0fSiEf8r/rxShidOVnGLiBW2KFmBa22/Gfc4jnqg/keN3dxvkSGoqmeXgctyp6g==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/slider@3.8.3': - resolution: {integrity: sha512-tOZVH+wLt3ik0C3wyuXqHL9fvnQ5S+/tHMYB7z8aZV5cEe36Gt4efBILphlA7ChkL/RvpHGK2AGpEGxvuEQIuQ==} + '@react-aria/slider@3.8.5': + resolution: {integrity: sha512-gqkJxznk141mE0JamXF5CXml9PDbPkBz8dyKlihtWHWX4yhEbVYdC9J0otE7iCR3zx69Bm7WHoTGL0BsdpKzVA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/spinbutton@3.7.0': - resolution: {integrity: sha512-FOyH94BZp+jNhUJuZqXSubQZDNQEJyW/J19/gwCxQvQvxAP79dhDFshh1UtrL4EjbjIflmaOes+sH/XEHUnJVA==} + '@react-aria/spinbutton@3.7.2': + resolution: {integrity: sha512-adjE1wNCWlugvAtVXlXWPtIG9JWurEgYVn1Eeyh19x038+oXGvOsOAoKCXM+SnGleTWQ9J7pEZITFoEI3cVfAw==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 @@ -3876,80 +3987,80 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/switch@3.7.9': - resolution: {integrity: sha512-RZtuFRXews0PBx8Fc2R/kqaIARD5YIM5uYtmwnWfY7y5bEsBGONxp0d+m2vDyY7yk+VNpVFBdwewY9GbZmH1CA==} + '@react-aria/switch@3.7.11': + resolution: {integrity: sha512-dYVX71HiepBsKyeMaQgHbhqI+MQ3MVoTd5EnTbUjefIBnmQZavYj1/e4NUiUI4Ix+/C0HxL8ibDAv4NlSW3eLQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/table@3.17.9': - resolution: {integrity: sha512-Jby561E1YfzoRgtp+RQuhDz4vnxlcqol9RTgQQ7FWXC2IcN9Pny1COU34LkA1cL9VeB9LJ0+qfMhGw4aAwaUmw==} + '@react-aria/table@3.17.11': + resolution: {integrity: sha512-GkYmWPiW3OM+FUZxdS33teHXHXde7TjHuYgDDaG9phvg6cQTQjGilJozrzA3OfftTOq5VB8XcKTIQW3c0tpYsQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/tabs@3.10.9': - resolution: {integrity: sha512-2+FNd7Ohr3hrEgYrKdZW0FWbgybzTVZft6tw95oQ2+9PnjdDVdtzHliI+8HY8jzb4hTf4bU7O8n+s/HBlCBSIw==} + '@react-aria/tabs@3.11.1': + resolution: {integrity: sha512-3Ppz7yaEDW9L7p9PE9yNOl5caLwNnnLQqI+MX/dwbWlw9HluHS7uIjb21oswNl6UbSxAWyENOka45+KN4Fkh7A==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/tag@3.7.3': - resolution: {integrity: sha512-fonqGFxhpnlIDOz3u38y4+MG5wyAef9+oDybsCKaJ57K+D4BTvSmpGBemN/mcaxdabnYfyhasCm0H91Q9XRcCA==} + '@react-aria/tag@3.8.1': + resolution: {integrity: sha512-VonpO++F8afXGDWc9VUxAc2wefyJpp1n9OGpbnB7zmqWiuPwO/RixjUdcH7iJkiC4vADwx9uLnhyD6kcwGV2ig==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/textfield@3.18.3': - resolution: {integrity: sha512-ehiSHOKuKCwPdxFe7wGE0QJlSeeJR4iJuH+OdsYVlZzYbl9J/uAdGbpsj/zPhNtBo1g/Td76U8TtTlYRZ8lUZw==} + '@react-aria/textfield@3.18.5': + resolution: {integrity: sha512-ttwVSuwoV3RPaG2k2QzEXKeQNQ3mbdl/2yy6I4Tjrn1ZNkYHfVyJJ26AjenfSmj1kkTQoSAfZ8p+7rZp4n0xoQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/toast@3.0.9': - resolution: {integrity: sha512-2sRitczXl5VEwyq97o8TVvq3bIqLA7EfA7dhDPkYlHGa4T1vzKkhNqgkskKd9+Tw7gqeFRFjnokh+es9jkM11g==} + '@react-aria/toast@3.0.11': + resolution: {integrity: sha512-2DjZjBAvm8/CWbnZ6s7LjkYCkULKtjMve6GvhPTq98AthuEDLEiBvM1wa3xdecCRhZyRT1g6DXqVca0EfZ9fJA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/toggle@3.12.3': - resolution: {integrity: sha512-mciUbeVP99fRObnH5qLFrkKXX+5VKeV6BhFJlmz1eo3ltR/0xZKnUcycA2CGzmqtB70w09CAhr8NMEnpNH8dwQ==} + '@react-aria/toggle@3.12.5': + resolution: {integrity: sha512-XXVFLzcV8fr9mz7y/wfxEAhWvaBZ9jSfhCMuxH2bsivO7nTcMJ1jb4g2xJNwZgne17bMWNc7mKvW5dbsdlI6BA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/toolbar@3.0.0-beta.22': - resolution: {integrity: sha512-Q1gOj6N4vzvpGrIoNAxpUudEQP82UgQACENH/bcH8FnEMbSP7DHvVfDhj7GTU6ldMXO2cjqLhiidoUK53gkCiA==} + '@react-aria/toolbar@3.0.0-beta.24': + resolution: {integrity: sha512-B2Rmpko7Ghi2RbNfsGdbR7I+RQBDhPGVE4bU3/EwHz+P/vNe5LyGPTeSwqaOMsQTF9lKNCkY8424dVTCr6RUMg==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/tooltip@3.9.0': - resolution: {integrity: sha512-2O1DXEV8/+DeUq9dIlAfaNa7lSG+7FCZDuF+sNiPYnZM6tgFOrsId26uMF5EuwpVfOvXSSGnq0+6Ma2On7mZPg==} + '@react-aria/tooltip@3.9.2': + resolution: {integrity: sha512-VrgkPwHiEnAnBhoQ4W7kfry/RfVuRWrUPaJSp0+wKM6u0gg2tmn7OFRDXTxBAm/omQUguIdIjRWg7sf3zHH82A==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/tree@3.1.5': - resolution: {integrity: sha512-FAq7pAhRVrWU0U/8QbQIJfBqHuoCD+F9rR9ruoM3oL0vVIZxVN57ak/dhyge3EGlraTl9vzFi6IRceXiMuk5kg==} + '@react-aria/tree@3.1.7': + resolution: {integrity: sha512-C54yH5NmsOFa2Q+cg6B1BPr5KUlU9vLIoBnVrgrH237FRSXQPIbcM4VpmITAHq1VR7w6ayyS1hgTwFxo67ykWQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/utils@3.32.0': - resolution: {integrity: sha512-/7Rud06+HVBIlTwmwmJa2W8xVtgxgzm0+kLbuFooZRzKDON6hhozS1dOMR/YLMxyJOaYOTpImcP4vRR9gL1hEg==} + '@react-aria/utils@3.33.1': + resolution: {integrity: sha512-kIx1Sj6bbAT0pdqCegHuPanR9zrLn5zMRiM7LN12rgRf55S19ptd9g3ncahArifYTRkfEU9VIn+q0HjfMqS9/w==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/virtualizer@4.1.11': - resolution: {integrity: sha512-eYL//bX11Aox4Eh1BSZFX4I/4EdyVVWLjmpW+Y5qy4WajNrowjiuJJM7Fp1rQBlOAVuz0KbaDmFhiU3Z3rWjsw==} + '@react-aria/virtualizer@4.1.13': + resolution: {integrity: sha512-d5KS+p8GXGNRbGPRE/N6jtth3et3KssQIz52h2+CAoAh7C3vvR64kkTaGdeywClvM+fSo8FxJuBrdfQvqC2ktQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-aria/visually-hidden@3.8.29': - resolution: {integrity: sha512-1joCP+MHBLd+YA6Gb08nMFfDBhOF0Kh1gR1SA8zoxEB5RMfQEEkufIB8k0GGwvHGSCK3gFyO8UAVsD0+rRYEyg==} + '@react-aria/visually-hidden@3.8.31': + resolution: {integrity: sha512-RTOHHa4n56a9A3criThqFHBifvZoV71+MCkSuNP2cKO662SUWjqKkd0tJt/mBRMEJPkys8K7Eirp6T8Wt5FFRA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 @@ -3959,142 +4070,142 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/calendar@3.9.1': - resolution: {integrity: sha512-q0Q8fivpQa1rcLg5daUVxwVj1smCp1VnpX9A5Q5PkI9lH9x+xdS0Y6eOqb8Ih3TKBDkx9/oEZonOX7RYNIzSig==} + '@react-stately/calendar@3.9.3': + resolution: {integrity: sha512-uw7fCZXoypSBBUsVkbNvJMQWTihZReRbyLIGG3o/ZM630N3OCZhb/h4Uxke4pNu7n527H0V1bAnZgAldIzOYqg==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/checkbox@3.7.3': - resolution: {integrity: sha512-ve2K+uWT+NRM1JMn+tkWJDP2iBAaWvbZ0TbSXs371IUcTWaNW61HygZ+UFOB/frAZGloazEKGqAsX5XjFpgB9w==} + '@react-stately/checkbox@3.7.5': + resolution: {integrity: sha512-K5R5ted7AxLB3sDkuVAazUdyRMraFT1imVqij2GuAiOUFvsZvbuocnDuFkBVKojyV3GpqLBvViV8IaCMc4hNIw==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/collections@3.12.8': - resolution: {integrity: sha512-AceJYLLXt1Y2XIcOPi6LEJSs4G/ubeYW3LqOCQbhfIgMaNqKfQMIfagDnPeJX9FVmPFSlgoCBxb1pTJW2vjCAQ==} + '@react-stately/collections@3.12.10': + resolution: {integrity: sha512-wmF9VxJDyBujBuQ76vXj2g/+bnnj8fx5DdXgRmyfkkYhPB46+g2qnjbVGEvipo7bJuGxDftCUC4SN7l7xqUWfg==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/color@3.9.3': - resolution: {integrity: sha512-H5lQgl07upsI7+cxTwYo639ziDDG1DFgOtq5pmC4Nxi8uNl8sR/8YeLaYuxyJiVkj2VLHBYRQ3+JcxrdduFvPQ==} + '@react-stately/color@3.9.5': + resolution: {integrity: sha512-8pZxzXWDRuglzDwyTG7mLw2LQMCHIVNbVc9YmbsxbOjAL+lOqszo60KzyaFKVxeDQczSvrNTHcQZqlbNIC0eyQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/combobox@3.12.1': - resolution: {integrity: sha512-RwfTTYgKJ9raIY+7grZ5DbfVRSO5pDjo/ur2VN/28LZzM0eOQrLFQ00vpBmY7/R64sHRpcXLDxpz5cqpKCdvTw==} + '@react-stately/combobox@3.13.0': + resolution: {integrity: sha512-dX9g/cK1hjLRjcbWVF6keHxTQDGhKGB2QAgPhWcBmOK3qJv+2dQqsJ6YCGWn/Y2N2acoEseLrAA7+Qe4HWV9cg==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/data@3.15.0': - resolution: {integrity: sha512-ocP39NQQkrbtHVCPsqltNncpEHaONyYX/8s2UK9xeLRc+55NtDI2RZDKTUf/mi6H2SHxzEwLMQH8hWtEwC55mQ==} + '@react-stately/data@3.15.2': + resolution: {integrity: sha512-BsmeeGgFwOGwo0g9Waprdyt+846n3KhKggZfpEnp5+sC4dE4uW1VIYpdyupMfr3bQcmX123q6TegfNP3eszrUA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/datepicker@3.15.3': - resolution: {integrity: sha512-RDYoz1R/EkCyxHYewb58T7DngU3gl6CnQL7xiWiDlayPnstGaanoQ3yCZGJaIQwR8PrKdNbQwXF9NlSmj8iCOw==} + '@react-stately/datepicker@3.16.1': + resolution: {integrity: sha512-BtAMDvxd1OZxkxjqq5tN5TYmp6Hm8+o3+IDA4qmem2/pfQfVbOZeWS2WitcPBImj4n4T+W1A5+PI7mT/6DUBVg==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/disclosure@3.0.9': - resolution: {integrity: sha512-M3HKsXqdzYKQf1TpnQRLZ6+/b8E3Nba3oOuY0OW5NnM5dZWSnXuj8foBQJT118FdLgMjpfBdPIkUvnaGiDCs5w==} + '@react-stately/disclosure@3.0.11': + resolution: {integrity: sha512-/KjB/0HkxGWbhFAPztCP411LUKZCx9k8cKukrlGqrUWyvrcXlmza90j0g/CuxACBoV+DJP9V+4q+8ide0x750A==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/dnd@3.7.2': - resolution: {integrity: sha512-tr5nNgrLMn5GV308K1f010XUZ2j8CApqHrrcjg5fa2AnpO2gECcOf+UEnAvoFNUsvknje4iPX8y0/0No2ZHsgA==} + '@react-stately/dnd@3.7.4': + resolution: {integrity: sha512-YD0TVR5JkvTqskc1ouBpVKs6t/QS4RYCIyu8Ug8RgO122iIizuf2pfKnRLjYMdu5lXzBXGaIgd49dvnLzEXHIw==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 '@react-stately/flags@3.1.2': resolution: {integrity: sha512-2HjFcZx1MyQXoPqcBGALwWWmgFVUk2TuKVIQxCbRq7fPyWXIl6VHcakCLurdtYC2Iks7zizvz0Idv48MQ38DWg==} - '@react-stately/form@3.2.2': - resolution: {integrity: sha512-soAheOd7oaTO6eNs6LXnfn0tTqvOoe3zN9FvtIhhrErKz9XPc5sUmh3QWwR45+zKbitOi1HOjfA/gifKhZcfWw==} + '@react-stately/form@3.2.4': + resolution: {integrity: sha512-qNBzun8SbLdgahryhKLqL1eqP+MXY6as82sVXYOOvUYLzgU5uuN8mObxYlxJgMI5akSdQJQV3RzyfVobPRE7Kw==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/grid@3.11.7': - resolution: {integrity: sha512-SqzBSxUTFZKLZicfXDK+M0A3gh07AYK1pmU/otcq2cjZ0nSC4CceKijQ2GBZnl+YGcGHI1RgkhpLP6ZioMYctQ==} + '@react-stately/grid@3.11.9': + resolution: {integrity: sha512-qQY6F+27iZRn30dt0ZOrSetUmbmNJ0pLe9Weuqw3+XDVSuWT+2O/rO1UUYeK+mO0Acjzdv+IWiYbu9RKf2wS9w==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/layout@4.5.2': - resolution: {integrity: sha512-quAzYkshApkv1vChz2NXBaLTC7ihJUmv3ijqJBHCkZSY6qq+1qnc4aGespDF1f3mPhmpGswTFGXFImFTAYfi5g==} + '@react-stately/layout@4.6.0': + resolution: {integrity: sha512-kBenEsP03nh5rKgfqlVMPcoKTJv0v92CTvrAb5gYY8t9g8LOwzdL89Yannq7f5xv8LFck/MmRQlotpMt2InETg==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/list@3.13.2': - resolution: {integrity: sha512-dGFALuQWNNOkv7W12qSsXLF4mJHLeWeK2hVvdyj4SI8Vxku+BOfaVKuW3sn3mNiixI1dM/7FY2ip4kK+kv27vw==} + '@react-stately/list@3.13.4': + resolution: {integrity: sha512-HHYSjA9VG7FPSAtpXAjQyM/V7qFHWGg88WmMrDt5QDlTBexwPuH0oFLnW0qaVZpAIxuWIsutZfxRAnme/NhhAA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/menu@3.9.9': - resolution: {integrity: sha512-moW5JANxMxPilfR0SygpCWCZe7Ef09oadgzTZthRymNRv0PXVS9ad4wd1EkwuMvPH/n0uZLZE2s8hNyFDgyqPA==} + '@react-stately/menu@3.9.11': + resolution: {integrity: sha512-vYkpO9uV2OUecsIkrOc+Urdl/s1xw/ibNH/UXsp4PtjMnS6mK9q2kXZTM3WvMAKoh12iveUO+YkYCZQshmFLHQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/numberfield@3.10.3': - resolution: {integrity: sha512-40g/oyVcWoEaLqkr61KuHZzQVLLXFi3oa2K8XLnb6o+859SM4TX3XPNqL6eNQjXSKoJO5Hlgpqhee9j+VDbGog==} + '@react-stately/numberfield@3.11.0': + resolution: {integrity: sha512-rxfC047vL0LP4tanjinfjKAriAvdVL57Um5RUL5nHML8IOWCB3TBxegQkJ6to6goScC/oZhd0/Y2LSaiRuKbNw==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/overlays@3.6.21': - resolution: {integrity: sha512-7f25H1PS2g+SNvuWPEW30pSGqYNHxesCP4w+1RcV/XV1oQI7oP5Ji2WfI0QsJEFc9wP/ZO1pyjHNKpfLI3O88g==} + '@react-stately/overlays@3.6.23': + resolution: {integrity: sha512-RzWxots9A6gAzQMP4s8hOAHV7SbJRTFSlQbb6ly1nkWQXacOSZSFNGsKOaS0eIatfNPlNnW4NIkgtGws5UYzfw==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/radio@3.11.3': - resolution: {integrity: sha512-8+Cy0azV1aBWKcBfGHi3nBa285lAS6XhmVw2LfEwxq8DeVKTbJAaCHHwvDoclxDiOAnqzE0pio0QMD8rYISt9g==} + '@react-stately/radio@3.11.5': + resolution: {integrity: sha512-QxA779S4ea5icQ0ja7CeiNzY1cj7c9G9TN0m7maAIGiTSinZl2Ia8naZJ0XcbRRp+LBll7RFEdekne15TjvS/w==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/searchfield@3.5.17': - resolution: {integrity: sha512-/KExpJt6EGyuLxy/PRQJlETQxJGw8tRxVws6qF1lankN49Os2UhFEWi7ogbMCOWN67gIgevhZRdzmJnuov6BEQ==} + '@react-stately/searchfield@3.5.19': + resolution: {integrity: sha512-URllgjbtTQEaOCfddbHpJSPKOzG3pE3ajQHJ7Df8qCoHTjKfL6hnm/vp7X5sxPaZaN7VLZ5kAQxTE8hpo6s0+A==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/select@3.9.0': - resolution: {integrity: sha512-eNE33zVYpVdCPKRPGYyViN3LnEq82e1wjBIrs9T7Vo4EBnJeT57pqMZpalTPk7qsA+861t14Qrj7GnUd+YbEXw==} + '@react-stately/select@3.9.2': + resolution: {integrity: sha512-oWn0bijuusp8YI7FRM/wgtPVqiIrgU/ZUfLKe/qJUmT8D+JFaMAJnyrAzKpx98TrgamgtXynF78ccpopPhgrKQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/selection@3.20.7': - resolution: {integrity: sha512-NkiRsNCfORBIHNF1bCavh4Vvj+Yd5NffE10iXtaFuhF249NlxLynJZmkcVCqNP9taC2pBIHX00+9tcBgxhG+mA==} + '@react-stately/selection@3.20.9': + resolution: {integrity: sha512-RhxRR5Wovg9EVi3pq7gBPK2BoKmP59tOXDMh2r1PbnGevg/7TNdR67DCEblcmXwHuBNS46ELfKdd0XGHqmS8nQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/slider@3.7.3': - resolution: {integrity: sha512-9QGnQNXFAH52BzxtU7weyOV/VV7/so6uIvE8VOHfc6QR3GMBM/kJvqBCTWZfQ0pxDIsRagBQDD/tjB09ixTOzg==} + '@react-stately/slider@3.7.5': + resolution: {integrity: sha512-OrQMNR5xamLYH52TXtvTgyw3EMwv+JI+1istQgEj1CHBjC9eZZqn5iNCN20tzm+uDPTH0EIGULFjjPIumqYUQg==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/table@3.15.2': - resolution: {integrity: sha512-vgEArBN5ocqsQdeORBj6xk8acu5iFnd/CyXEQKl0R5RyuYuw0ms8UmFHvs8Fv1HONehPYg+XR4QPliDFPX8R9A==} + '@react-stately/table@3.15.4': + resolution: {integrity: sha512-fGaNyw3wv7JgRCNzgyDzpaaTFuSy5f4Qekch4UheMXDJX7dOeaMhUXeOfvnXCVg+BGM4ey/D82RvDOGvPy1Nww==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/tabs@3.8.7': - resolution: {integrity: sha512-ETZEzg7s9F2SCvisZ2cCpLx6XBHqdvVgDGU5l3C3s9zBKBr6lgyLFt61IdGW8XXZRUvw4mMGT6tGQbXeGvR0Wg==} + '@react-stately/tabs@3.8.9': + resolution: {integrity: sha512-AQ4Xrn6YzIolaVShCV9cnwOjBKPAOGP/PTp7wpSEtQbQ0HZzUDG2RG/M4baMeUB2jZ33b7ifXyPcK78o0uOftg==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/toast@3.1.2': - resolution: {integrity: sha512-HiInm7bck32khFBHZThTQaAF6e6/qm57F4mYRWdTq8IVeGDzpkbUYibnLxRhk0UZ5ybc6me+nqqPkG/lVmM42Q==} + '@react-stately/toast@3.1.3': + resolution: {integrity: sha512-mT9QJKmD523lqFpOp0VWZ6QHZENFK7HrodnNJDVc7g616s5GNmemdlkITV43fSY3tHeThCVvPu+Uzh7RvQ9mpQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/toggle@3.9.3': - resolution: {integrity: sha512-G6aA/aTnid/6dQ9dxNEd7/JqzRmVkVYYpOAP+l02hepiuSmFwLu4nE98i4YFBQqFZ5b4l01gMrS90JGL7HrNmw==} + '@react-stately/toggle@3.9.5': + resolution: {integrity: sha512-PVzXc788q3jH98Kvw1LYDL+wpVC14dCEKjOku8cSaqhEof6AJGaLR9yq+EF1yYSL2dxI6z8ghc0OozY8WrcFcA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/tooltip@3.5.9': - resolution: {integrity: sha512-YwqtxFqQFfJtbeh+axHVGAfz9XHf73UaBndHxSbVM/T5c1PfI2yOB39T2FOU5fskZ2VMO3qTDhiXmFgGbGYSfQ==} + '@react-stately/tooltip@3.5.11': + resolution: {integrity: sha512-o8PnFXbvDCuVZ4Ht9ahfS6KHwIZjXopvoQ2vUPxv920irdgWEeC+4omgDOnJ/xFvcpmmJAmSsrQsTQrTguDUQA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/tree@3.9.4': - resolution: {integrity: sha512-Re1fdEiR0hHPcEda+7ecw+52lgGfFW0MAEDzFg9I6J/t8STQSP+1YC0VVVkv2xRrkLbKLPqggNKgmD8nggecnw==} + '@react-stately/tree@3.9.6': + resolution: {integrity: sha512-JCuhGyX2A+PAMsx2pRSwArfqNFZJ9JSPkDaOQJS8MFPAsBe5HemvXsdmv9aBIMzlbCYcVq6EsrFnzbVVTBt/6w==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 @@ -4103,154 +4214,154 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-stately/virtualizer@4.4.4': - resolution: {integrity: sha512-ri8giqXSZOrznZDCCOE4U36wSkOhy+hrFK7yo/YVcpxTqqp3d3eisfKMqbDsgqBW+XTHycTU/xeAf0u9NqrfpQ==} + '@react-stately/virtualizer@4.4.6': + resolution: {integrity: sha512-9SfXgLFB61/8SXNLfg5ARx9jAK4m03Aw6/Cg8mdZN24SYarL4TKNRpfw8K/HHVU/bi6WHSJypk6Z/z19o/ztrg==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/autocomplete@3.0.0-alpha.36': - resolution: {integrity: sha512-J/wYkXom9zmEX/xuGjKrqMco9sf5AcByNXOgGAx82LMlk0jFcViggVjIYo/Qzr0TmDeTWyy++r1N59POI6179g==} + '@react-types/autocomplete@3.0.0-alpha.38': + resolution: {integrity: sha512-0XrlVC8drzcrCNzybbkZdLcTofXEzBsHuaFevt5awW1J0xBJ+SMLIQMDeUYrvKjjwXUBlCtjJJpOvitGt4Z+KA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/breadcrumbs@3.7.17': - resolution: {integrity: sha512-IhvVTcfli5o/UDlGACXxjlor2afGlMQA8pNR3faH0bBUay1Fmm3IWktVw9Xwmk+KraV2RTAg9e+E6p8DOQZfiw==} + '@react-types/breadcrumbs@3.7.19': + resolution: {integrity: sha512-AnkyYYmzaM2QFi/N0P/kQLM8tHOyFi7p397B/jEMucXDfwMw5Ny1ObCXeIEqbh8KrIa2Xp8SxmQlCV+8FPs4LA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/button@3.14.1': - resolution: {integrity: sha512-D8C4IEwKB7zEtiWYVJ3WE/5HDcWlze9mLWQ5hfsBfpePyWCgO3bT/+wjb/7pJvcAocrkXo90QrMm85LcpBtrpg==} + '@react-types/button@3.15.1': + resolution: {integrity: sha512-M1HtsKreJkigCnqceuIT22hDJBSStbPimnpmQmsl7SNyqCFY3+DHS7y/Sl3GvqCkzxF7j9UTL0dG38lGQ3K4xQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/calendar@3.8.1': - resolution: {integrity: sha512-B0UuitMP7YkArBAQldwSZSNL2WwazNGCG+lp6yEDj831NrH9e36/jcjv1rObQ9ZMS6uDX9LXu5C8V5RFwGQabA==} + '@react-types/calendar@3.8.3': + resolution: {integrity: sha512-fpH6WNXotzH0TlKHXXxtjeLZ7ko0sbyHmwDAwmDFyP7T0Iwn1YQZ+lhceLifvynlxuOgX6oBItyUKmkHQ0FouQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/checkbox@3.10.2': - resolution: {integrity: sha512-ktPkl6ZfIdGS1tIaGSU/2S5Agf2NvXI9qAgtdMDNva0oLyAZ4RLQb6WecPvofw1J7YKXu0VA5Mu7nlX+FM2weQ==} + '@react-types/checkbox@3.10.4': + resolution: {integrity: sha512-tYCG0Pd1usEz5hjvBEYcqcA0youx930Rss1QBIse9TgMekA1c2WmPDNupYV8phpO8Zuej3DL1WfBeXcgavK8aw==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/color@3.1.2': - resolution: {integrity: sha512-NP0TAY3j4tlMztOp/bBfMlPwC9AQKTjSiTFmc2oQNkx5M4sl3QpPqFPosdt7jZ8M4nItvfCWZrlZGjST4SB83A==} + '@react-types/color@3.1.4': + resolution: {integrity: sha512-s+Xj4pvNBlJPpQ1Gr7bO1j4/tuwMUfdS9xIVFuiW5RvDsSybKTUJ/gqPzTxms94VDCRhLFocVn2STNdD2Erf6A==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/combobox@3.13.10': - resolution: {integrity: sha512-Wo4iix++ID6JzoH9eD7ddGUlirQiGpN/VQc3iFjnaTXiJ/cj3v+1oGsDGCZZTklTVeUMU7SRBfMhMgxHHIYLXA==} + '@react-types/combobox@3.14.0': + resolution: {integrity: sha512-zmSSS7BcCOD8rGT8eGbVy7UlL5qq1vm88fFn4WgFe+lfK33ne+E7yTzTxcPY2TCGSo5fY6xMj3OG79FfVNGbSg==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/datepicker@3.13.3': - resolution: {integrity: sha512-OTRa3banGxcUQKRTLUzr0zTVUMUL+Az1BWARCYQ+8Z/dlkYXYUW0fnS5I0pUEqihgai15KxiY13U0gAqbNSfcA==} + '@react-types/datepicker@3.13.5': + resolution: {integrity: sha512-j28Vz+xvbb4bj7+9Xbpc4WTvSitlBvt7YEaEGM/8ZQ5g4Jr85H2KwkmDwjzmMN2r6VMQMMYq9JEcemq5wWpfUQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/dialog@3.5.22': - resolution: {integrity: sha512-smSvzOcqKE196rWk0oqJDnz+ox5JM5+OT0PmmJXiUD4q7P5g32O6W5Bg7hMIFUI9clBtngo8kLaX2iMg+GqAzg==} + '@react-types/dialog@3.5.24': + resolution: {integrity: sha512-NFurEP/zV0dA/41422lV1t+0oh6f/13n+VmLHZG8R13m1J3ql/kAXZ49zBSqkqANBO1ojyugWebk99IiR4pYOw==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/form@3.7.16': - resolution: {integrity: sha512-Sb7KJoWEaQ/e4XIY+xRbjKvbP1luome98ZXevpD+zVSyGjEcfIroebizP6K1yMHCWP/043xH6GUkgEqWPoVGjg==} + '@react-types/form@3.7.18': + resolution: {integrity: sha512-0sBJW0+I9nJcF4SmKrYFEWAlehiebSTy7xqriqAXtqfTEdvzAYLGaAK2/7gx+wlNZeDTdW43CDRJ4XAhyhBqnw==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/grid@3.3.6': - resolution: {integrity: sha512-vIZJlYTii2n1We9nAugXwM2wpcpsC6JigJFBd6vGhStRdRWRoU4yv1Gc98Usbx0FQ/J7GLVIgeG8+1VMTKBdxw==} + '@react-types/grid@3.3.8': + resolution: {integrity: sha512-zJvXH8gc1e1VH2H3LRnHH/W2HIkLkZMH3Cu5pLcj0vDuLBSWpcr3Ikh3jZ+VUOZF0G1Jt1lO8pKIaqFzDLNmLQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/link@3.6.5': - resolution: {integrity: sha512-+I2s3XWBEvLrzts0GnNeA84mUkwo+a7kLUWoaJkW0TOBDG7my95HFYxF9WnqKye7NgpOkCqz4s3oW96xPdIniQ==} + '@react-types/link@3.6.7': + resolution: {integrity: sha512-1apXCFJgMC1uydc2KNENrps1qR642FqDpwlNWe254UTpRZn/hEZhA6ImVr8WhomfLJu672WyWA0rUOv4HT+/pQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/listbox@3.7.4': - resolution: {integrity: sha512-p4YEpTl/VQGrqVE8GIfqTS5LkT5jtjDTbVeZgrkPnX/fiPhsfbTPiZ6g0FNap4+aOGJFGEEZUv2q4vx+rCORww==} + '@react-types/listbox@3.7.6': + resolution: {integrity: sha512-335NYElKEByXMalAmeRPyulKIDd2cjOCQhLwvv2BtxO5zaJfZnBbhZs+XPd9zwU6YomyOxODKSHrwbNDx+Jf3w==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/menu@3.10.5': - resolution: {integrity: sha512-HBTrKll2hm0VKJNM4ubIv1L9MNo8JuOnm2G3M+wXvb6EYIyDNxxJkhjsqsGpUXJdAOSkacHBDcNh2HsZABNX4A==} + '@react-types/menu@3.10.7': + resolution: {integrity: sha512-+p7ixZdvPDJZhisqdtWiiuJ9pteNfK5i19NB6wzAw5XkljbEzodNhwLv6rI96DY5XpbFso2kcjw7IWi+rAAGGQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/meter@3.4.13': - resolution: {integrity: sha512-EiarfbpHcvmeyXvXcr6XLaHkNHuGc4g7fBVEiDPwssFJKKfbUzqnnknDxPjyspqUVRcXC08CokS98J1jYobqDg==} + '@react-types/meter@3.4.15': + resolution: {integrity: sha512-9WjNphhLLM+TA4Ev1y2MkpugJ5JjTXseHh7ZWWx2veq5DrXMZYclkRpfUrUdLVKvaBIPQCgpQIj0TcQi+quR9A==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/numberfield@3.8.16': - resolution: {integrity: sha512-945F0GsD7K2T293YXhap+2Runl3tZWbnhadXVHFWLbqIKKONZFSZTfLKxQcbFr+bQXr2uh1bVJhYcOiS1l5M+A==} + '@react-types/numberfield@3.8.18': + resolution: {integrity: sha512-nLzk7YAG9yAUtSv+9R8LgCHsu8hJq8/A+m1KsKxvc8WmNJjIujSFgWvT21MWBiUgPBzJKGzAqpMDDa087mltJQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/overlays@3.9.2': - resolution: {integrity: sha512-Q0cRPcBGzNGmC8dBuHyoPR7N3057KTS5g+vZfQ53k8WwmilXBtemFJPLsogJbspuewQ/QJ3o2HYsp2pne7/iNw==} + '@react-types/overlays@3.9.4': + resolution: {integrity: sha512-7Z9HaebMFyYBqtv3XVNHEmVkm7AiYviV7gv0c98elEN2Co+eQcKFGvwBM9Gy/lV57zlTqFX1EX/SAqkMEbCLOA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/progress@3.5.16': - resolution: {integrity: sha512-I9tSdCFfvQ7gHJtm90VAKgwdTWXQgVNvLRStEc0z9h+bXBxdvZb+QuiRPERChwFQ9VkK4p4rDqaFo69nDqWkpw==} + '@react-types/progress@3.5.18': + resolution: {integrity: sha512-mKeQn+KrHr1y0/k7KtrbeDGDaERH6i4f6yBwj/ZtYDCTNKMO3tPHJY6nzF0w/KKZLplIO+BjUbHXc2RVm8ovwQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/radio@3.9.2': - resolution: {integrity: sha512-3UcJXu37JrTkRyP4GJPDBU7NmDTInrEdOe+bVzA1j4EegzdkJmLBkLg5cLDAbpiEHB+xIsvbJdx6dxeMuc+H3g==} + '@react-types/radio@3.9.4': + resolution: {integrity: sha512-TkMRY3sA1PcFZhhclu4IUzUTIir6MzNJj8h6WT8vO6Nug2kXJ72qigugVFBWJSE472mltduOErEAo0rtAYWbQA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/searchfield@3.6.6': - resolution: {integrity: sha512-cl3itr/fk7wbIQc2Gz5Ie8aVeUmPjVX/mRGS5/EXlmzycAKNYTvqf2mlxwObLndtLISmt7IgNjRRhbUUDI8Ang==} + '@react-types/searchfield@3.6.8': + resolution: {integrity: sha512-M2p7OVdMTMDmlBcHd4N2uCBwg3uJSNM4lmEyf09YD44N5wDAI0yogk52QBwsnhpe+i2s65UwCYgunB+QltRX8A==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/select@3.12.0': - resolution: {integrity: sha512-tM3mEbQNotvCJs1gYRFyIeXmXrIBSBLGw7feCIaYSO45IyjCGv8NZwpQWjoKPaWo3GpbHfHMNlWlq3v5QQPIXw==} + '@react-types/select@3.12.2': + resolution: {integrity: sha512-AseOjfr3qM1W1qIWcbAe6NFpwZluVeQX/dmu9BYxjcnVvtoBLPMbE5zX/BPbv+N5eFYjoMyj7Ug9dqnI+LrlGw==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/shared@3.32.1': - resolution: {integrity: sha512-famxyD5emrGGpFuUlgOP6fVW2h/ZaF405G5KDi3zPHzyjAWys/8W6NAVJtNbkCkhedmvL0xOhvt8feGXyXaw5w==} + '@react-types/shared@3.33.1': + resolution: {integrity: sha512-oJHtjvLG43VjwemQDadlR5g/8VepK56B/xKO2XORPHt9zlW6IZs3tZrYlvH29BMvoqC7RtE7E5UjgbnbFtDGag==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/slider@3.8.2': - resolution: {integrity: sha512-MQYZP76OEOYe7/yA2To+Dl0LNb0cKKnvh5JtvNvDnAvEprn1RuLiay8Oi/rTtXmc2KmBa4VdTcsXsmkbbkeN2Q==} + '@react-types/slider@3.8.4': + resolution: {integrity: sha512-C+xFVvfKREai9S/ekBDCVaGPOQYkNUAsQhjQnNsUAATaox4I6IYLmcIgLmljpMQWqAe+gZiWsIwacRYMez2Tew==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/switch@3.5.15': - resolution: {integrity: sha512-r/ouGWQmIeHyYSP1e5luET+oiR7N7cLrAlWsrAfYRWHxqXOSNQloQnZJ3PLHrKFT02fsrQhx2rHaK2LfKeyN3A==} + '@react-types/switch@3.5.17': + resolution: {integrity: sha512-2GTPJvBCYI8YZ3oerHtXg+qikabIXCMJ6C2wcIJ5Xn0k9XOovowghfJi10OPB2GGyOiLBU74CczP5nx8adG90Q==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/table@3.13.4': - resolution: {integrity: sha512-I/DYiZQl6aNbMmjk90J9SOhkzVDZvyA3Vn3wMWCiajkMNjvubFhTfda5DDf2SgFP5l0Yh6TGGH5XumRv9LqL5Q==} + '@react-types/table@3.13.6': + resolution: {integrity: sha512-eluL+iFfnVmFm7OSZrrFG9AUjw+tcv898zbv+NsZACa8oXG1v9AimhZfd+Mo8q/5+sX/9hguWNXFkSvmTjuVPQ==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/tabs@3.3.20': - resolution: {integrity: sha512-Kjq4PypapdMOVPAQgaFIKH65Kr3YnRvaxBGd6RYizTsqYImQhXoGj6B4lBpjYy4KhfRd4dYS82frHqTGKmBYiA==} + '@react-types/tabs@3.3.22': + resolution: {integrity: sha512-HGwLD9dA3k3AGfRKGFBhNgxU9/LyRmxN0kxVj1ghA4L9S/qTOzS6GhrGNkGzsGxyVLV4JN8MLxjWN2o9QHnLEg==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/textfield@3.12.6': - resolution: {integrity: sha512-hpEVKE+M3uUkTjw2WrX1NrH/B3rqDJFUa+ViNK2eVranLY4ZwFqbqaYXSzHupOF3ecSjJJv2C103JrwFvx6TPQ==} + '@react-types/textfield@3.12.8': + resolution: {integrity: sha512-wt6FcuE5AyntxsnPika/h3nf/DPmeAVbI018L9o6h+B/IL4sMWWdx663wx2KOOeHH8ejKGZQNPLhUKs4s1mVQA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@react-types/tooltip@3.5.0': - resolution: {integrity: sha512-o/m1wlKlOD2sLb9vZLWdVkD5LFLHBMLGeeK/bhyUtp0IEdUeKy0ZRTS7pa/A50trov9RvdbzLK79xG8nKNxHew==} + '@react-types/tooltip@3.5.2': + resolution: {integrity: sha512-FvSuZ2WP08NEWefrpCdBYpEEZh/5TvqvGjq0wqGzWg2OPwpc14HjD8aE7I3MOuylXkD4MSlMjl7J4DlvlcCs3Q==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@rolldown/pluginutils@1.0.0-beta.53': - resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==} + '@rolldown/pluginutils@1.0.0-rc.3': + resolution: {integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==} '@rollup/plugin-babel@6.1.0': resolution: {integrity: sha512-dFZNuFD2YRcoomP4oYf+DvQNSUA9ih+A3vUqopQx5EdtPGo3WBnQcI/S8pwpz91UsGfL0HsMSOlaMld8HrbubA==} @@ -4327,128 +4438,128 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.55.1': - resolution: {integrity: sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==} + '@rollup/rollup-android-arm-eabi@4.59.0': + resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.55.1': - resolution: {integrity: sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==} + '@rollup/rollup-android-arm64@4.59.0': + resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.55.1': - resolution: {integrity: sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==} + '@rollup/rollup-darwin-arm64@4.59.0': + resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.55.1': - resolution: {integrity: sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==} + '@rollup/rollup-darwin-x64@4.59.0': + resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.55.1': - resolution: {integrity: sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==} + '@rollup/rollup-freebsd-arm64@4.59.0': + resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.55.1': - resolution: {integrity: sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==} + '@rollup/rollup-freebsd-x64@4.59.0': + resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.55.1': - resolution: {integrity: sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==} + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.55.1': - resolution: {integrity: sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==} + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.55.1': - resolution: {integrity: sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==} + '@rollup/rollup-linux-arm64-gnu@4.59.0': + resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.55.1': - resolution: {integrity: sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==} + '@rollup/rollup-linux-arm64-musl@4.59.0': + resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loong64-gnu@4.55.1': - resolution: {integrity: sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==} + '@rollup/rollup-linux-loong64-gnu@4.59.0': + resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-loong64-musl@4.55.1': - resolution: {integrity: sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==} + '@rollup/rollup-linux-loong64-musl@4.59.0': + resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.55.1': - resolution: {integrity: sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==} + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-ppc64-musl@4.55.1': - resolution: {integrity: sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==} + '@rollup/rollup-linux-ppc64-musl@4.59.0': + resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.55.1': - resolution: {integrity: sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==} + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.55.1': - resolution: {integrity: sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==} + '@rollup/rollup-linux-riscv64-musl@4.59.0': + resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.55.1': - resolution: {integrity: sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==} + '@rollup/rollup-linux-s390x-gnu@4.59.0': + resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.55.1': - resolution: {integrity: sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==} + '@rollup/rollup-linux-x64-gnu@4.59.0': + resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.55.1': - resolution: {integrity: sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==} + '@rollup/rollup-linux-x64-musl@4.59.0': + resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} cpu: [x64] os: [linux] - '@rollup/rollup-openbsd-x64@4.55.1': - resolution: {integrity: sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==} + '@rollup/rollup-openbsd-x64@4.59.0': + resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.55.1': - resolution: {integrity: sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==} + '@rollup/rollup-openharmony-arm64@4.59.0': + resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.55.1': - resolution: {integrity: sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==} + '@rollup/rollup-win32-arm64-msvc@4.59.0': + resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.55.1': - resolution: {integrity: sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==} + '@rollup/rollup-win32-ia32-msvc@4.59.0': + resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.55.1': - resolution: {integrity: sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==} + '@rollup/rollup-win32-x64-gnu@4.59.0': + resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.55.1': - resolution: {integrity: sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==} + '@rollup/rollup-win32-x64-msvc@4.59.0': + resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} cpu: [x64] os: [win32] @@ -4516,8 +4627,8 @@ packages: '@rspack/lite-tapable@1.1.0': resolution: {integrity: sha512-E2B0JhYFmVAwdDiG14+DW0Di4Ze4Jg10Pc4/lILUrd5DRCaklduz2OvJ5HYQ6G+hd+WTzqQb3QnDNfK4yvAFYw==} - '@sinclair/typebox@0.34.47': - resolution: {integrity: sha512-ZGIBQ+XDvO5JQku9wmwtabcVTHJsgSWAHYtVuM9pBNNR5E88v6Jcj/llpmsjivig5X8A8HHOb4/mbEKPS5EvAw==} + '@sinclair/typebox@0.34.48': + resolution: {integrity: sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==} '@sindresorhus/is@4.6.0': resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} @@ -4537,23 +4648,23 @@ packages: '@standard-schema/utils@0.3.0': resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} - '@storybook/addon-docs@10.1.11': - resolution: {integrity: sha512-Jwm291Fhim2eVcZIVlkG1B2skb0ZI9oru6nqMbJxceQZlvZmcIa4oxvS1oaMTKw2DJnCv97gLm57P/YvRZ8eUg==} + '@storybook/addon-docs@10.2.16': + resolution: {integrity: sha512-tdndvqYqUybCFb3co+IfpInfD37mMWtsC9OBBRLEHhHODH/6c16n6iSdzEEOIJhc4rfjxvwNYsTq7jddplAT4g==} peerDependencies: - storybook: ^10.1.11 + storybook: ^10.2.16 - '@storybook/builder-vite@10.1.11': - resolution: {integrity: sha512-MMD09Ap7FyzDfWG961pkIMv/w684XXe1bBEi+wCEpHxvrgAd3j3A9w/Rqp9Am2uRDPCEdi1QgSzS3SGW3aGThQ==} + '@storybook/builder-vite@10.2.16': + resolution: {integrity: sha512-fP+fjvHC2oh2mJue3594AscGKY01wnM80+1s5EVQcSJ8hOk69qPKwN+97SUC5XfoZXg4ZMP0eglzY7TT3i2erA==} peerDependencies: - storybook: ^10.1.11 + storybook: ^10.2.16 vite: ^5.0.0 || ^6.0.0 || ^7.0.0 - '@storybook/csf-plugin@10.1.11': - resolution: {integrity: sha512-Ant0NhgqHKzQsseeVTSetZCuDHHs0W2HRkHt51Kg/sUl0T/sDtfVA+fWZT8nGzGZqYSFkxqYPWjauPmIhPtaRw==} + '@storybook/csf-plugin@10.2.16': + resolution: {integrity: sha512-4p4ZFloO70BQwwLYXSH7N1FdZEXISVxJW16941MLSBDtHBqZxVLL+507424hCATi7d65yPKFL2460WVNodTXig==} peerDependencies: esbuild: '*' rollup: '*' - storybook: ^10.1.11 + storybook: ^10.2.16 vite: '*' webpack: '*' peerDependenciesMeta: @@ -4575,27 +4686,27 @@ 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 - '@storybook/react-dom-shim@10.1.11': - resolution: {integrity: sha512-o8WPhRlZbORUWG9lAgDgJP0pi905VHJUFJr1Kp8980gHqtlemtnzjPxKy5vFwj6glNhAlK8SS8OOYzWP7hloTQ==} + '@storybook/react-dom-shim@10.2.16': + resolution: {integrity: sha512-waDfcEx8OW78qH8COQLKD2nDtDEXzw1zwXm47VPrRKiyhdea5z8OwO/SIk3y1lcoFMCT1RVJKBdYUPeVAoIB6w==} peerDependencies: 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 - storybook: ^10.1.11 + storybook: ^10.2.16 - '@storybook/react-vite@10.1.11': - resolution: {integrity: sha512-qh1BCD25nIoiDfqwha+qBkl7pcG4WuzM+c8tsE63YEm8AFIbNKg5K8lVUoclF+4CpFz7IwBpWe61YUTDfp+91w==} + '@storybook/react-vite@10.2.16': + resolution: {integrity: sha512-4HZnBn/XJlbXk/heaV3Gr/zt+NFWn+8ph8ewfMFLWe/oi1PXeXQKBSujreqGz4C8SvBGgrzQ4ORdmycsaESWMg==} peerDependencies: 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 - storybook: ^10.1.11 + storybook: ^10.2.16 vite: ^5.0.0 || ^6.0.0 || ^7.0.0 - '@storybook/react@10.1.11': - resolution: {integrity: sha512-rmMGmEwBaM2YpB8oDk2moM0MNjNMqtwyoPPZxjyruY9WVhYca8EDPGKEdRzUlb4qZJsTgLi7VU4eqg6LD/mL3Q==} + '@storybook/react@10.2.16': + resolution: {integrity: sha512-0MQJaeHvjBHnDGpsyxujjvvcgPlXeoF4bTtOhB1vYrdxO5Rozjf7hs9K/gY9hx9v95lTttNsU4Qib5L+K6XK+Q==} peerDependencies: 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 - storybook: ^10.1.11 + storybook: ^10.2.16 typescript: '>= 4.9.x' peerDependenciesMeta: typescript: @@ -4767,8 +4878,8 @@ packages: '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - '@swc/helpers@0.5.18': - resolution: {integrity: sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==} + '@swc/helpers@0.5.19': + resolution: {integrity: sha512-QamiFeIK3txNjgUTNppE6MiG3p7TdninpZu0E0PbqVh1a9FNLT2FRhisaa4NcaX52XVhA5l7Pk58Ft7Sqi/2sA==} '@swc/types@0.1.25': resolution: {integrity: sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==} @@ -4777,65 +4888,65 @@ packages: resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} engines: {node: '>=10'} - '@tailwindcss/node@4.1.18': - resolution: {integrity: sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==} + '@tailwindcss/node@4.2.1': + resolution: {integrity: sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==} - '@tailwindcss/oxide-android-arm64@4.1.18': - resolution: {integrity: sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-android-arm64@4.2.1': + resolution: {integrity: sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==} + engines: {node: '>= 20'} cpu: [arm64] os: [android] - '@tailwindcss/oxide-darwin-arm64@4.1.18': - resolution: {integrity: sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-darwin-arm64@4.2.1': + resolution: {integrity: sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==} + engines: {node: '>= 20'} cpu: [arm64] os: [darwin] - '@tailwindcss/oxide-darwin-x64@4.1.18': - resolution: {integrity: sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-darwin-x64@4.2.1': + resolution: {integrity: sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==} + engines: {node: '>= 20'} cpu: [x64] os: [darwin] - '@tailwindcss/oxide-freebsd-x64@4.1.18': - resolution: {integrity: sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-freebsd-x64@4.2.1': + resolution: {integrity: sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==} + engines: {node: '>= 20'} cpu: [x64] os: [freebsd] - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18': - resolution: {integrity: sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.1': + resolution: {integrity: sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==} + engines: {node: '>= 20'} cpu: [arm] os: [linux] - '@tailwindcss/oxide-linux-arm64-gnu@4.1.18': - resolution: {integrity: sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-linux-arm64-gnu@4.2.1': + resolution: {integrity: sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==} + engines: {node: '>= 20'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-arm64-musl@4.1.18': - resolution: {integrity: sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-linux-arm64-musl@4.2.1': + resolution: {integrity: sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==} + engines: {node: '>= 20'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-x64-gnu@4.1.18': - resolution: {integrity: sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-linux-x64-gnu@4.2.1': + resolution: {integrity: sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==} + engines: {node: '>= 20'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-linux-x64-musl@4.1.18': - resolution: {integrity: sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-linux-x64-musl@4.2.1': + resolution: {integrity: sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==} + engines: {node: '>= 20'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-wasm32-wasi@4.1.18': - resolution: {integrity: sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==} + '@tailwindcss/oxide-wasm32-wasi@4.2.1': + resolution: {integrity: sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==} engines: {node: '>=14.0.0'} cpu: [wasm32] bundledDependencies: @@ -4846,127 +4957,126 @@ packages: - '@emnapi/wasi-threads' - tslib - '@tailwindcss/oxide-win32-arm64-msvc@4.1.18': - resolution: {integrity: sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-win32-arm64-msvc@4.2.1': + resolution: {integrity: sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==} + engines: {node: '>= 20'} cpu: [arm64] os: [win32] - '@tailwindcss/oxide-win32-x64-msvc@4.1.18': - resolution: {integrity: sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-win32-x64-msvc@4.2.1': + resolution: {integrity: sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==} + engines: {node: '>= 20'} cpu: [x64] os: [win32] - '@tailwindcss/oxide@4.1.18': - resolution: {integrity: sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==} - engines: {node: '>= 10'} + '@tailwindcss/oxide@4.2.1': + resolution: {integrity: sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==} + engines: {node: '>= 20'} '@tailwindcss/typography@0.5.19': resolution: {integrity: sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==} peerDependencies: tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1' - '@tailwindcss/vite@4.1.18': - resolution: {integrity: sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA==} + '@tailwindcss/vite@4.2.1': + resolution: {integrity: sha512-TBf2sJjYeb28jD2U/OhwdW0bbOsxkWPwQ7SrqGf9sVcoYwZj7rkXljroBO9wKBut9XnmQLXanuDUeqQK0lGg/w==} peerDependencies: vite: ^5.2.0 || ^6 || ^7 - '@tanstack/db-ivm@0.1.14': - resolution: {integrity: sha512-GluhFsd/Z1E/MZTf60l9dZpKNpmdxtV4izPRnj1RK6TYrhC9LMndN+ywk1VDFBrjtBq/CTShz4CilECLwVlTGg==} + '@tanstack/db-ivm@0.1.17': + resolution: {integrity: sha512-DK7vm56CDxNuRAdsbiPs+gITJ+16tUtYgZg3BRTLYKGIDsy8sdIO7sQFq5zl7Y+aIKAPmMAbVp9UjJ75FTtwgQ==} peerDependencies: typescript: '>=4.7' - '@tanstack/db@0.5.16': - resolution: {integrity: sha512-V4oCsGlighwgKGWldw1umaXaVYiDR0sK/1fCWictrx2lqxqmBMUEfmNtWnt0CFJXEbyRA/LF8TyFn1ooXtyZ3w==} + '@tanstack/db@0.5.30': + resolution: {integrity: sha512-kgBbmGrWSrDdKPzl465OEGy2Epyc6HsoI2U/jUrMSHuGgUEtgowpnBCTyPJCGBrHL8+bYgASFV4ULsFn4L6pLg==} peerDependencies: typescript: '>=4.7' - '@tanstack/eslint-plugin-router@1.141.0': - resolution: {integrity: sha512-E5QSLvoS8By2UajtUE64CNp22LVyzdqNyR/ponVV+yxONWHC3IzDUUHKBnPxW1yVwRT88qQoJYV0RJL6noW25A==} + '@tanstack/eslint-plugin-router@1.161.4': + resolution: {integrity: sha512-Cw6naM1QII0DEpjQvs1VDCa8f0hNhCQ0DehdAeVqHfovwUSWw+5F7WhgSlUrZAQN2RodzehWkRm6K/BqtQYnyA==} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - '@tanstack/history@1.145.7': - resolution: {integrity: sha512-gMo/ReTUp0a3IOcZoI3hH6PLDC2R/5ELQ7P2yu9F6aEkA0wSQh+Q4qzMrtcKvF2ut0oE+16xWCGDo/TdYd6cEQ==} - engines: {node: '>=12'} + '@tanstack/history@1.161.4': + resolution: {integrity: sha512-Kp/WSt411ZWYvgXy6uiv5RmhHrz9cAml05AQPrtdAp7eUqvIDbMGPnML25OKbzR3RJ1q4wgENxDTvlGPa9+Mww==} + engines: {node: '>=20.19'} - '@tanstack/pacer-lite@0.1.1': - resolution: {integrity: sha512-y/xtNPNt/YeyoVxE/JCx+T7yjEzpezmbb+toK8DDD1P4m7Kzs5YR956+7OKexG3f8aXgC3rLZl7b1V+yNUSy5w==} + '@tanstack/pacer-lite@0.2.1': + resolution: {integrity: sha512-3PouiFjR4B6x1c969/Pl4ZIJleof1M0n6fNX8NRiC9Sqv1g06CVDlEaXUR4212ycGFyfq4q+t8Gi37Xy+z34iQ==} engines: {node: '>=18'} - '@tanstack/query-core@5.90.16': - resolution: {integrity: sha512-MvtWckSVufs/ja463/K4PyJeqT+HMlJWtw6PrCpywznd2NSgO3m4KwO9RqbFqGg6iDE8vVMFWMeQI4Io3eEYww==} + '@tanstack/query-core@5.90.20': + resolution: {integrity: sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==} - '@tanstack/query-devtools@5.92.0': - resolution: {integrity: sha512-N8D27KH1vEpVacvZgJL27xC6yPFUy0Zkezn5gnB3L3gRCxlDeSuiya7fKge8Y91uMTnC8aSxBQhcK6ocY7alpQ==} + '@tanstack/query-devtools@5.93.0': + resolution: {integrity: sha512-+kpsx1NQnOFTZsw6HAFCW3HkKg0+2cepGtAWXjiiSOJJ1CtQpt72EE2nyZb+AjAbLRPoeRmPJ8MtQd8r8gsPdg==} - '@tanstack/react-db@0.1.60': - resolution: {integrity: sha512-Pz3pwH4vgRxlS/L3+BszINjNlIUXahJ6EqSEsYBMBT19G36GzTzyd5Qq98JaOXuu8V0dkiFWEoyEoTv3BiHcrg==} + '@tanstack/react-db@0.1.74': + resolution: {integrity: sha512-5c5sIVLWsqDnufK4fTnO6VQWUjuIQXB5LEY7zBSqhfJgTMomHtFVxb899O97z2oqF+UzIzmW/lXqUq9Xm8l1Pg==} peerDependencies: react: '>=16.8.0' - '@tanstack/react-query-devtools@5.91.2': - resolution: {integrity: sha512-ZJ1503ay5fFeEYFUdo7LMNFzZryi6B0Cacrgr2h1JRkvikK1khgIq6Nq2EcblqEdIlgB/r7XDW8f8DQ89RuUgg==} + '@tanstack/react-query-devtools@5.91.3': + resolution: {integrity: sha512-nlahjMtd/J1h7IzOOfqeyDh5LNfG0eULwlltPEonYy0QL+nqrBB+nyzJfULV+moL7sZyxc2sHdNJki+vLA9BSA==} peerDependencies: - '@tanstack/react-query': ^5.90.14 + '@tanstack/react-query': ^5.90.20 react: ^18 || ^19 - '@tanstack/react-query@5.90.16': - resolution: {integrity: sha512-bpMGOmV4OPmif7TNMteU/Ehf/hoC0Kf98PDc0F4BZkFrEapRMEqI/V6YS0lyzwSV6PQpY1y4xxArUIfBW5LVxQ==} + '@tanstack/react-query@5.90.21': + resolution: {integrity: sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg==} peerDependencies: react: ^18 || ^19 - '@tanstack/react-router-devtools@1.145.7': - resolution: {integrity: sha512-crzHSQ/rcGX7RfuYsmm1XG5quurNMDTIApU7jfwDx5J9HnUxCOSJrbFX0L3w0o0VRCw5xhrL2EdCnW78Ic86hg==} - engines: {node: '>=12'} + '@tanstack/react-router-devtools@1.166.2': + resolution: {integrity: sha512-EQhFQRArwxS0OjIWWGD5wfNboJq7rIYCbioHvepgbxgblKtNLWnRr3LFj34QhXTP1aQsPYb9t8+VTi3VbFuAfA==} + engines: {node: '>=20.19'} peerDependencies: - '@tanstack/react-router': ^1.145.7 - '@tanstack/router-core': ^1.145.7 + '@tanstack/react-router': ^1.166.2 + '@tanstack/router-core': ^1.166.2 react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' peerDependenciesMeta: '@tanstack/router-core': optional: true - '@tanstack/react-router@1.145.7': - resolution: {integrity: sha512-0O+a4TjJSPXd2BsvDPwDPBKRQKYqNIBg5TAg9NzCteqJ0NXRxwohyqCksHqCEEtJe/uItwqmHoqkK4q5MDhEsA==} - engines: {node: '>=12'} + '@tanstack/react-router@1.166.2': + resolution: {integrity: sha512-pKhUtrvVLlhjWhsHkJSuIzh1J4LcP+8ErbIqRLORX9Js8dUFMKoT0+8oFpi+P8QRpuhm/7rzjYiWfcyTsqQZtA==} + engines: {node: '>=20.19'} peerDependencies: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' - '@tanstack/react-store@0.8.0': - resolution: {integrity: sha512-1vG9beLIuB7q69skxK9r5xiLN3ztzIPfSQSs0GfeqWGO2tGIyInZx0x1COhpx97RKaONSoAb8C3dxacWksm1ow==} + '@tanstack/react-store@0.9.1': + resolution: {integrity: sha512-YzJLnRvy5lIEFTLWBAZmcOjK3+2AepnBv/sr6NZmiqJvq7zTQggyK99Gw8fqYdMdHPQWXjz0epFKJXC+9V2xDA==} peerDependencies: 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 - '@tanstack/router-core@1.145.7': - resolution: {integrity: sha512-v6jx6JqVUBM0/FcBq1tX22xiPq8Ufc0PDEP582/4deYoq2/RYd+bZstANp3mGSsqdxE/luhoLYuuSQiwi/j1wA==} - engines: {node: '>=12'} + '@tanstack/router-core@1.166.2': + resolution: {integrity: sha512-zn3NhENOAX9ToQiX077UV2OH3aJKOvV2ZMNZZxZ3gDG3i3WqL8NfWfEgetEAfMN37/Mnt90PpotYgf7IyuoKqQ==} + engines: {node: '>=20.19'} - '@tanstack/router-devtools-core@1.145.7': - resolution: {integrity: sha512-oKeq/6QvN49THCh++FJyPv1X65i20qGS4aJHQTNsl4cu1piW1zWUhab2L3DZVr3G8C40FW3xb6hVw92N/fzZbQ==} - engines: {node: '>=12'} + '@tanstack/router-devtools-core@1.166.2': + resolution: {integrity: sha512-Ke8HquuwMhLYpo/6nxNgrzi9Ns2lsK9uwDba6WKA8I0K7fyYZoAUu+7AD6gdEcVU4NF6LjtMPfUCHmVtYYRTDw==} + engines: {node: '>=20.19'} peerDependencies: - '@tanstack/router-core': ^1.145.7 + '@tanstack/router-core': ^1.166.2 csstype: ^3.0.10 - solid-js: '>=1.9.5' peerDependenciesMeta: csstype: optional: true - '@tanstack/router-generator@1.145.7': - resolution: {integrity: sha512-xg71c1WTku0ro0rgpJWh3Dt+ognV9qWe2KJHAPzrqfOYdUYu9sGq7Ri4jo8Rk0luXWZrWsrFdBP+9Jx6JH6zWA==} - engines: {node: '>=12'} + '@tanstack/router-generator@1.166.2': + resolution: {integrity: sha512-wbvdyP1PKKQKk4aVlGeK9S5uDy8zodTr3tEZ2gRKNavJLusXbEWqtoo42JxHFFNB6dtguehFMt8PyZPAtkgWwQ==} + engines: {node: '>=20.19'} - '@tanstack/router-plugin@1.145.10': - resolution: {integrity: sha512-2001Qu/aUdEXVjyKa21/8HXXmgyDwTEtvgNoWaB9H6KmpqUUnlNuh+hlfa1tjGSnlFevkjbLb3NfveSy/Bvynw==} - engines: {node: '>=12'} + '@tanstack/router-plugin@1.166.2': + resolution: {integrity: sha512-TnyV/7//Vp5fR49mmNbOWHGz9IJTm1lqVxzPdtpzg7D5PjkW2HFmLFLtWwpJgz2R7AJJWR4Ge5kIPmC+fVZ6eQ==} + engines: {node: '>=20.19'} peerDependencies: '@rsbuild/core': '>=1.0.2' - '@tanstack/react-router': ^1.145.7 + '@tanstack/react-router': ^1.166.2 vite: '>=5.0.0 || >=6.0.0 || >=7.0.0' vite-plugin-solid: ^2.11.10 webpack: '>=5.92.0' @@ -4982,16 +5092,16 @@ packages: webpack: optional: true - '@tanstack/router-utils@1.143.11': - resolution: {integrity: sha512-N24G4LpfyK8dOlnP8BvNdkuxg1xQljkyl6PcrdiPSA301pOjatRT1y8wuCCJZKVVD8gkd0MpCZ0VEjRMGILOtA==} - engines: {node: '>=12'} + '@tanstack/router-utils@1.161.4': + resolution: {integrity: sha512-r8TpjyIZoqrXXaf2DDyjd44gjGBoyE+/oEaaH68yLI9ySPO1gUWmQENZ1MZnmBnpUGN24NOZxdjDLc8npK0SAw==} + engines: {node: '>=20.19'} - '@tanstack/store@0.8.0': - resolution: {integrity: sha512-Om+BO0YfMZe//X2z0uLF2j+75nQga6TpTJgLJQBiq85aOyZNIhkCgleNcud2KQg4k4v9Y9l+Uhru3qWMPGTOzQ==} + '@tanstack/store@0.9.1': + resolution: {integrity: sha512-+qcNkOy0N1qSGsP7omVCW0SDrXtaDcycPqBDE726yryiA5eTDFpjBReaYjghVJwNf1pcPMyzIwTGlYjCSQR0Fg==} - '@tanstack/virtual-file-routes@1.145.4': - resolution: {integrity: sha512-CI75JrfqSluhdGwLssgVeQBaCphgfkMQpi8MCY3UJX1hoGzXa8kHYJcUuIFMOLs1q7zqHy++EVVtMK03osR5wQ==} - engines: {node: '>=12'} + '@tanstack/virtual-file-routes@1.161.4': + resolution: {integrity: sha512-42WoRePf8v690qG8yGRe/YOh+oHni9vUaUUfoqlS91U2scd3a5rkLtVsc6b7z60w3RogH0I00vdrC5AaeiZ18w==} + engines: {node: '>=20.19'} '@testing-library/dom@10.4.1': resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} @@ -5007,10 +5117,6 @@ packages: peerDependencies: '@testing-library/dom': '>=7.21.4' - '@trysound/sax@0.2.0': - resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} - engines: {node: '>=10.13.0'} - '@tsconfig/node10@1.0.12': resolution: {integrity: sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==} @@ -5086,6 +5192,9 @@ packages: '@types/eslint-scope@3.7.7': resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} + '@types/esquery@1.5.4': + resolution: {integrity: sha512-yYO4Q8H+KJHKW1rEeSzHxcZi90durqYgWVfnh5K6ZADVBjBv2e1NEveYX5yT2bffgN7RqzH3k9930m+i2yBoMA==} + '@types/estree-jsx@1.0.5': resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} @@ -5098,8 +5207,8 @@ packages: '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - '@types/http-cache-semantics@4.0.4': - resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + '@types/http-cache-semantics@4.2.0': + resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==} '@types/http-proxy@1.17.17': resolution: {integrity: sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==} @@ -5110,8 +5219,8 @@ packages: '@types/keyv@3.1.4': resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} - '@types/lodash@4.17.21': - resolution: {integrity: sha512-FOvQ0YPD5NOfPgMzJihoT+Za5pdkDJWcbpuj1DjaKZIr/gxodQjY/uWEFlTNqW2ugXHUiL8lRQgw63dzKHZdeQ==} + '@types/lodash@4.17.24': + resolution: {integrity: sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==} '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} @@ -5122,26 +5231,20 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/node-fetch@2.6.13': - resolution: {integrity: sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==} + '@types/node@20.19.37': + resolution: {integrity: sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw==} - '@types/node@18.19.130': - resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==} + '@types/node@24.12.0': + resolution: {integrity: sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==} - '@types/node@20.19.27': - resolution: {integrity: sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==} - - '@types/node@22.19.3': - resolution: {integrity: sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==} - - '@types/node@25.0.3': - resolution: {integrity: sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==} + '@types/node@25.3.5': + resolution: {integrity: sha512-oX8xrhvpiyRCQkG1MFchB09f+cXftgIXb3a7UUa4Y3wpmZPw5tyZGTLWhlESOLq1Rq6oDlc8npVU2/9xiCuXMA==} '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} - '@types/pg@8.16.0': - resolution: {integrity: sha512-RmhMd/wD+CF8Dfo+cVIy3RR5cl8CyfXQ0tGgW6XBL8L4LM/UTEbNXYRbLwU6w+CgrKBNbrQWt4FUtTfaU5jSYQ==} + '@types/pg@8.18.0': + resolution: {integrity: sha512-gT+oueVQkqnj6ajGJXblFR4iavIXWsGAFCk3dP4Kki5+a9R4NMt0JARdk6s8cUKcfUoqP5dAtDSLU8xYUTFV+Q==} '@types/plist@3.0.5': resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==} @@ -5160,8 +5263,8 @@ packages: resolution: {integrity: sha512-omC9GxqKOdEiHLlqWU6NrDUF+qD7DHIZ9K5Wxw/XPrm22rfP/jgZrW8c27u23ON5LMWM/nIlUf0FUh+/DlftlQ==} deprecated: This is a stub types definition. react-timeago provides its own type definitions, so you do not need this installed. - '@types/react@19.2.7': - resolution: {integrity: sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==} + '@types/react@19.2.14': + resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} @@ -5184,94 +5287,101 @@ packages: '@types/verror@1.10.11': resolution: {integrity: sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==} + '@types/webidl-conversions@7.0.3': + resolution: {integrity: sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==} + + '@types/whatwg-url@13.0.0': + resolution: {integrity: sha512-N8WXpbE6Wgri7KUSvrmQcqrMllKZ9uxkYWMt+mCSGwNc0Hsw9VQTW7ApqI4XNrx6/SaM2QQJCzMPDEXE058s+Q==} + '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@typescript-eslint/eslint-plugin@8.52.0': - resolution: {integrity: sha512-okqtOgqu2qmZJ5iN4TWlgfF171dZmx2FzdOv2K/ixL2LZWDStL8+JgQerI2sa8eAEfoydG9+0V96m7V+P8yE1Q==} + '@typescript-eslint/eslint-plugin@8.56.1': + resolution: {integrity: sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.52.0 - eslint: ^8.57.0 || ^9.0.0 + '@typescript-eslint/parser': ^8.56.1 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.52.0': - resolution: {integrity: sha512-iIACsx8pxRnguSYhHiMn2PvhvfpopO9FXHyn1mG5txZIsAaB6F0KwbFnUQN3KCiG3Jcuad/Cao2FAs1Wp7vAyg==} + '@typescript-eslint/parser@8.56.1': + resolution: {integrity: sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.52.0': - resolution: {integrity: sha512-xD0MfdSdEmeFa3OmVqonHi+Cciab96ls1UhIF/qX/O/gPu5KXD0bY9lu33jj04fjzrXHcuvjBcBC+D3SNSadaw==} + '@typescript-eslint/project-service@8.56.1': + resolution: {integrity: sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.52.0': - resolution: {integrity: sha512-ixxqmmCcc1Nf8S0mS0TkJ/3LKcC8mruYJPOU6Ia2F/zUUR4pApW7LzrpU3JmtePbRUTes9bEqRc1Gg4iyRnDzA==} + '@typescript-eslint/scope-manager@8.56.1': + resolution: {integrity: sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.52.0': - resolution: {integrity: sha512-jl+8fzr/SdzdxWJznq5nvoI7qn2tNYV/ZBAEcaFMVXf+K6jmXvAFrgo/+5rxgnL152f//pDEAYAhhBAZGrVfwg==} + '@typescript-eslint/tsconfig-utils@8.56.1': + resolution: {integrity: sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.52.0': - resolution: {integrity: sha512-JD3wKBRWglYRQkAtsyGz1AewDu3mTc7NtRjR/ceTyGoPqmdS5oCdx/oZMWD5Zuqmo6/MpsYs0wp6axNt88/2EQ==} + '@typescript-eslint/type-utils@8.56.1': + resolution: {integrity: sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.52.0': - resolution: {integrity: sha512-LWQV1V4q9V4cT4H5JCIx3481iIFxH1UkVk+ZkGGAV1ZGcjGI9IoFOfg3O6ywz8QqCDEp7Inlg6kovMofsNRaGg==} + '@typescript-eslint/types@8.56.1': + resolution: {integrity: sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.52.0': - resolution: {integrity: sha512-XP3LClsCc0FsTK5/frGjolyADTh3QmsLp6nKd476xNI9CsSsLnmn4f0jrzNoAulmxlmNIpeXuHYeEQv61Q6qeQ==} + '@typescript-eslint/typescript-estree@8.56.1': + resolution: {integrity: sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.52.0': - resolution: {integrity: sha512-wYndVMWkweqHpEpwPhwqE2lnD2DxC6WVLupU/DOt/0/v+/+iQbbzO3jOHjmBMnhu0DgLULvOaU4h4pwHYi2oRQ==} + '@typescript-eslint/utils@8.56.1': + resolution: {integrity: sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.52.0': - resolution: {integrity: sha512-ink3/Zofus34nmBsPjow63FP5M7IGff0RKAgqR6+CFpdk22M7aLwC9gOcLGYqr7MczLPzZVERW9hRog3O4n1sQ==} + '@typescript-eslint/visitor-keys@8.56.1': + resolution: {integrity: sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript/vfs@1.6.2': - resolution: {integrity: sha512-hoBwJwcbKHmvd2QVebiytN1aELvpk9B74B4L1mFm/XT1Q/VOYAWl2vQ9AWRFtQq8zmz6enTpfTV8WRc4ATjW/g==} + '@typescript/vfs@1.6.4': + resolution: {integrity: sha512-PJFXFS4ZJKiJ9Qiuix6Dz/OwEIqHD7Dme1UwZhTK11vR+5dqW2ACbdndWQexBzCx+CPuMe5WBYQWCsFyGlQLlQ==} peerDependencies: typescript: '*' - '@typespec/compiler@1.7.1': - resolution: {integrity: sha512-sb3MEsKjFlAx8ZG484exs5Ec+JwmYf2anJqLjMusrV3rRMUhv3fbEulk9MD+l4eOkBS46VMNGqRu0wTn8suVVA==} + '@typespec/compiler@1.9.0': + resolution: {integrity: sha512-Rz9fFWQSTJSnhBfZvtA/bDIuO82fknYdtyMsL9lZNJE82rquC6JByHPFsnbGH1VXA0HhMj9L7Oqyp3f0m/BTOA==} engines: {node: '>=20.0.0'} hasBin: true - '@typespec/emitter-framework@0.14.0': - resolution: {integrity: sha512-35C9XlLOFk2hQ85Hf6YT19gWOz4SfVgOCoBMs4rgx/KrJj7qM/AbdXjuSO+QLp76a928NWAAHQhbq5NbOpKztw==} + '@typespec/emitter-framework@0.16.0': + resolution: {integrity: sha512-9Sug3Jt4y7acDVqrP9fD+YBSGqXqnAvUpGcTfTIH6d6QE1+Jxn4qEl7AjyKtyVd7Fyxwp4kqooUocL+QHLzXVw==} peerDependencies: - '@alloy-js/core': ^0.21.0 - '@alloy-js/csharp': ^0.21.0 - '@alloy-js/typescript': ^0.21.0 - '@typespec/compiler': ^1.7.0 + '@alloy-js/core': ^0.22.0 + '@alloy-js/csharp': ^0.22.0 + '@alloy-js/python': ^0.3.0 + '@alloy-js/typescript': ^0.22.0 + '@typespec/compiler': ^1.9.0 - '@typespec/prettier-plugin-typespec@1.7.0': - resolution: {integrity: sha512-QxCCjWOHqlf43ZMIqma4JU9dnsuknqlUO8yfYUXdxXIBxadevY6Pk3HbTR+ecNgeZlxuvd8ms2v1rhcojw3pTA==} + '@typespec/prettier-plugin-typespec@1.9.0': + resolution: {integrity: sha512-39Nc1uRM/kwDLrFfuMh+aS9P8fUpKi8IOBVF/3s45vFnITt2Pa1Pud3+xcU+/JWoc/q6bkzXM6PmfJ4/60Z+mw==} - '@uiw/codemirror-extensions-basic-setup@4.25.4': - resolution: {integrity: sha512-YzNwkm0AbPv1EXhCHYR5v0nqfemG2jEB0Z3Att4rBYqKrlG7AA9Rhjc3IyBaOzsBu18wtrp9/+uhTyu7TXSRng==} + '@uiw/codemirror-extensions-basic-setup@4.25.7': + resolution: {integrity: sha512-tPV/AGjF4yM22D5mnyH7EuYBkWO05wF5Y4x3lmQJo6LuHmhjh0RQsVDjqeIgNOkXT3UO9OdkL4dzxw465/JZVg==} peerDependencies: '@codemirror/autocomplete': 6.20.0 '@codemirror/commands': 6.10.1 @@ -5281,8 +5391,8 @@ packages: '@codemirror/state': 6.5.3 '@codemirror/view': 6.39.9 - '@uiw/react-codemirror@4.25.4': - resolution: {integrity: sha512-ipO067oyfUw+DVaXhQCxkB0ZD9b7RnY+ByrprSYSKCHaULvJ3sqWYC/Zen6zVQ8/XC4o5EPBfatGiX20kC7XGA==} + '@uiw/react-codemirror@4.25.7': + resolution: {integrity: sha512-s/EbEe0dFANWEgfLbfdIrrOGv0R7M1XhkKG3ShroBeH6uP9pVNQy81YHOLRCSVcytTp9zAWRNfXR/+XxZTvV7w==} peerDependencies: '@babel/runtime': '>=7.11.0' '@codemirror/state': 6.5.3 @@ -5390,8 +5500,13 @@ packages: cpu: [x64] os: [win32] - '@vitejs/plugin-react@5.1.2': - resolution: {integrity: sha512-EcA07pHJouywpzsoTUqNh5NwGayl2PPVEJKUSinGGSxFGYn+shYbqMGBg6FXDqgXum9Ou/ecb+411ssw8HImJQ==} + '@valibot/to-json-schema@1.5.0': + resolution: {integrity: sha512-GE7DmSr1C2UCWPiV0upRH6mv0cCPsqYGs819fb6srCS1tWhyXrkGGe+zxUiwzn/L1BOfADH4sNjY/YHCuP8phQ==} + peerDependencies: + valibot: ^1.2.0 + + '@vitejs/plugin-react@5.1.4': + resolution: {integrity: sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 @@ -5402,17 +5517,6 @@ packages: '@vitest/expect@4.0.18': resolution: {integrity: sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==} - '@vitest/mocker@3.2.4': - resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} - peerDependencies: - msw: ^2.4.9 - vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 - peerDependenciesMeta: - msw: - optional: true - vite: - optional: true - '@vitest/mocker@4.0.18': resolution: {integrity: sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==} peerDependencies: @@ -5448,17 +5552,11 @@ packages: '@vitest/utils@4.0.18': resolution: {integrity: sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==} - '@vue/reactivity@3.5.26': - resolution: {integrity: sha512-9EnYB1/DIiUYYnzlnUBgwU32NNvLp/nhxLXeWRhHUEeWNTn1ECxX8aGO7RTXeX6PPcxe3LLuNBFoJbV4QZ+CFQ==} - - '@vue/reactivity@3.5.28': - resolution: {integrity: sha512-gr5hEsxvn+RNyu9/9o1WtdYdwDjg5FgjUSBEkZWqgTKlo/fvwZ2+8W6AfKsc9YN2k/+iHYdS9vZYAhpi10kNaw==} - - '@vue/shared@3.5.26': - resolution: {integrity: sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A==} + '@vue/reactivity@3.5.29': + resolution: {integrity: sha512-zcrANcrRdcLtmGZETBxWqIkoQei8HaFpZWx/GHKxx79JZsiZ8j1du0VUJtu4eJjgFvU/iKL5lRXFXksVmI+5DA==} - '@vue/shared@3.5.28': - resolution: {integrity: sha512-cfWa1fCGBxrvaHRhvV3Is0MgmrbSCxYTXCSCau2I0a1Xw1N1pHAvkWCiXPRAqjvToILvguNyEwjevUqAuBQWvQ==} + '@vue/shared@3.5.29': + resolution: {integrity: sha512-w7SR0A5zyRByL9XUkCfdLs7t9XOHUyJ67qPGQjOou3p6GvBeBW+AVjUUmlxtZ4PIYaRvE+1LmK44O4uajlZwcg==} '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -5561,12 +5659,12 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn-walk@8.3.4: - resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + acorn-walk@8.3.5: + resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==} engines: {node: '>=0.4.0'} - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} engines: {node: '>=0.4.0'} hasBin: true @@ -5582,10 +5680,6 @@ packages: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} - agentkeepalive@4.6.0: - resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} - engines: {node: '>= 8.0.0'} - ajv-formats@2.1.1: resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} peerDependencies: @@ -5604,12 +5698,15 @@ packages: peerDependencies: ajv: ^8.8.2 - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@6.14.0: + resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + ajv@8.18.0: + resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} + ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -5648,13 +5745,6 @@ packages: app-builder-bin@5.0.0-alpha.12: resolution: {integrity: sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w==} - app-builder-lib@26.3.1: - resolution: {integrity: sha512-TA6SCnyfZkUVv+QUwNlF75bq9Fq9/zHRm3l1dNa5RZx2a/mtOI71In82O2aglu3uHhmqUwmjkgPxxmkp4pvDmw==} - engines: {node: '>=14.0.0'} - peerDependencies: - dmg-builder: 26.3.1 - electron-builder-squirrel-windows: 26.3.1 - app-builder-lib@26.4.0: resolution: {integrity: sha512-Uas6hNe99KzP3xPWxh5LGlH8kWIVjZixzmMJHNB9+6hPyDpjc7NQMkVgi16rQDdpCFy22ZU5sp8ow7tvjeMgYQ==} engines: {node: '>=14.0.0'} @@ -5662,6 +5752,21 @@ packages: dmg-builder: 26.4.0 electron-builder-squirrel-windows: 26.4.0 + app-builder-lib@26.8.1: + resolution: {integrity: sha512-p0Im/Dx5C4tmz8QEE1Yn4MkuPC8PrnlRneMhWJj7BBXQfNTJUshM/bp3lusdEsDbvvfJZpXWnYesgSLvwtM2Zw==} + engines: {node: '>=14.0.0'} + peerDependencies: + dmg-builder: 26.8.1 + electron-builder-squirrel-windows: 26.8.1 + + archiver-utils@5.0.2: + resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==} + engines: {node: '>= 14'} + + archiver@7.0.1: + resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==} + engines: {node: '>= 14'} + arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} @@ -5746,8 +5851,8 @@ packages: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} - autoprefixer@10.4.23: - resolution: {integrity: sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==} + autoprefixer@10.4.27: + resolution: {integrity: sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: @@ -5757,19 +5862,31 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + aws-ssl-profiles@1.1.2: + resolution: {integrity: sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==} + engines: {node: '>= 6.0.0'} + axe-core@4.11.1: resolution: {integrity: sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A==} engines: {node: '>=4'} - axios@1.13.2: - resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} + axios@1.13.6: + resolution: {integrity: sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==} axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} - babel-dead-code-elimination@1.0.11: - resolution: {integrity: sha512-mwq3W3e/pKSI6TG8lXMiDWvEi1VXYlSBlJlB3l+I0bAb5u1RNUl88udos85eOPNK3m5EXK9uO7d2g08pesTySQ==} + b4a@1.8.0: + resolution: {integrity: sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==} + peerDependencies: + react-native-b4a: '*' + peerDependenciesMeta: + react-native-b4a: + optional: true + + babel-dead-code-elimination@1.0.12: + resolution: {integrity: sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==} babel-plugin-const-enum@1.2.0: resolution: {integrity: sha512-o1m/6iyyFnp9MRsK1dHF3bneqyf3AlM2q3A/YbgQr2pCat6B6XJVDv2TXqzfY2RYUi4mak6WAksSBPlyYGx9dg==} @@ -5780,8 +5897,8 @@ packages: resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} engines: {node: '>=10', npm: '>=6'} - babel-plugin-polyfill-corejs2@0.4.14: - resolution: {integrity: sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==} + babel-plugin-polyfill-corejs2@0.4.15: + resolution: {integrity: sha512-hR3GwrRwHUfYwGfrisXPIDP3JcYfBrW7wKE7+Au6wDYl7fm/ka1NEII6kORzxNU556JjfidZeBsO10kYvtV1aw==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -5790,8 +5907,13 @@ packages: peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-regenerator@0.6.5: - resolution: {integrity: sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==} + babel-plugin-polyfill-corejs3@0.14.0: + resolution: {integrity: sha512-AvDcMxJ34W4Wgy4KBIIePQTAOP1Ie2WFwkQp3dB7FQ/f0lI5+nM96zUnYEOE1P9sEg0es5VCP0HxiWu5fUHZAQ==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-regenerator@0.6.6: + resolution: {integrity: sha512-hYm+XLYRMvupxiQzrvXUj7YyvFFVfv5gI0R71AJzudg1g2AI2vyCPPIFEBjk162/wFzti3inBHo7isWFuEVS/A==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -5813,15 +5935,54 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - balanced-match@4.0.2: - resolution: {integrity: sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==} - engines: {node: 20 || >=22} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + bare-events@2.8.2: + resolution: {integrity: sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==} + peerDependencies: + bare-abort-controller: '*' + peerDependenciesMeta: + bare-abort-controller: + optional: true + + bare-fs@4.5.5: + resolution: {integrity: sha512-XvwYM6VZqKoqDll8BmSww5luA5eflDzY0uEFfBJtFKe4PAAtxBjU3YIxzIBzhyaEQBy1VXEQBto4cpN5RZJw+w==} + engines: {bare: '>=1.16.0'} + peerDependencies: + bare-buffer: '*' + peerDependenciesMeta: + bare-buffer: + optional: true + + bare-os@3.7.1: + resolution: {integrity: sha512-ebvMaS5BgZKmJlvuWh14dg9rbUI84QeV3WlWn6Ph6lFI8jJoh7ADtVTyD2c93euwbe+zgi0DVrl4YmqXeM9aIA==} + engines: {bare: '>=1.14.0'} + + bare-path@3.0.0: + resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} + + bare-stream@2.8.0: + resolution: {integrity: sha512-reUN0M2sHRqCdG4lUK3Fw8w98eeUIZHL5c3H7Mbhk2yVBL+oofgaIp0ieLfD5QXwPCypBpmEEKU2WZKzbAk8GA==} + peerDependencies: + bare-buffer: '*' + bare-events: '*' + peerDependenciesMeta: + bare-buffer: + optional: true + bare-events: + optional: true + + bare-url@2.3.2: + resolution: {integrity: sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==} base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.9.11: - resolution: {integrity: sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==} + baseline-browser-mapping@2.10.0: + resolution: {integrity: sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==} + engines: {node: '>=6.0.0'} hasBin: true basic-auth@2.0.1: @@ -5831,8 +5992,8 @@ packages: before-after-hook@4.0.0: resolution: {integrity: sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==} - better-auth@1.4.18: - resolution: {integrity: sha512-bnyifLWBPcYVltH3RhS7CM62MoelEqC6Q+GnZwfiDWNfepXoQZBjEvn4urcERC7NTKgKq5zNBM8rvPvRBa6xcg==} + better-auth@1.4.21: + resolution: {integrity: sha512-qdrIZS7xnGF2HPBV5wYNPWTkPojhauOOjz1+MhLvwFy+zXpgLofQmWsI5I9DY+ef845NKt93XcgpyAc4RPPT9A==} peerDependencies: '@lynx-js/react': '*' '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0 @@ -5893,43 +6054,110 @@ packages: vue: optional: true - better-call@1.1.8: - resolution: {integrity: sha512-XMQ2rs6FNXasGNfMjzbyroSwKwYbZ/T3IxruSS6U2MJRsSYh3wYtG3o6H00ZlKZ/C/UPOAD97tqgQJNsxyeTXw==} + better-auth@1.5.4: + resolution: {integrity: sha512-ReykcEKx6Kp9560jG1wtlDBnftA7L7xb3ZZdDWm5yGXKKe2pUf+oBjH0fqekrkRII0m4XBVQbQ0mOrFv+3FdYg==} peerDependencies: - zod: ^4.0.0 + '@lynx-js/react': '*' + '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0 + '@sveltejs/kit': ^2.0.0 + '@tanstack/react-start': ^1.0.0 + '@tanstack/solid-start': ^1.0.0 + better-sqlite3: ^12.0.0 + drizzle-kit: '>=0.31.4' + drizzle-orm: '>=0.41.0' + mongodb: ^6.0.0 || ^7.0.0 + mysql2: ^3.0.0 + next: ^14.0.0 || ^15.0.0 || ^16.0.0 + pg: ^8.0.0 + prisma: ^5.0.0 || ^6.0.0 || ^7.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + solid-js: ^1.0.0 + svelte: ^4.0.0 || ^5.0.0 + vitest: ^2.0.0 || ^3.0.0 || ^4.0.0 + vue: ^3.0.0 peerDependenciesMeta: - zod: + '@lynx-js/react': optional: true + '@prisma/client': + optional: true + '@sveltejs/kit': + optional: true + '@tanstack/react-start': + optional: true + '@tanstack/solid-start': + optional: true + better-sqlite3: + optional: true + drizzle-kit: + optional: true + drizzle-orm: + optional: true + mongodb: + optional: true + mysql2: + optional: true + next: + optional: true + pg: + optional: true + prisma: + optional: true + react: + optional: true + react-dom: + optional: true + solid-js: + optional: true + svelte: + optional: true + vitest: + optional: true + vue: + optional: true + + better-call@1.1.8: + resolution: {integrity: sha512-XMQ2rs6FNXasGNfMjzbyroSwKwYbZ/T3IxruSS6U2MJRsSYh3wYtG3o6H00ZlKZ/C/UPOAD97tqgQJNsxyeTXw==} + peerDependencies: + zod: ^4.0.0 + peerDependenciesMeta: + zod: + optional: true + + better-call@1.3.2: + resolution: {integrity: sha512-4cZIfrerDsNTn3cm+MhLbUePN0gdwkhSXEuG7r/zuQ8c/H7iU0/jSK5TD3FW7U0MgKHce/8jGpPYNO4Ve+4NBw==} + peerDependencies: + zod: ^4.0.0 + peerDependenciesMeta: + zod: + optional: true + + better-sqlite3@12.6.2: + resolution: {integrity: sha512-8VYKM3MjCa9WcaSAI3hzwhmyHVlH8tiGFwf0RlTsZPWJ1I5MkzjiudCo4KC4DxOaL/53A5B1sI/IbldNFDbsKA==} + engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + bippy@0.5.30: + resolution: {integrity: sha512-8CFmJAHD3gmTLDOCDHuWhjm1nxHSFZdlGoWtak9r53Uxn36ynOjxBLyxXHh/7h/XiKLyPvfdXa0gXWcD9o9lLQ==} + peerDependencies: + react: '>=17.0.1' + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + body-parser@1.20.4: + resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - better-sqlite3@12.6.2: - resolution: {integrity: sha512-8VYKM3MjCa9WcaSAI3hzwhmyHVlH8tiGFwf0RlTsZPWJ1I5MkzjiudCo4KC4DxOaL/53A5B1sI/IbldNFDbsKA==} - engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x} - - big.js@5.2.2: - resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} - - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - - bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - - bippy@0.3.34: - resolution: {integrity: sha512-vmptmU/20UdIWHHhq7qCSHhHzK7Ro3YJ1utU0fBG7ujUc58LEfTtilKxcF0IOgSjT5XLcm7CBzDjbv4lcKApGQ==} - peerDependencies: - react: '>=17.0.1' - - bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - - body-parser@1.20.4: - resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - - boolbase@1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - boolean@3.2.0: resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. @@ -5940,9 +6168,9 @@ packages: brace-expansion@2.0.2: resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} - brace-expansion@5.0.2: - resolution: {integrity: sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==} - engines: {node: 20 || >=22} + brace-expansion@5.0.4: + resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==} + engines: {node: 18 || 20 || >=22} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} @@ -5953,6 +6181,10 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + bson@7.2.0: + resolution: {integrity: sha512-YCEo7KjMlbNlyHhz7zAZNDpIpQbd+wOEHJYezv0nMYTn4x31eIUM2yomNNubclAt63dObUzKHWsBLJ9QcZNSnQ==} + engines: {node: '>=20.19.0'} + btoa@1.2.1: resolution: {integrity: sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==} engines: {node: '>= 0.4.0'} @@ -5961,22 +6193,29 @@ packages: buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + buffer-crc32@1.0.0: + resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==} + engines: {node: '>=8.0.0'} + buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + builder-util-runtime@9.5.1: resolution: {integrity: sha512-qt41tMfgHTllhResqM5DcnHyDIWNgzHvuY2jDcYP9iaGpkWxTUzV6GQjDeLnlR1/DtdlcsWQbA7sByMpmJFTLQ==} engines: {node: '>=12.0.0'} - builder-util@26.3.1: - resolution: {integrity: sha512-pplZEYBx1g15qvIOshpR1WTwjAwQM4ukhGgSNdYPnbuM6wLePq3+njy1sGfekCrJmUP+2xfuwuT9zEoUWfX5zQ==} - builder-util@26.3.4: resolution: {integrity: sha512-aRn88mYMktHxzdqDMF6Ayj0rKoX+ZogJ75Ck7RrIqbY/ad0HBvnS2xA4uHfzrGr5D2aLL3vU6OBEH4p0KMV2XQ==} + builder-util@26.8.1: + resolution: {integrity: sha512-pm1lTYbGyc90DHgCDO7eo8Rl4EqKLciayNbZqGziqnH9jrlKe8ZANGdityLZU+pJh16dfzjAx2xQq9McuIPEtw==} + bundle-name@4.1.0: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} engines: {node: '>=18'} @@ -5991,6 +6230,14 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} + c12@3.1.0: + resolution: {integrity: sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw==} + peerDependencies: + magicast: ^0.3.5 + peerDependenciesMeta: + magicast: + optional: true + c12@3.3.3: resolution: {integrity: sha512-750hTRvgBy5kcMNPdh95Qo+XUBeGo8C7nsKSmedDmaQI+E0r82DwHeM6vBewDe4rGFbnxoa4V9pw+sPh5+Iz8Q==} peerDependencies: @@ -6039,11 +6286,8 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-api@3.0.0: - resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} - - caniuse-lite@1.0.30001762: - resolution: {integrity: sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw==} + caniuse-lite@1.0.30001777: + resolution: {integrity: sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ==} ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -6142,6 +6386,10 @@ packages: resolution: {integrity: sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==} engines: {node: '>=8'} + ci-info@4.4.0: + resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} + engines: {node: '>=8'} + citty@0.1.6: resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} @@ -6211,9 +6459,6 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - colord@2.9.3: - resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} - colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} @@ -6240,6 +6485,10 @@ packages: resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} engines: {node: '>=18'} + commander@14.0.3: + resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} + engines: {node: '>=20'} + commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -6259,8 +6508,8 @@ packages: resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} engines: {node: ^12.20.0 || >=14} - comment-parser@1.4.1: - resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} + comment-parser@1.4.5: + resolution: {integrity: sha512-aRDkn3uyIlCFfk5NUA+VdwMmMsh8JGhc4hapfV4yxymHGQ3BVskMQfoXGpCo5IoBuQ9tS5iiVKhCpTcB4pW4qw==} engines: {node: '>= 12.0.0'} commondir@1.0.1: @@ -6270,6 +6519,10 @@ packages: resolution: {integrity: sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==} engines: {node: '>=0.10.0'} + compress-commons@6.0.2: + resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} + engines: {node: '>= 14'} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -6314,8 +6567,8 @@ packages: resolution: {integrity: sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==} engines: {node: '>= 0.8'} - core-js-compat@3.47.0: - resolution: {integrity: sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==} + core-js-compat@3.48.0: + resolution: {integrity: sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==} core-util-is@1.0.2: resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} @@ -6340,8 +6593,8 @@ packages: typescript: optional: true - cosmiconfig@9.0.0: - resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + cosmiconfig@9.0.1: + resolution: {integrity: sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==} engines: {node: '>=14'} peerDependencies: typescript: '>=4.9.5' @@ -6349,6 +6602,15 @@ packages: typescript: optional: true + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + crc32-stream@6.0.0: + resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==} + engines: {node: '>= 14'} + crc@3.8.0: resolution: {integrity: sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==} @@ -6369,22 +6631,9 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} - css-declaration-sorter@6.4.1: - resolution: {integrity: sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==} - engines: {node: ^10 || ^12 || >=14} - peerDependencies: - postcss: ^8.0.9 - - css-select@4.3.0: - resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} - css-select@5.2.2: resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} - css-tree@1.1.3: - resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} - engines: {node: '>=8.0.0'} - css-tree@2.2.1: resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} @@ -6405,28 +6654,6 @@ packages: engines: {node: '>=4'} hasBin: true - cssnano-preset-default@5.2.14: - resolution: {integrity: sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - cssnano-utils@3.1.0: - resolution: {integrity: sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - cssnano@5.1.15: - resolution: {integrity: sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - csso@4.2.0: - resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==} - engines: {node: '>=8.0.0'} - csso@5.0.5: resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} @@ -6536,6 +6763,10 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + deepmerge-ts@7.1.5: + resolution: {integrity: sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==} + engines: {node: '>=16.0.0'} + deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} @@ -6544,8 +6775,8 @@ packages: resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} engines: {node: '>=18'} - default-browser@5.4.0: - resolution: {integrity: sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg==} + default-browser@5.5.0: + resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} engines: {node: '>=18'} defaults@1.0.4: @@ -6581,6 +6812,10 @@ packages: delegates@1.0.0: resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + denque@2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} + depd@1.1.2: resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} engines: {node: '>= 0.6'} @@ -6600,11 +6835,6 @@ packages: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - detect-libc@1.0.3: - resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} - engines: {node: '>=0.10'} - hasBin: true - detect-libc@2.0.2: resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} engines: {node: '>=8'} @@ -6624,19 +6854,19 @@ packages: devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} - diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + diff@4.0.4: + resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==} engines: {node: '>=0.3.1'} - diff@8.0.2: - resolution: {integrity: sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==} + diff@8.0.3: + resolution: {integrity: sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==} engines: {node: '>=0.3.1'} dir-compare@4.2.0: resolution: {integrity: sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ==} - dmg-builder@26.3.1: - resolution: {integrity: sha512-hYOlXCqmBxFXz8TZrAGm/Ym5ji+/Am5sgQaT+yZ/VULb9O+E7Lr1Z0HFnKk8GaaYfULV8PDVCYO4/bpQyb+BSg==} + dmg-builder@26.8.1: + resolution: {integrity: sha512-glMJgnTreo8CFINujtAhCgN96QAqApDMZ8Vl1r8f0QT8QprvC1UCltV4CcWj20YoIyLZx6IUskaJZ0NV8fokcg==} dmg-license@1.0.11: resolution: {integrity: sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==} @@ -6658,26 +6888,16 @@ packages: dom-accessibility-api@0.6.3: resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} - dom-serializer@1.4.1: - resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} - dom-serializer@2.0.0: resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} domelementtype@2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - domhandler@4.3.1: - resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} - engines: {node: '>= 4'} - domhandler@5.0.3: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} - domutils@2.8.0: - resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} - domutils@3.2.2: resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} @@ -6799,8 +7019,11 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - effect@3.19.14: - resolution: {integrity: sha512-3vwdq0zlvQOxXzXNKRIPKTqZNMyGCdaFUBfMPqpsyzZDre67kgC1EEHDV4EoQTovJ4w5fmJW756f86kkuz7WFA==} + effect@3.18.4: + resolution: {integrity: sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==} + + effect@3.19.19: + resolution: {integrity: sha512-Yc8U/SVXo2dHnaP7zNBlAo83h/nzSJpi7vph6Hzyl4ulgMBIgPmz3UzOjb9sBgpFE00gC0iETR244sfXDNLHRg==} ejs@3.1.10: resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} @@ -6810,25 +7033,25 @@ packages: electron-builder-squirrel-windows@26.4.0: resolution: {integrity: sha512-7dvalY38xBzWNaoOJ4sqy2aGIEpl2S1gLPkkB0MHu1Hu5xKQ82il1mKSFlXs6fLpXUso/NmyjdHGlSHDRoG8/w==} - electron-builder@26.3.1: - resolution: {integrity: sha512-e8utkPlf+VF94KX1M6/qZqCXsQMLKEASg+DNO5JWLtPZeKkvXS9Oyac8hb6HelvlGzEP02N7IDX6UFGjmvV66g==} + electron-builder@26.8.1: + resolution: {integrity: sha512-uWhx1r74NGpCagG0ULs/P9Nqv2nsoo+7eo4fLUOB8L8MdWltq9odW/uuLXMFCDGnPafknYLZgjNX0ZIFRzOQAw==} engines: {node: '>=14.0.0'} hasBin: true electron-devtools-installer@4.0.0: resolution: {integrity: sha512-9Tntu/jtfSn0n6N/ZI6IdvRqXpDyLQiDuuIbsBI+dL+1Ef7C8J2JwByw58P3TJiNeuqyV3ZkphpNWuZK5iSY2w==} - electron-publish@26.3.1: - resolution: {integrity: sha512-XYGYL/fpQULLW9slTVPelaUOGlKfOTmV2Uda3K+qzFzvNnkGJCj7L0nLVvMuj5cgxpAX+3BhO5HOUb4rv6jikA==} - electron-publish@26.3.4: resolution: {integrity: sha512-5/ouDPb73SkKuay2EXisPG60LTFTMNHWo2WLrK5GDphnWK9UC+yzYrzVeydj078Yk4WUXi0+TaaZsNd6Zt5k/A==} - electron-to-chromium@1.5.267: - resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} + electron-publish@26.8.1: + resolution: {integrity: sha512-q+jrSTIh/Cv4eGZa7oVR+grEJo/FoLMYBAnSL5GCtqwUpr1T+VgKB/dn1pnzxIxqD8S/jP1yilT9VrwCqINR4w==} - electron-updater@6.7.3: - resolution: {integrity: sha512-EgkT8Z9noqXKbwc3u5FkJA+r48jwZ5DTUiOkJMOTEEH//n5Am6wfQGz7nvSFEA2oIAMv9jRzn5JKTyWeSKOPgg==} + electron-to-chromium@1.5.307: + resolution: {integrity: sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg==} + + electron-updater@6.8.3: + resolution: {integrity: sha512-Z6sgw3jgbikWKXei1ENdqFOxBP0WlXg3TtKfz0rgw2vIZFJUyI4pD7ZN7jrkm7EoMK+tcm/qTnPUdqfZukBlBQ==} electron-vite@5.0.0: resolution: {integrity: sha512-OHp/vjdlubNlhNkPkL/+3JD34ii5ov7M0GpuXEVdQeqdQ3ulvVR7Dg/rNBLfS5XPIFwgoBLDf9sjjrL+CuDyRQ==} @@ -6845,8 +7068,8 @@ packages: resolution: {integrity: sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==} engines: {node: '>=8.0.0'} - electron@39.2.7: - resolution: {integrity: sha512-KU0uFS6LSTh4aOIC3miolcbizOFP7N1M46VTYVfqIgFiuA2ilfNaOHLDS9tCMvwwHRowAsvqBrh9NgMXcTOHCQ==} + electron@40.8.0: + resolution: {integrity: sha512-WoPq0Nr9Yx3g7T6VnJXdwa/rr2+VRyH3a+K+ezfMKBlf6WjxE/LmhMQabKbb6yjm9RbZhJBRcYyoLph421O2mQ==} engines: {node: '>= 12.20.55'} hasBin: true @@ -6859,10 +7082,6 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - emojis-list@3.0.0: - resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} - engines: {node: '>= 4'} - empathic@2.0.0: resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} engines: {node: '>=14'} @@ -6877,8 +7096,8 @@ packages: end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - enhanced-resolve@5.18.4: - resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} + enhanced-resolve@5.20.0: + resolution: {integrity: sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==} engines: {node: '>=10.13.0'} enquirer@2.3.6: @@ -6889,9 +7108,6 @@ packages: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} engines: {node: '>=8.6'} - entities@2.2.0: - resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} - entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -6956,8 +7172,8 @@ packages: engines: {node: '>=18'} hasBin: true - esbuild@0.27.2: - resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} + esbuild@0.27.3: + resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==} engines: {node: '>=18'} hasBin: true @@ -7008,12 +7224,18 @@ packages: eslint-plugin-import-x: optional: true - eslint-plugin-better-tailwindcss@3.8.0: - resolution: {integrity: sha512-bRJVOb47d3ONK4Qb6Zt58ra37E8rMCexWy7RuNgLQZS/Ch92oLRFBupa/s+FB1O9XRdph9ZMCXBiEFKc4gAGTQ==} - engines: {node: ^20.11.0 || >=21.2.0} + eslint-plugin-better-tailwindcss@4.3.2: + resolution: {integrity: sha512-1DLX2QmHmOj3u667f8vEI0zKoRc0Y1qJt33tfIeIkpTyzWaz9b2GzWBLD4bR+WJ/kxzC0Skcbx7cMerRWQ6OYg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23.0.0} peerDependencies: - eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 - tailwindcss: ^3.3.0 || ^4.1.6 + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 + oxlint: ^1.35.0 + tailwindcss: ^3.3.0 || ^4.1.17 + peerDependenciesMeta: + eslint: + optional: true + oxlint: + optional: true eslint-plugin-import-x@4.16.1: resolution: {integrity: sha512-vPZZsiOKaBAIATpFE2uMI4w5IRwdv/FpQ+qZZMR4E+PeOcM4OeoEbqxRMnywdxP19TyB/3h6QBB0EWon7letSQ==} @@ -7034,11 +7256,11 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 - eslint-plugin-perfectionist@5.3.0: - resolution: {integrity: sha512-Y3qYps6MpFrwyR+6DGd479GrgEA2PmCNWJ10Q6LnnfQfJTTtb0DNaKOjF5TAQc4wz/9mHwA8lx9ruR5EdFcylA==} + eslint-plugin-perfectionist@5.6.0: + resolution: {integrity: sha512-pxrLrfRp5wl1Vol1fAEa/G5yTXxefTPJjz07qC7a8iWFXcOZNuWBItMQ2OtTzfQIvMq6bMyYcrzc3Wz++na55Q==} engines: {node: ^20.0.0 || >=22.0.0} peerDependencies: - eslint: '>=8.45.0' + eslint: ^8.45.0 || ^9.0.0 || ^10.0.0 eslint-plugin-react-hooks@7.0.1: resolution: {integrity: sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==} @@ -7068,6 +7290,10 @@ packages: resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + eslint@9.39.2: resolution: {integrity: sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -7106,9 +7332,6 @@ packages: estree-util-is-identifier-name@3.0.0: resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} - estree-walker@0.6.1: - resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} - estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} @@ -7130,6 +7353,9 @@ packages: eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + events-universal@1.0.1: + resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==} + events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} @@ -7178,6 +7404,9 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} @@ -7188,9 +7417,18 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-string-truncated-width@3.0.3: + resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} + + fast-string-width@3.0.2: + resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} + fast-uri@3.1.0: resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + fast-wrap-ansi@0.2.0: + resolution: {integrity: sha512-rLV8JHxTyhVmFYhBJuMujcrHqOT2cnO5Zxj37qROj23CP39GXubJRBUFF0z8KFK77Uc0SukZUf7JZhsVEQ6n8w==} + fastq@1.20.1: resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} @@ -7218,17 +7456,11 @@ packages: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} - file-loader@6.2.0: - resolution: {integrity: sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==} - engines: {node: '>= 10.13.0'} - peerDependencies: - webpack: ^4.0.0 || ^5.0.0 - file-uri-to-path@1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - filelist@1.0.4: - resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + filelist@1.0.6: + resolution: {integrity: sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==} fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} @@ -7275,8 +7507,8 @@ packages: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + flatted@3.3.4: + resolution: {integrity: sha512-3+mMldrTAPdta5kjX2G2J7iX4zxtnwpdA8Tr2ZSjkyPSanvbZAcy6flmtnXbEybHrDcU9641lxrMfFuUxVz9vA==} follow-redirects@1.15.11: resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} @@ -7295,17 +7527,10 @@ packages: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} - form-data-encoder@1.7.2: - resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==} - form-data@4.0.5: resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} engines: {node: '>= 6'} - formdata-node@4.4.1: - resolution: {integrity: sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==} - engines: {node: '>= 12.20'} - formdata-polyfill@4.0.10: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} @@ -7335,8 +7560,8 @@ packages: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} - fs-extra@11.3.3: - resolution: {integrity: sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==} + fs-extra@11.3.4: + resolution: {integrity: sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==} engines: {node: '>=14.14'} fs-extra@7.0.1: @@ -7362,11 +7587,6 @@ packages: fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -7382,6 +7602,9 @@ packages: functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + generate-function@2.3.1: + resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==} + generator-function@2.0.1: resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} engines: {node: '>= 0.4'} @@ -7397,14 +7620,17 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-east-asian-width@1.4.0: - resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==} + get-east-asian-width@1.5.0: + resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} engines: {node: '>=18'} get-intrinsic@1.3.0: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} + get-port-please@3.2.0: + resolution: {integrity: sha512-I9QVvBw5U/hw3RmWpYKRumUeaDgxTPd401x364rLmWBJcOQ753eov1eTgzDqRG9bqFIfDc7gfzcQEWrUri3o1A==} + get-proto@1.0.1: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} @@ -7417,8 +7643,8 @@ packages: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} - get-tsconfig@4.13.0: - resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} + get-tsconfig@4.13.6: + resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==} giget@2.0.0: resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} @@ -7443,15 +7669,9 @@ packages: deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true - glob@11.1.0: - resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==} - engines: {node: 20 || >=22} - deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me - hasBin: true - - glob@13.0.0: - resolution: {integrity: sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==} - engines: {node: 20 || >=22} + glob@13.0.6: + resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} + engines: {node: 18 || 20 || >=22} glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} @@ -7478,8 +7698,8 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@17.0.0: - resolution: {integrity: sha512-gv5BeD2EssA793rlFWVPMMCqefTlpusw6/2TbAVMy0FzcG8wKJn4O+NqJ4+XWmmwrayJgw5TzrmWjFgmz1XPqw==} + globals@17.4.0: + resolution: {integrity: sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw==} engines: {node: '>=18'} globalthis@1.0.4: @@ -7490,8 +7710,8 @@ packages: resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==} engines: {node: '>=18'} - globby@16.0.0: - resolution: {integrity: sha512-ejy4TJFga99yW6Q0uhM3pFawKWZmtZzZD/v/GwI5+9bCV5Ew+D2pSND6W7fUes5UykqSsJkUfxFVdRh7Q1+P3Q==} + globby@16.1.1: + resolution: {integrity: sha512-dW7vl+yiAJSp6aCekaVnVJxurRv7DCOLyXqEG3RYMYUg7AuJ2jCqPkZTA8ooqC2vtnkaMcV5WfFBMuEnTu1OQg==} engines: {node: '>=20'} globrex@0.1.2: @@ -7513,6 +7733,12 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + grammex@3.1.12: + resolution: {integrity: sha512-6ufJOsSA7LcQehIJNCO7HIBykfM7DXQual0Ny780/DEcJIpBlHRvcqEBWGPYd7hrXL2GJ3oJI1MIhaXjWmLQOQ==} + + graphmatch@1.1.1: + resolution: {integrity: sha512-5ykVn/EXM1hF0XCaWh05VbYvEiOL2lY1kBxZtaYsyvjp7cmWOU1XsAdfQBwClraEofXDT197lFbXOEVMHpvQOg==} + has-bigints@1.1.0: resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} engines: {node: '>= 0.4'} @@ -7563,6 +7789,10 @@ packages: resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} engines: {node: '>=0.10.0'} + hono@4.11.4: + resolution: {integrity: sha512-U7tt8JsyrxSRKspfhtLET79pU8K+tInj5QZXs1jSugO1Vq5dFj3kmZsRldo29mTBfcjDRVRXrEZ6LS63Cog9ZA==} + engines: {node: '>=16.9.0'} + hosted-git-info@4.1.0: resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} engines: {node: '>=10'} @@ -7617,6 +7847,9 @@ packages: engines: {node: '>=12'} hasBin: true + http-status-codes@2.3.0: + resolution: {integrity: sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==} + http2-wrapper@1.0.3: resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} engines: {node: '>=10.19.0'} @@ -7625,9 +7858,6 @@ packages: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} - humanize-ms@1.2.1: - resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} - iconv-corefoundation@1.1.7: resolution: {integrity: sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==} engines: {node: ^8.11.2 || >=10} @@ -7641,13 +7871,10 @@ packages: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} - iconv-lite@0.7.1: - resolution: {integrity: sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==} + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} engines: {node: '>=0.10.0'} - icss-replace-symbols@1.1.0: - resolution: {integrity: sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==} - icss-utils@5.1.0: resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} engines: {node: ^10 || ^12 || >= 14} @@ -7672,18 +7899,10 @@ packages: immediate@3.0.6: resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} - import-cwd@3.0.0: - resolution: {integrity: sha512-4pnzH16plW+hgvRECbDWpQl3cqtvSofHWh44met7ESfZ8UZOWWddm8hEyDTqREJ9RbYHY8gi8DqmaelApoOGMg==} - engines: {node: '>=8'} - import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} - import-from@3.0.0: - resolution: {integrity: sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ==} - engines: {node: '>=8'} - imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} @@ -7856,6 +8075,9 @@ packages: resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} engines: {node: '>=0.10.0'} + is-property@1.0.2: + resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==} + is-reference@1.2.1: resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} @@ -7871,6 +8093,10 @@ packages: resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} engines: {node: '>= 0.4'} + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + is-string@1.1.1: resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} engines: {node: '>= 0.4'} @@ -7915,8 +8141,8 @@ packages: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} - is-wsl@3.1.0: - resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + is-wsl@3.1.1: + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} engines: {node: '>=16'} isarray@1.0.0: @@ -7933,16 +8159,16 @@ packages: resolution: {integrity: sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ==} engines: {node: '>= 18.0.0'} - isbot@5.1.32: - resolution: {integrity: sha512-VNfjM73zz2IBZmdShMfAUg10prm6t7HFUQmNAEOAVS4YH92ZrZcvkMcGX6cIgBJAzWDzPent/EeAtYEHNPNPBQ==} + isbot@5.1.35: + resolution: {integrity: sha512-waFfC72ZNfwLLuJ2iLaoVaqcNo+CAaLR7xCpAn0Y5WfGzkNHv7ZN39Vbi1y+kb+Zs46XHOX3tZNExroFUPX+Kg==} engines: {node: '>=18'} isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - isexe@3.1.1: - resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} - engines: {node: '>=16'} + isexe@3.1.5: + resolution: {integrity: sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==} + engines: {node: '>=18'} isomorphic-ws@5.0.0: resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} @@ -7956,14 +8182,6 @@ packages: jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - jackspeak@4.1.1: - resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} - engines: {node: 20 || >=22} - - jackspeak@4.2.3: - resolution: {integrity: sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==} - engines: {node: 20 || >=22} - jake@10.9.4: resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} engines: {node: '>=10'} @@ -7985,8 +8203,8 @@ packages: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true - jose@6.1.3: - resolution: {integrity: sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==} + jose@6.2.0: + resolution: {integrity: sha512-xsfE1TcSCbUdo6U07tR0mvhg0flGxU8tPLbF03mirl2ukGQENhUg4ubGYQnhVH0b5stLlPM+WOqDkEl1R1y5sQ==} joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} @@ -8029,6 +8247,9 @@ packages: json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + json-with-bigint@3.5.7: + resolution: {integrity: sha512-7ei3MdAI5+fJPVnKlW77TKNKwQ5ppSzWvhPuSuINT/GYW9ZOC1eRKOuhV9yHG5aEsUPj9BBx5JIekkmoLHxZOw==} + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -8068,10 +8289,6 @@ packages: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} - kleur@4.1.5: - resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} - engines: {node: '>=6'} - koa-compose@4.1.0: resolution: {integrity: sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==} @@ -8096,6 +8313,10 @@ packages: lazy-val@1.0.5: resolution: {integrity: sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==} + lazystream@1.0.1: + resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} + engines: {node: '>= 0.6.3'} + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -8108,74 +8329,74 @@ packages: lie@3.3.0: resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} - lightningcss-android-arm64@1.30.2: - resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==} + lightningcss-android-arm64@1.31.1: + resolution: {integrity: sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [android] - lightningcss-darwin-arm64@1.30.2: - resolution: {integrity: sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==} + lightningcss-darwin-arm64@1.31.1: + resolution: {integrity: sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [darwin] - lightningcss-darwin-x64@1.30.2: - resolution: {integrity: sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==} + lightningcss-darwin-x64@1.31.1: + resolution: {integrity: sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [darwin] - lightningcss-freebsd-x64@1.30.2: - resolution: {integrity: sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==} + lightningcss-freebsd-x64@1.31.1: + resolution: {integrity: sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [freebsd] - lightningcss-linux-arm-gnueabihf@1.30.2: - resolution: {integrity: sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==} + lightningcss-linux-arm-gnueabihf@1.31.1: + resolution: {integrity: sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==} engines: {node: '>= 12.0.0'} cpu: [arm] os: [linux] - lightningcss-linux-arm64-gnu@1.30.2: - resolution: {integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==} + lightningcss-linux-arm64-gnu@1.31.1: + resolution: {integrity: sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - lightningcss-linux-arm64-musl@1.30.2: - resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} + lightningcss-linux-arm64-musl@1.31.1: + resolution: {integrity: sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - lightningcss-linux-x64-gnu@1.30.2: - resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} + lightningcss-linux-x64-gnu@1.31.1: + resolution: {integrity: sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - lightningcss-linux-x64-musl@1.30.2: - resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} + lightningcss-linux-x64-musl@1.31.1: + resolution: {integrity: sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - lightningcss-win32-arm64-msvc@1.30.2: - resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} + lightningcss-win32-arm64-msvc@1.31.1: + resolution: {integrity: sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [win32] - lightningcss-win32-x64-msvc@1.30.2: - resolution: {integrity: sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==} + lightningcss-win32-x64-msvc@1.31.1: + resolution: {integrity: sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [win32] - lightningcss@1.30.2: - resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==} + lightningcss@1.31.1: + resolution: {integrity: sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==} engines: {node: '>= 12.0.0'} lilconfig@2.1.0: @@ -8206,10 +8427,6 @@ packages: resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} engines: {node: '>=6.11.5'} - loader-utils@2.0.4: - resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==} - engines: {node: '>=8.9.0'} - loader-utils@3.3.1: resolution: {integrity: sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==} engines: {node: '>= 12.13.0'} @@ -8238,15 +8455,9 @@ packages: resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. - lodash.memoize@4.1.2: - resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} - lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - lodash.uniq@4.5.0: - resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} - lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} @@ -8268,6 +8479,9 @@ packages: long-timeout@0.1.1: resolution: {integrity: sha512-BFRuQUqc7x2NWxfJBCyUrN8iYUYznzL9JROmRz1gZ6KlOIgmoD+njPVbb+VNn2nGMKggMsK79iUNErillsrx7w==} + long@5.3.2: + resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} + longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} @@ -8288,8 +8502,8 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.2.4: - resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} + lru-cache@11.2.6: + resolution: {integrity: sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==} engines: {node: 20 || >=22} lru-cache@5.1.1: @@ -8299,6 +8513,10 @@ packages: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} + lru.min@1.1.4: + resolution: {integrity: sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA==} + engines: {bun: '>=1.0.0', deno: '>=1.30.0', node: '>=8.0.0'} + luxon@3.7.2: resolution: {integrity: sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==} engines: {node: '>=12'} @@ -8344,8 +8562,8 @@ packages: mdast-util-find-and-replace@3.0.2: resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} - mdast-util-from-markdown@2.0.2: - resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + mdast-util-from-markdown@2.0.3: + resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==} mdast-util-gfm-autolink-literal@2.0.1: resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} @@ -8386,9 +8604,6 @@ packages: mdast-util-to-string@4.0.0: resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} - mdn-data@2.0.14: - resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} - mdn-data@2.0.28: resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} @@ -8406,6 +8621,9 @@ packages: resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} engines: {node: '>= 0.8'} + memory-pager@1.5.0: + resolution: {integrity: sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==} + merge-descriptors@1.0.3: resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} @@ -8563,29 +8781,25 @@ packages: resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==} hasBin: true - minimatch@10.1.1: - resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} - engines: {node: 20 || >=22} - - minimatch@10.2.1: - resolution: {integrity: sha512-MClCe8IL5nRRmawL6ib/eT4oLyeKMGCghibcDWK+J0hh0Q8kqSdia6BvbRMVk6mPa6WqUa5uR2oxt6C5jd533A==} - engines: {node: 20 || >=22} + minimatch@10.2.4: + resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} + engines: {node: 18 || 20 || >=22} - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} - minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + minimatch@5.1.9: + resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} engines: {node: '>=10'} - minimatch@9.0.3: - resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} - engines: {node: '>=16 || 14 >=14.17'} - minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} + engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -8597,8 +8811,8 @@ packages: resolution: {integrity: sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ==} engines: {node: ^18.17.0 || >=20.5.0} - minipass-fetch@5.0.0: - resolution: {integrity: sha512-fiCdUALipqgPWrOVTz9fw0XhcazULXOSU6ie40DDbX1F49p1dBrSRBuswndTx1x3vEb/g0FT7vC4c4C2u/mh3A==} + minipass-fetch@5.0.2: + resolution: {integrity: sha512-2d0q2a8eCi2IRg/IGubCNRJoYbA1+YPXAzQVRFmB45gdGZafyivnZ5YSEfo3JikbjGxOdntGFvBQGqaSMXlAFQ==} engines: {node: ^20.17.0 || >=22.9.0} minipass-flush@1.0.5: @@ -8613,6 +8827,10 @@ packages: resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} engines: {node: '>=8'} + minipass-sized@2.0.0: + resolution: {integrity: sha512-zSsHhto5BcUVM2m1LurnXY6M//cGhVaegT71OfOXoprxT6o780GZd792ea6FfrQkuU4usHZIUczAQMRUE2plzA==} + engines: {node: '>=8'} + minipass@3.3.6: resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} engines: {node: '>=8'} @@ -8621,8 +8839,8 @@ packages: resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} engines: {node: '>=8'} - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} minizlib@2.1.2: @@ -8645,12 +8863,39 @@ packages: engines: {node: '>=10'} hasBin: true - mlly@1.8.0: - resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} + mlly@1.8.1: + resolution: {integrity: sha512-SnL6sNutTwRWWR/vcmCYHSADjiEesp5TGQQ0pXyLhW5IoeibRlF/CbSLailbB3CNqJUk9cVJ9dUDnbD7GrcHBQ==} - mri@1.2.0: - resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} - engines: {node: '>=4'} + mongodb-connection-string-url@7.0.1: + resolution: {integrity: sha512-h0AZ9A7IDVwwHyMxmdMXKy+9oNlF0zFoahHiX3vQ8e3KFcSP3VmsmfvtRSuLPxmyv2vjIDxqty8smTgie/SNRQ==} + engines: {node: '>=20.19.0'} + + mongodb@7.1.0: + resolution: {integrity: sha512-kMfnKunbolQYwCIyrkxNJFB4Ypy91pYqua5NargS/f8ODNSJxT03ZU3n1JqL4mCzbSih8tvmMEMLpKTT7x5gCg==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@aws-sdk/credential-providers': ^3.806.0 + '@mongodb-js/zstd': ^7.0.0 + gcp-metadata: ^7.0.1 + kerberos: ^7.0.0 + mongodb-client-encryption: '>=7.0.0 <7.1.0' + snappy: ^7.3.2 + socks: ^2.8.6 + peerDependenciesMeta: + '@aws-sdk/credential-providers': + optional: true + '@mongodb-js/zstd': + optional: true + gcp-metadata: + optional: true + kerberos: + optional: true + mongodb-client-encryption: + optional: true + snappy: + optional: true + socks: + optional: true ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -8676,16 +8921,24 @@ packages: resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==} engines: {node: ^20.17.0 || >=22.9.0} + mysql2@3.15.3: + resolution: {integrity: sha512-FBrGau0IXmuqg4haEZRBfHNWB5mUARw6hNwPDXXGg0XzVJ50mr/9hb267lvpVMnhZ1FON3qNd4Xfcez1rbFwSg==} + engines: {node: '>= 8.0'} + mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + named-placeholders@1.1.6: + resolution: {integrity: sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w==} + engines: {node: '>=8.0.0'} + nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - nanostores@1.1.0: - resolution: {integrity: sha512-yJBmDJr18xy47dbNVlHcgdPrulSn1nhSE6Ns9vTG+Nx9VPT6iV1MD6aQFp/t52zpf82FhLLTXAXr30NuCnxvwA==} + nanostores@1.1.1: + resolution: {integrity: sha512-EYJqS25r2iBeTtGQCHidXl1VfZ1jXM7Q04zXJOrMlxVVmD0ptxJaNux92n1mJ7c5lN3zTq12MhH/8x59nP+qmg==} engines: {node: ^20.0.0 || >=22.0.0} napi-build-utils@2.0.0: @@ -8721,8 +8974,8 @@ packages: resolution: {integrity: sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ==} engines: {node: '>=10'} - node-abi@4.24.0: - resolution: {integrity: sha512-u2EC1CeNe25uVtX3EZbdQ275c74zdZmmpzrHEQh2aIYqoVjlglfUpOX9YY85x1nlBydEKDVaSmMNhR7N82Qj8A==} + node-abi@4.26.0: + resolution: {integrity: sha512-8QwIZqikRvDIkXS2S93LjzhsSPJuIbfaMETWH+Bx8oOT9Sa9UsUtBFQlc3gBNd1+QINjaTloitXr1W3dQLi9Iw==} engines: {node: '>=22.12.0'} node-addon-api@1.7.2: @@ -8739,6 +8992,10 @@ packages: engines: {node: '>=10.5.0'} deprecated: Use your platform's native DOMException instead + node-exports-info@1.6.0: + resolution: {integrity: sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==} + engines: {node: '>= 0.4'} + node-fetch-native@1.6.7: resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} @@ -8771,8 +9028,8 @@ packages: node-machine-id@1.1.12: resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==} - node-releases@2.0.27: - resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + node-releases@2.0.36: + resolution: {integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==} node-schedule@2.1.1: resolution: {integrity: sha512-OXdegQq03OmXEjt2hZP33W2YPs/E5BcFQks46+G2gAxs4gHOIVD1u7EqlYLYSKsaIpyKCK9Gbk0ta1/gjRSMRQ==} @@ -8810,12 +9067,12 @@ packages: nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - nx@22.3.3: - resolution: {integrity: sha512-pOxtKWUfvf0oD8Geqs8D89Q2xpstRTaSY+F6Ut/Wd0GnEjUjO32SS1ymAM6WggGPHDZN4qpNrd5cfIxQmAbRLg==} + nx@22.5.4: + resolution: {integrity: sha512-L8wL7uCjnmpyvq4r2mN9s+oriUE4lY+mX9VgOpjj0ucRd5nzaEaBQppVs0zQGkbKC0BnHS8PGtnAglspd5Gh1Q==} hasBin: true peerDependencies: - '@swc-node/register': ^1.8.0 - '@swc/core': ^1.3.85 + '@swc-node/register': ^1.11.1 + '@swc/core': ^1.15.8 peerDependenciesMeta: '@swc-node/register': optional: true @@ -8884,12 +9141,15 @@ packages: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} - openai@4.77.0: - resolution: {integrity: sha512-WWacavtns/7pCUkOWvQIjyOfcdr9X+9n9Vvb0zFeKVDAqwCMDHB+iSr24SVaBAhplvSG6JrRXFpcNM9gWhOGIw==} + openai@6.27.0: + resolution: {integrity: sha512-osTKySlrdYrLYTt0zjhY8yp0JUBmWDCN+Q+QxsV4xMQnnoVFpylgKGgxwN8sSdTNw0G4y+WUXs4eCMWpyDNWZQ==} hasBin: true peerDependencies: - zod: ^3.23.8 + ws: ^8.18.0 + zod: ^3.25 || ^4.0 peerDependenciesMeta: + ws: + optional: true zod: optional: true @@ -8917,17 +9177,13 @@ packages: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} - oxc-resolver@11.16.2: - resolution: {integrity: sha512-Uy76u47vwhhF7VAmVY61Srn+ouiOobf45MU9vGct9GD2ARy6hKoqEElyHDB0L+4JOM6VLuZ431KiLwyjI/A21g==} + oxc-resolver@11.19.1: + resolution: {integrity: sha512-qE/CIg/spwrTBFt5aKmwe3ifeDdLfA2NESN30E42X/lII5ClF8V7Wt6WIJhcGZjp0/Q+nQ+9vgxGk//xZNX2hg==} p-cancelable@2.1.1: resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} engines: {node: '>=8'} - p-finally@1.0.0: - resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} - engines: {node: '>=4'} - p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} @@ -8948,14 +9204,6 @@ packages: resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==} engines: {node: '>=18'} - p-queue@6.6.2: - resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} - engines: {node: '>=8'} - - p-timeout@3.2.0: - resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} - engines: {node: '>=8'} - p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} @@ -9004,9 +9252,9 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} - path-scurry@2.0.1: - resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} - engines: {node: 20 || >=22} + path-scurry@2.0.2: + resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} + engines: {node: 18 || 20 || >=22} path-to-regexp@0.1.12: resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} @@ -9033,33 +9281,36 @@ packages: pend@1.2.0: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + perfect-debounce@2.1.0: resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==} pg-cloudflare@1.3.0: resolution: {integrity: sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==} - pg-connection-string@2.11.0: - resolution: {integrity: sha512-kecgoJwhOpxYU21rZjULrmrBJ698U2RxXofKVzOn5UDj61BPj/qMb7diYUR1nLScCDbrztQFl1TaQZT0t1EtzQ==} + pg-connection-string@2.12.0: + resolution: {integrity: sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ==} pg-int8@1.0.1: resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} engines: {node: '>=4.0.0'} - pg-pool@3.11.0: - resolution: {integrity: sha512-MJYfvHwtGp870aeusDh+hg9apvOe2zmpZJpyt+BMtzUWlVqbhFmMK6bOBXLBUPd7iRtIF9fZplDc7KrPN3PN7w==} + pg-pool@3.13.0: + resolution: {integrity: sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA==} peerDependencies: pg: '>=8.0' - pg-protocol@1.11.0: - resolution: {integrity: sha512-pfsxk2M9M3BuGgDOfuy37VNRRX3jmKgMjcvAcWqNDpZSf4cUmv8HSOl5ViRQFsfARFn0KuUQTgLxVMbNq5NW3g==} + pg-protocol@1.13.0: + resolution: {integrity: sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==} pg-types@2.2.0: resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} engines: {node: '>=4'} - pg@8.18.0: - resolution: {integrity: sha512-xqrUDL1b9MbkydY/s+VZ6v+xiMUmOUk7SS9d/1kpyQxoJ6U9AO1oIJyUWVZojbfe5Cc/oluutcgFG4L9RDP1iQ==} + pg@8.20.0: + resolution: {integrity: sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==} engines: {node: '>= 16.0.0'} peerDependencies: pg-native: '>=3.0.1' @@ -9085,14 +9336,6 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} - pify@2.3.0: - resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} - engines: {node: '>=0.10.0'} - - pify@5.0.0: - resolution: {integrity: sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==} - engines: {node: '>=10'} - pirates@4.0.7: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} @@ -9107,16 +9350,6 @@ packages: pkg-types@2.3.0: resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} - playwright-core@1.57.0: - resolution: {integrity: sha512-agTcKlMw/mjBWOnD6kFZttAAGHgi/Nw0CZ2o6JqWSbMlI219lAFLZZCyqByTsvVAJq5XA5H8cA6PrvBRpBWEuQ==} - engines: {node: '>=18'} - hasBin: true - - playwright@1.57.0: - resolution: {integrity: sha512-ilYQj1s8sr2ppEJ2YVadYBN0Mb3mdo9J0wQ+UuDhzYqURwSoW4n1Xs5vs7ORwgDGmyEh33tRMeS8KhdkMoLXQw==} - engines: {node: '>=18'} - hasBin: true - plist@3.1.0: resolution: {integrity: sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==} engines: {node: '>=10.4.0'} @@ -9129,130 +9362,35 @@ packages: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} - postcss-calc@8.2.4: - resolution: {integrity: sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==} + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} peerDependencies: - postcss: ^8.2.2 + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true - postcss-colormin@5.3.1: - resolution: {integrity: sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==} - engines: {node: ^10 || ^12 || >=14.0} + postcss-modules-extract-imports@3.1.0: + resolution: {integrity: sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==} + engines: {node: ^10 || ^12 || >= 14} peerDependencies: - postcss: ^8.2.15 + postcss: ^8.1.0 - postcss-convert-values@5.1.3: - resolution: {integrity: sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==} - engines: {node: ^10 || ^12 || >=14.0} + postcss-modules-local-by-default@4.2.0: + resolution: {integrity: sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==} + engines: {node: ^10 || ^12 || >= 14} peerDependencies: - postcss: ^8.2.15 - - postcss-discard-comments@5.1.2: - resolution: {integrity: sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-discard-duplicates@5.1.0: - resolution: {integrity: sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-discard-empty@5.1.1: - resolution: {integrity: sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-discard-overridden@5.1.0: - resolution: {integrity: sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-import@16.1.1: - resolution: {integrity: sha512-2xVS1NCZAfjtVdvXiyegxzJ447GyqCeEI5V7ApgQVOWnros1p5lGNovJNapwPpMombyFBfqDwt7AD3n2l0KOfQ==} - engines: {node: '>=18.0.0'} - peerDependencies: - postcss: ^8.0.0 - - postcss-load-config@3.1.4: - resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} - engines: {node: '>= 10'} - peerDependencies: - postcss: '>=8.0.9' - ts-node: '>=9.0.0' - peerDependenciesMeta: - postcss: - optional: true - ts-node: - optional: true - - postcss-load-config@6.0.1: - resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} - engines: {node: '>= 18'} - peerDependencies: - jiti: '>=1.21.0' - postcss: '>=8.0.9' - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - jiti: - optional: true - postcss: - optional: true - tsx: - optional: true - yaml: - optional: true - - postcss-merge-longhand@5.1.7: - resolution: {integrity: sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-merge-rules@5.1.4: - resolution: {integrity: sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-minify-font-values@5.1.0: - resolution: {integrity: sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-minify-gradients@5.1.1: - resolution: {integrity: sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-minify-params@5.1.4: - resolution: {integrity: sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-minify-selectors@5.2.1: - resolution: {integrity: sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-modules-extract-imports@3.1.0: - resolution: {integrity: sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==} - engines: {node: ^10 || ^12 || >= 14} - peerDependencies: - postcss: ^8.1.0 - - postcss-modules-local-by-default@4.2.0: - resolution: {integrity: sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==} - engines: {node: ^10 || ^12 || >= 14} - peerDependencies: - postcss: ^8.1.0 + postcss: ^8.1.0 postcss-modules-scope@3.2.1: resolution: {integrity: sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==} @@ -9266,83 +9404,11 @@ packages: peerDependencies: postcss: ^8.1.0 - postcss-modules@4.3.1: - resolution: {integrity: sha512-ItUhSUxBBdNamkT3KzIZwYNNRFKmkJrofvC2nWab3CPKhYBQ1f27XXh1PAPE27Psx58jeelPsxWB/+og+KEH0Q==} + postcss-modules@6.0.1: + resolution: {integrity: sha512-zyo2sAkVvuZFFy0gc2+4O+xar5dYlaVy/ebO24KT0ftk/iJevSNyPyQellsBLlnccwh7f6V6Y4GvuKRYToNgpQ==} peerDependencies: postcss: ^8.0.0 - postcss-normalize-charset@5.1.0: - resolution: {integrity: sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-normalize-display-values@5.1.0: - resolution: {integrity: sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-normalize-positions@5.1.1: - resolution: {integrity: sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-normalize-repeat-style@5.1.1: - resolution: {integrity: sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-normalize-string@5.1.0: - resolution: {integrity: sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-normalize-timing-functions@5.1.0: - resolution: {integrity: sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-normalize-unicode@5.1.1: - resolution: {integrity: sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-normalize-url@5.1.0: - resolution: {integrity: sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-normalize-whitespace@5.1.1: - resolution: {integrity: sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-ordered-values@5.1.3: - resolution: {integrity: sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-reduce-initial@5.1.2: - resolution: {integrity: sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-reduce-transforms@5.1.0: - resolution: {integrity: sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - postcss-selector-parser@6.0.10: resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} engines: {node: '>=4'} @@ -9351,23 +9417,11 @@ packages: resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} engines: {node: '>=4'} - postcss-svgo@5.1.0: - resolution: {integrity: sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - - postcss-unique-selectors@5.1.1: - resolution: {integrity: sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + postcss@8.5.8: + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} engines: {node: ^10 || ^12 || >=14} postgres-array@2.0.0: @@ -9386,13 +9440,17 @@ packages: resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} engines: {node: '>=0.10.0'} + postgres@3.4.7: + resolution: {integrity: sha512-Jtc2612XINuBjIl/QTWsV5UvE8UHuNblcO3vVADSrKsrc6RqGX6lOW1cEo3CM2v0XG4Nat8nI+YM7/f26VxXLw==} + engines: {node: '>=12'} + postject@1.0.0-alpha.6: resolution: {integrity: sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==} engines: {node: '>=14.0.0'} hasBin: true - preact@10.28.2: - resolution: {integrity: sha512-lbteaWGzGHdlIuiJ0l2Jq454m6kcpI1zNje6d8MlGAFlYvP2GO4ibnat7P74Esfz4sPTdM6UxtTwh/d3pwM9JA==} + preact@10.28.4: + resolution: {integrity: sha512-uKFfOHWuSNpRFVTnljsCluEFq57OKT+0QdOiQo8XWnQ/pSvg7OpX5eNOejELXJMWy+BwM2nobz0FkvzmnpCNsQ==} prebuild-install@7.1.3: resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} @@ -9404,16 +9462,6 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier@3.6.2: - resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} - engines: {node: '>=14'} - hasBin: true - - prettier@3.7.4: - resolution: {integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==} - engines: {node: '>=14'} - hasBin: true - prettier@3.8.1: resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} engines: {node: '>=14'} @@ -9427,6 +9475,19 @@ packages: resolution: {integrity: sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + prisma@7.4.2: + resolution: {integrity: sha512-2bP8Ruww3Q95Z2eH4Yqh4KAENRsj/SxbdknIVBfd6DmjPwmpsC4OVFMLOeHt6tM3Amh8ebjvstrUz3V/hOe1dA==} + engines: {node: ^20.19 || ^22.12 || >=24.0} + hasBin: true + peerDependencies: + better-sqlite3: '>=9.0.0' + typescript: '>=5.4.0' + peerDependenciesMeta: + better-sqlite3: + optional: true + typescript: + optional: true + proc-log@5.0.0: resolution: {integrity: sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==} engines: {node: ^18.17.0 || >=20.5.0} @@ -9438,6 +9499,10 @@ packages: process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + progress@2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} @@ -9449,10 +9514,6 @@ packages: resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} engines: {node: '>=10'} - promise.series@0.2.0: - resolution: {integrity: sha512-VWQJyU2bcDTgZw8kpfBpB/ejZASlCrzwz5f2hjb/zlujOEB4oeiAhHygAWq8ubsX2GVkD4kCU5V2dwOTaCY5EQ==} - engines: {node: '>=0.12'} - prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} @@ -9460,6 +9521,9 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + proper-lockfile@4.1.2: + resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} + property-information@7.1.0: resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} @@ -9470,8 +9534,8 @@ packages: proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - pump@3.0.3: - resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} @@ -9480,8 +9544,12 @@ packages: pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} - qs@6.14.1: - resolution: {integrity: sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==} + qs@6.14.2: + resolution: {integrity: sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==} + engines: {node: '>=0.6'} + + qs@6.15.0: + resolution: {integrity: sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==} engines: {node: '>=0.6'} queue-microtask@1.2.3: @@ -9494,9 +9562,6 @@ packages: rambda@9.4.2: resolution: {integrity: sha512-++euMfxnl7OgaEKwXh9QqThOjMeta2HH001N1v4mYQzBjJBnmXBh2BCK6dZAbICFVXOFUVD3xFG0R3ZPU0mxXw==} - randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} @@ -9512,14 +9577,14 @@ packages: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true - react-aria-components@1.14.0: - resolution: {integrity: sha512-u21N/yS6Ozk9P9oO8wxMNZSFiPk6F3aAE9w6aN7pseGPApkjXqDyPNCnTsTTvMtVL3QRBkVbf7fJ5yi2hksVEg==} + react-aria-components@1.16.0: + resolution: {integrity: sha512-MjHbTLpMFzzD2Tv5KbeXoZwPczuUWZcRavVvQQlNHRtXHH38D+sToMEYpNeir7Wh3K/XWtzeX3EujfJW6QNkrw==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - react-aria@3.45.0: - resolution: {integrity: sha512-QsdWIhhm3+IAiW3SU9tEm7pmeIcveEPAO6riZ1IUF78ZCvH/47nU4zVztcdtYmwYWSL4168QxLncWKtlMva3BA==} + react-aria@3.47.0: + resolution: {integrity: sha512-nvahimIqdByl/PXk/xPkG30LPRzcin+/Uk0uFfwbbKRRFC9aa22a6BRULZLqVHwa9GaNyKe6CDUxO1Dde4v0kA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 @@ -9533,16 +9598,15 @@ packages: resolution: {integrity: sha512-+NRMYs2DyTP4/tqWz371Oo50JqmWltR1h2gcdgUMAWZJIAvrd0/SqlCfx7tpzpl/s36rzw6qH2MjoNrxtRNYhA==} engines: {node: ^20.9.0 || >=22} - react-dom@19.2.3: - resolution: {integrity: sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==} + react-dom@19.2.4: + resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} peerDependencies: - react: ^19.2.3 + react: ^19.2.4 - react-error-boundary@6.0.2: - resolution: {integrity: sha512-yvWErn55ag/ywZEFqYpXYX9rxIDPIabXIX25F184KY3F5Szk2x/cVieOflw5R47ltN3KzWOw82Lmlb4vNjyn9A==} + react-error-boundary@6.1.1: + resolution: {integrity: sha512-BrYwPOdXi5mqkk5lw+Uvt0ThHx32rCt3BkukS4X23A2AIWDPSGX6iaWTc0y9TU/mHDA/6qOSGel+B2ERkOvD1w==} peerDependencies: react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 react-hook-form@7.70.0: resolution: {integrity: sha512-COOMajS4FI3Wuwrs3GPpi/Jeef/5W1DRR84Yl5/ShlT3dKVFUfoGiEZ/QE6Uw8P4T2/CLJdcTVYKvWBMQTEpvw==} @@ -9550,8 +9614,8 @@ packages: peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 - react-icons@5.5.0: - resolution: {integrity: sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==} + react-icons@5.6.0: + resolution: {integrity: sha512-RH93p5ki6LfOiIt0UtDyNg/cee+HLVR6cHHtW3wALfo+eOHTp8RnU2kRkI6E+H19zMIs03DyxUG/GfZMOGvmiA==} peerDependencies: react: '*' @@ -9574,39 +9638,26 @@ packages: resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} engines: {node: '>=0.10.0'} - react-resizable-panels@4.3.0: - resolution: {integrity: sha512-F8LGxzK3tq5N4m1oSvTZSDTH+QUhr5qPLuFhPyxVrOPqCFGZ1j2KOSx2K96aiKC4UI4kGR3/NKHczCumTgxVxA==} + react-resizable-panels@4.7.1: + resolution: {integrity: sha512-RYBRgvdZhnUds5jJWYr1up0hYFofgN1dqSwhxfBl9Savoxms0gyGF0AfaXskhxTYkXrlwc+TlQPe5UkoV+1neg==} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - react-scan@0.4.3: - resolution: {integrity: sha512-jhAQuQ1nja6HUYrSpbmNFHqZPsRCXk8Yqu0lHoRIw9eb8N96uTfXCpVyQhTTnJ/nWqnwuvxbpKVG/oWZT8+iTQ==} + react-scan@0.5.3: + resolution: {integrity: sha512-qde9PupmUf0L3MU1H6bjmoukZNbCXdMyTEwP4Gh8RQ4rZPd2GGNBgEKWszwLm96E8k+sGtMpc0B9P0KyFDP6Bw==} hasBin: true peerDependencies: - '@remix-run/react': '>=1.0.0' - next: '>=13.0.0' 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 - react-router: ^5.0.0 || ^6.0.0 || ^7.0.0 - react-router-dom: ^5.0.0 || ^6.0.0 || ^7.0.0 - peerDependenciesMeta: - '@remix-run/react': - optional: true - next: - optional: true - react-router: - optional: true - react-router-dom: - optional: true react-simple-animate@3.5.3: resolution: {integrity: sha512-Ob+SmB5J1tXDEZyOe2Hf950K4M8VaWBBmQ3cS2BUnTORqHjhK0iKG8fB+bo47ZL15t8d3g/Y0roiqH05UBjG7A==} peerDependencies: react-dom: ^16.8.0 || ^17 || ^18 || ^19 - react-stately@3.43.0: - resolution: {integrity: sha512-dScb9fTL1tRtFODPnk/2rP0a9kp1C+7+40RArS0C7j0auAUmnrO/wDILojwQUso7/kkys4fP707fTwGJDeJ7vg==} + react-stately@3.45.0: + resolution: {integrity: sha512-G3bYr0BIiookpt4H05VeZUuVS/FslQAj2TeT8vDfCiL314Y+LtPXIPe/a3eamCA0wljy7z1EDYKV50Qbz7pcJg==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 @@ -9615,17 +9666,14 @@ packages: peerDependencies: react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react@19.2.3: - resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} + react@19.2.4: + resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} engines: {node: '>=0.10.0'} read-binary-file-arch@1.0.6: resolution: {integrity: sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg==} hasBin: true - read-cache@1.0.0: - resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} - read-yaml-file@2.1.0: resolution: {integrity: sha512-UkRNRIwnhG+y7hpqnycCL/xbTk7+ia9VuVTC0S+zVbwd65DI9eUpRMfsWIGrCWxTU/mi+JW8cHQCrv+zfCbEPQ==} engines: {node: '>=10.13'} @@ -9637,6 +9685,13 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} + readable-stream@4.7.0: + resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + readdir-glob@1.1.3: + resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -9698,6 +9753,9 @@ packages: remark-stringify@11.0.0: resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + remeda@2.33.4: + resolution: {integrity: sha512-ygHswjlc/opg2VrtiYvUOPLjxjtdKvjGz1/plDhkG66hjNjFr1xmfrs2ClNFo/E6TyUFiwYNh53bKV26oBoMGQ==} + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -9744,8 +9802,9 @@ packages: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true - resolve@2.0.0-next.5: - resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + resolve@2.0.0-next.6: + resolution: {integrity: sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==} + engines: {node: '>= 0.4'} hasBin: true responselike@2.0.1: @@ -9779,23 +9838,14 @@ packages: resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==} engines: {node: '>=8.0'} - rollup-plugin-postcss@4.0.2: - resolution: {integrity: sha512-05EaY6zvZdmvPUDi3uCcAQoESDcYnv8ogJJQRp6V5kZ6J6P7uAVJlrTZcaaA20wTH527YTnKfkAoPxWI/jPp4w==} - engines: {node: '>=10'} - peerDependencies: - postcss: 8.x - rollup-plugin-typescript2@0.36.0: resolution: {integrity: sha512-NB2CSQDxSe9+Oe2ahZbf+B4bh7pHwjV5L+RSYpCu7Q5ROuN94F9b6ioWwKfz3ueL3KTtmX4o2MUH2cgHDIEUsw==} peerDependencies: rollup: '>=1.26.3' typescript: '>=2.4.0' - rollup-pluginutils@2.8.2: - resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} - - rollup@4.55.1: - resolution: {integrity: sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==} + rollup@4.59.0: + resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -9819,9 +9869,6 @@ packages: safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - safe-identifier@0.4.2: - resolution: {integrity: sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w==} - safe-push-apply@1.0.0: resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} engines: {node: '>= 0.4'} @@ -9836,16 +9883,13 @@ packages: sanitize-filename@1.6.3: resolution: {integrity: sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==} - sax@1.4.3: - resolution: {integrity: sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==} + sax@1.5.0: + resolution: {integrity: sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==} + engines: {node: '>=11.0.0'} scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} - schema-utils@3.3.0: - resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} - engines: {node: '>= 10.13.0'} - schema-utils@4.3.3: resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} engines: {node: '>= 10.13.0'} @@ -9874,11 +9918,6 @@ packages: engines: {node: '>=10'} hasBin: true - semver@7.7.3: - resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} - engines: {node: '>=10'} - hasBin: true - semver@7.7.4: resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} engines: {node: '>=10'} @@ -9888,21 +9927,21 @@ packages: resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} engines: {node: '>= 0.8.0'} + seq-queue@0.0.5: + resolution: {integrity: sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==} + serialize-error@7.0.1: resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==} engines: {node: '>=10'} - serialize-javascript@6.0.2: - resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} - seroval-plugins@1.3.3: resolution: {integrity: sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w==} engines: {node: '>=10'} peerDependencies: seroval: ^1.0 - seroval-plugins@1.4.2: - resolution: {integrity: sha512-X7p4MEDTi+60o2sXZ4bnDBhgsUYDSkQEvzYZuJyFqWg9jcoPsHts5nrg5O956py2wyt28lUrBxk0M0/wU8URpA==} + seroval-plugins@1.5.0: + resolution: {integrity: sha512-EAHqADIQondwRZIdeW2I636zgsODzoBDwb3PT/+7TLDWyw1Dy/Xv7iGUIEXXav7usHDE9HVhOU61irI3EnyyHA==} engines: {node: '>=10'} peerDependencies: seroval: ^1.0 @@ -9911,8 +9950,8 @@ packages: resolution: {integrity: sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==} engines: {node: '>=10'} - seroval@1.4.2: - resolution: {integrity: sha512-N3HEHRCZYn3cQbsC4B5ldj9j+tHdf4JZoYPlcI4rRYu0Xy4qN8MQf1Z08EibzB0WpgRG5BGK08FTrmM66eSzKQ==} + seroval@1.5.0: + resolution: {integrity: sha512-OE4cvmJ1uSPrKorFIH9/w/Qwuvi/IMcGbv5RKgcJ/zjA/IohDLU6SVaxFN9FwajbP7nsX0dQqMDes1whk3y+yw==} engines: {node: '>=10'} serve-static@1.16.3: @@ -9922,6 +9961,9 @@ packages: set-cookie-parser@2.7.2: resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} + set-cookie-parser@3.0.1: + resolution: {integrity: sha512-n7Z7dXZhJbwuAHhNzkTti6Aw9QDDjZtm3JTpTGATIdNzdQz5GuFs22w90BcvF4INfnrL5xrX3oGsuqO5Dx3A1Q==} + set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -10044,6 +10086,9 @@ packages: space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + sparse-bitfield@3.0.3: + resolution: {integrity: sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==} + split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} @@ -10054,22 +10099,22 @@ packages: sprintf-js@1.1.3: resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + sqlstring@2.3.3: + resolution: {integrity: sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==} + engines: {node: '>= 0.6'} + ssri@12.0.0: resolution: {integrity: sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==} engines: {node: ^18.17.0 || >=20.5.0} - ssri@13.0.0: - resolution: {integrity: sha512-yizwGBpbCn4YomB2lzhZqrHLJoqFGXihNbib3ozhqF/cIp5ue+xSmOQrjNasEE62hFxsCcg/V/z23t4n8jMEng==} + ssri@13.0.1: + resolution: {integrity: sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==} engines: {node: ^20.17.0 || >=22.9.0} stable-hash-x@0.2.0: resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} engines: {node: '>=12.0.0'} - stable@0.1.8: - resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} - deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' - stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} @@ -10096,8 +10141,8 @@ packages: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} - storybook@10.1.11: - resolution: {integrity: sha512-pKP5jXJYM4OjvNklGuHKO53wOCAwfx79KvZyOWHoi9zXUH5WVMFUe/ZfWyxXG/GTcj0maRgHGUjq/0I43r0dDQ==} + storybook@10.2.16: + resolution: {integrity: sha512-Az1Qro0XjCBttsuO55H2aIGPYqGx00T8O3o29rLQswOyZhgAVY9H2EnJiVsfmSG1Kwt8qYTVv7VxzLlqDxropA==} hasBin: true peerDependencies: prettier: ^2 || ^3 @@ -10109,6 +10154,9 @@ packages: resolution: {integrity: sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==} engines: {node: '>=8.0'} + streamx@2.23.0: + resolution: {integrity: sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==} + string-hash@1.1.3: resolution: {integrity: sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==} @@ -10160,8 +10208,8 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.2: - resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} engines: {node: '>=12'} strip-bom@3.0.0: @@ -10188,9 +10236,6 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - style-inject@0.3.0: - resolution: {integrity: sha512-IezA2qp+vcdlhJaVm5SOdPPTUu0FCEqfNSli2vRuSIBbu5Nq5UvygTk/VzeCqfLz2Atj3dVII5QBKGZRZ0edzw==} - style-mod@4.1.3: resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==} @@ -10200,12 +10245,6 @@ packages: style-to-object@1.0.14: resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} - stylehacks@5.1.1: - resolution: {integrity: sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - stylis@4.2.0: resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} @@ -10233,13 +10272,8 @@ packages: svg-parser@2.0.4: resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} - svgo@2.8.0: - resolution: {integrity: sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==} - engines: {node: '>=10.13.0'} - hasBin: true - - svgo@3.3.2: - resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==} + svgo@3.3.3: + resolution: {integrity: sha512-+wn7I4p7YgJhHs38k2TNjy1vCfPIfLIJWR5MnCStsN8WuuTcBnRKcMHQLMM2ijxGZmDoZwNv8ipl5aTTen62ng==} engines: {node: '>=14.0.0'} hasBin: true @@ -10247,8 +10281,8 @@ packages: resolution: {integrity: sha512-4+kibROq06E7Yj3kEcCRN1Ki2C/5i+5P1B7An9iS9PO1BQY5VzWFuLhV7y7xNxkZjc8FEaLCh97NGzs/XBfOMQ==} hasBin: true - synckit@0.11.11: - resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} + synckit@0.11.12: + resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==} engines: {node: ^14.18.0 || >=16.0.0} syncpack@13.0.4: @@ -10260,8 +10294,8 @@ packages: resolution: {integrity: sha512-FzD187HuFIZEyeR7Xy6sJbJll2d4SybS90satC8SKIuaNRC05CxMvdzN7BUsfDQffcnabckRM5OIcfArjsZ0mg==} engines: {node: '>=18.18'} - tailwind-merge@3.4.0: - resolution: {integrity: sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==} + tailwind-merge@3.5.0: + resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==} tailwind-variants@3.2.2: resolution: {integrity: sha512-Mi4kHeMTLvKlM98XPnK+7HoBPmf4gygdFmqQPaDivc3DpYS6aIY6KiG/PgThrGvii5YZJqRsPz0aPyhoFzmZgg==} @@ -10278,8 +10312,8 @@ packages: peerDependencies: tailwindcss: ^4.0.0 - tailwindcss@4.1.18: - resolution: {integrity: sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==} + tailwindcss@4.2.1: + resolution: {integrity: sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==} tapable@2.3.0: resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} @@ -10292,15 +10326,20 @@ packages: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} + tar-stream@3.1.8: + resolution: {integrity: sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ==} + tar@6.2.1: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'} deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me - tar@7.5.2: - resolution: {integrity: sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==} + tar@7.5.10: + resolution: {integrity: sha512-8mOPs1//5q/rlkNSPcCegA6hiHJYDmSLEI8aMH/CdSQJNWztHC9WHNam5zdQlfpTwB9Xp7IBEsHfV5LKMJGVAw==} engines: {node: '>=18'} - deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + teex@1.0.1: + resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} temp-file@3.4.0: resolution: {integrity: sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==} @@ -10315,8 +10354,8 @@ packages: temporal-spec@0.3.0: resolution: {integrity: sha512-n+noVpIqz4hYgFSMOSiINNOUOMFtV5cZQNCmmszA6GiVFVRt3G7AqVyhXjhCSmowvQn+NsGn+jMDMKJYHd3bSQ==} - terser-webpack-plugin@5.3.16: - resolution: {integrity: sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==} + terser-webpack-plugin@5.3.17: + resolution: {integrity: sha512-YR7PtUp6GMU91BgSJmlaX/rS2lGDbAF7D+Wtq7hRO+MiljNmodYvqslzCFiYVAgW+Qoaaia/QUIP4lGXufjdZw==} engines: {node: '>= 10.13.0'} peerDependencies: '@swc/core': '*' @@ -10331,11 +10370,14 @@ packages: uglify-js: optional: true - terser@5.44.1: - resolution: {integrity: sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==} + terser@5.46.0: + resolution: {integrity: sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==} engines: {node: '>=10'} hasBin: true + text-decoder@1.2.7: + resolution: {integrity: sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==} + thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -10406,6 +10448,10 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + tr46@5.1.1: + resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} + engines: {node: '>=18'} + tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true @@ -10536,11 +10582,11 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} - typescript-eslint@8.52.0: - resolution: {integrity: sha512-atlQQJ2YkO4pfTVQmQ+wvYQwexPDOIgo+RaVcD7gHgzy/IQA+XTyuxNM9M9TVXvttkF7koBHmcwisKdOAf2EcA==} + typescript-eslint@8.56.1: + resolution: {integrity: sha512-U4lM6pjmBX7J5wk4szltF7I1cGBHXZopnAXCMXb3+fZ3B/0Z3hq3wS/CCUB2NZBNAExK92mCU2tEohWuwVMsDQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' typescript@5.4.5: @@ -10553,24 +10599,24 @@ packages: engines: {node: '>=14.17'} hasBin: true - ufo@1.6.2: - resolution: {integrity: sha512-heMioaxBcG9+Znsda5Q8sQbWnLJSl98AFDXTO80wELWEzX3hordXsTdxrIfMQoO9IY1MEnoGoPjpoKpMj+Yx0Q==} + ufo@1.6.3: + resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} - undici@7.18.2: - resolution: {integrity: sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw==} + undici-types@7.18.2: + resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} + + undici@7.22.0: + resolution: {integrity: sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==} engines: {node: '>=20.18.1'} unicode-canonical-property-names-ecmascript@2.0.1: @@ -10680,8 +10726,8 @@ packages: url-join@4.0.1: resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==} - use-debounce@10.0.6: - resolution: {integrity: sha512-C5OtPyhAZgVoteO9heXMTdW7v/IbFI+8bSVKYCJrSmiWWCLsbUxiBSp4t9v0hNBTGY97bT72ydDIDyGSFWfwXg==} + use-debounce@10.1.0: + resolution: {integrity: sha512-lu87Za35V3n/MyMoEpD5zJv0k7hCn0p+V/fK2kWD+3k2u3kOCwO593UArbczg1fhfs2rqPEnHpULJ3KmGdDzvg==} engines: {node: '>= 16.0.0'} peerDependencies: react: '*' @@ -10718,6 +10764,14 @@ packages: v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + valibot@1.2.0: + resolution: {integrity: sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg==} + peerDependencies: + typescript: '>=5' + peerDependenciesMeta: + typescript: + optional: true + validate-html-nesting@1.2.4: resolution: {integrity: sha512-doQi7e8EJ2OWneSG1aZpJluS6A49aZM0+EICXWKm1i6WvqTLmq0tpUcImc4KTWG50mORO0C4YDBtOCSYvElftw==} @@ -10743,13 +10797,10 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - vite-tsconfig-paths@6.0.3: - resolution: {integrity: sha512-7bL7FPX/DSviaZGYUKowWF1AiDVWjMjxNbE8lyaVGDezkedWqfGhlnQ4BZXre0ZN5P4kAgIJfAlgFDVyjrCIyg==} + vite-tsconfig-paths@6.1.1: + resolution: {integrity: sha512-2cihq7zliibCCZ8P9cKJrQBkfgdvcFkOOc3Y02o3GWUDLgqjWsZudaoiuOwO/gzTzy17cS5F7ZPo4bsnS4DGkg==} peerDependencies: vite: '*' - peerDependenciesMeta: - vite: - optional: true vite@7.3.1: resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} @@ -10845,8 +10896,8 @@ packages: w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} - watchpack@2.5.0: - resolution: {integrity: sha512-e6vZvY6xboSwLz2GD36c16+O/2Z6fKvIf4pOXptw2rY9MVwE/TXc6RGqxD3I3x0a28lwBY7DE+76uTPSsBrrCA==} + watchpack@2.5.1: + resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} engines: {node: '>=10.13.0'} wcwidth@1.0.1: @@ -10856,22 +10907,22 @@ packages: resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} - web-streams-polyfill@4.0.0-beta.3: - resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==} - engines: {node: '>= 14'} - webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - webpack-sources@3.3.3: - resolution: {integrity: sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==} + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + + webpack-sources@3.3.4: + resolution: {integrity: sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==} engines: {node: '>=10.13.0'} webpack-virtual-modules@0.6.2: resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} - webpack@5.104.1: - resolution: {integrity: sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==} + webpack@5.105.4: + resolution: {integrity: sha512-jTywjboN9aHxFlToqb0K0Zs9SbBoW4zRUlGzI2tYNxVYcEi/IPpn+Xi4ye5jTLvX2YeLuic/IvxNot+Q1jMoOw==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -10885,6 +10936,10 @@ packages: engines: {node: '>=12'} deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation + whatwg-url@14.2.0: + resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} + engines: {node: '>=18'} + whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} @@ -10900,8 +10955,8 @@ packages: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} - which-typed-array@1.1.19: - resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + which-typed-array@1.1.20: + resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} engines: {node: '>= 0.4'} which@1.3.1: @@ -11039,6 +11094,13 @@ packages: resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} engines: {node: '>=18'} + zeptomatch@2.1.0: + resolution: {integrity: sha512-KiGErG2J0G82LSpniV0CtIzjlJ10E04j02VOudJsPyPwNZgGnRKQy7I1R7GMyg/QswnE4l7ohSGrQbQbjXPPDA==} + + zip-stream@6.0.1: + resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} + engines: {node: '>= 14'} + zod-validation-error@4.0.2: resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==} engines: {node: '>=18.0.0'} @@ -11048,9 +11110,6 @@ packages: zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} - zod@4.3.5: - resolution: {integrity: sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==} - zod@4.3.6: resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} @@ -11078,8 +11137,9 @@ snapshots: '@adobe/css-tools@4.4.4': {} - '@aikidosec/safe-chain@1.4.0': + '@aikidosec/safe-chain@1.4.4': dependencies: + archiver: 7.0.1 certifi: 14.5.15 chalk: 5.4.1 https-proxy-agent: 7.0.6 @@ -11089,42 +11149,45 @@ snapshots: npm-registry-fetch: 19.1.1 semver: 7.7.2 transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a - supports-color - '@alloy-js/babel-plugin-jsx-dom-expressions@0.39.1(@babel/core@7.28.5)': + '@alloy-js/babel-plugin-jsx-dom-expressions@0.39.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-module-imports': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) - '@babel/types': 7.28.5 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/types': 7.29.0 html-entities: 2.6.0 validate-html-nesting: 1.2.4 transitivePeerDependencies: - supports-color - '@alloy-js/babel-plugin@0.2.1(@babel/core@7.28.5)': + '@alloy-js/babel-plugin@0.2.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/generator': 7.28.5 + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 '@babel/helper-module-imports': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) - '@babel/types': 7.28.5 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color - '@alloy-js/babel-preset@0.2.1(@babel/core@7.28.5)': + '@alloy-js/babel-preset@0.2.1(@babel/core@7.29.0)': dependencies: - '@alloy-js/babel-plugin': 0.2.1(@babel/core@7.28.5) - '@alloy-js/babel-plugin-jsx-dom-expressions': 0.39.1(@babel/core@7.28.5) + '@alloy-js/babel-plugin': 0.2.1(@babel/core@7.29.0) + '@alloy-js/babel-plugin-jsx-dom-expressions': 0.39.1(@babel/core@7.29.0) transitivePeerDependencies: - '@babel/core' - supports-color '@alloy-js/cli@0.22.0': dependencies: - '@alloy-js/babel-preset': 0.2.1(@babel/core@7.28.5) - '@babel/core': 7.28.5 - '@babel/preset-typescript': 7.28.5(@babel/core@7.28.5) + '@alloy-js/babel-preset': 0.2.1(@babel/core@7.29.0) + '@babel/core': 7.29.0 + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) pathe: 2.0.3 picocolors: 1.1.1 transitivePeerDependencies: @@ -11132,7 +11195,7 @@ snapshots: '@alloy-js/core@0.21.0': dependencies: - '@vue/reactivity': 3.5.28 + '@vue/reactivity': 3.5.29 cli-table3: 0.6.5 pathe: 2.0.3 picocolors: 1.1.1 @@ -11140,11 +11203,11 @@ snapshots: '@alloy-js/core@0.22.0': dependencies: - '@vue/reactivity': 3.5.26 + '@vue/reactivity': 3.5.29 cli-table3: 0.6.5 pathe: 2.0.3 picocolors: 1.1.1 - prettier: 3.7.4 + prettier: 3.8.1 '@alloy-js/csharp@0.21.0': dependencies: @@ -11161,13 +11224,19 @@ snapshots: marked: 16.4.2 pathe: 2.0.3 + '@alloy-js/python@0.3.0': + dependencies: + '@alloy-js/core': 0.22.0 + change-case: 5.4.4 + pathe: 2.0.3 + '@alloy-js/typescript@0.22.0': dependencies: '@alloy-js/core': 0.22.0 change-case: 5.4.4 pathe: 2.0.3 - '@babel/code-frame@7.27.1': + '@babel/code-frame@7.28.6': dependencies: '@babel/helper-validator-identifier': 7.28.5 js-tokens: 4.0.0 @@ -11179,19 +11248,19 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.28.5': {} + '@babel/compat-data@7.29.0': {} - '@babel/core@7.28.5': + '@babel/core@7.29.0': dependencies: '@babel/code-frame': 7.29.0 - '@babel/generator': 7.28.5 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) - '@babel/helpers': 7.28.4 - '@babel/parser': 7.28.5 - '@babel/template': 7.27.2 - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.28.6 + '@babel/parser': 7.29.0 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 debug: 4.4.3 @@ -11201,51 +11270,51 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.28.5': + '@babel/generator@7.29.1': dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 '@babel/helper-annotate-as-pure@7.27.3': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 - '@babel/helper-compilation-targets@7.27.2': + '@babel/helper-compilation-targets@7.28.6': dependencies: - '@babel/compat-data': 7.28.5 + '@babel/compat-data': 7.29.0 '@babel/helper-validator-option': 7.27.1 browserslist: 4.28.1 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.28.5(@babel/core@7.28.5)': + '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-member-expression-to-functions': 7.28.5 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5) + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.29.0 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.28.5)': + '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 regexpu-core: 6.4.0 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.5(@babel/core@7.28.5)': + '@babel/helper-define-polyfill-provider@0.6.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 debug: 4.4.3 lodash.debounce: 4.0.8 resolve: 1.22.11 @@ -11256,55 +11325,62 @@ snapshots: '@babel/helper-member-expression-to-functions@7.28.5': dependencies: - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': + '@babel/helper-module-imports@7.28.6': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-imports': 7.27.1 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color '@babel/helper-optimise-call-expression@7.27.1': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 - '@babel/helper-plugin-utils@7.27.1': {} + '@babel/helper-plugin-utils@7.28.6': {} - '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.28.5)': + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-wrap-function': 7.28.3 - '@babel/traverse': 7.28.5 + '@babel/helper-wrap-function': 7.28.6 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.5)': + '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-member-expression-to-functions': 7.28.5 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color @@ -11314,654 +11390,654 @@ snapshots: '@babel/helper-validator-option@7.27.1': {} - '@babel/helper-wrap-function@7.28.3': + '@babel/helper-wrap-function@7.28.6': dependencies: - '@babel/template': 7.27.2 - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/helpers@7.28.4': + '@babel/helpers@7.28.6': dependencies: - '@babel/template': 7.27.2 - '@babel/types': 7.28.5 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 - '@babel/parser@7.28.5': + '@babel/parser@7.29.0': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-transform-optional-chaining': 7.28.5(@babel/core@7.28.5) + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3(@babel/core@7.28.5)': + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-decorators@7.28.0(@babel/core@7.28.5)': + '@babel/plugin-proposal-decorators@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-decorators': 7.27.1(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-decorators': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.5)': + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 - '@babel/plugin-syntax-decorators@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-syntax-decorators@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-syntax-import-assertions@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.5)': + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-async-generator-functions@7.28.0(@babel/core@7.28.5)': + '@babel/plugin-transform-async-generator-functions@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.5) - '@babel/traverse': 7.28.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-async-to-generator@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-block-scoping@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-block-scoping@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-class-properties@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-class-static-block@7.28.3(@babel/core@7.28.5)': + '@babel/plugin-transform-class-static-block@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-classes@7.28.4(@babel/core@7.28.5)': + '@babel/plugin-transform-classes@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-globals': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5) - '@babel/traverse': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-computed-properties@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/template': 7.27.2 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/template': 7.28.6 - '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-dotall-regex@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-dotall-regex@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-explicit-resource-management@7.28.0(@babel/core@7.28.5)': + '@babel/plugin-transform-explicit-resource-management@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-exponentiation-operator@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-exponentiation-operator@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.5 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-json-strings@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-json-strings@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-logical-assignment-operators@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-logical-assignment-operators@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-systemjs@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-modules-systemjs@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-numeric-separator@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-object-rest-spread@7.28.4(@babel/core@7.28.5)': + '@babel/plugin-transform-object-rest-spread@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.5) - '@babel/traverse': 7.28.5 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-optional-catch-binding@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-optional-catch-binding@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-optional-chaining@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-optional-chaining@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.28.5)': + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-private-methods@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-private-property-in-object@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-constant-elements@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-react-constant-elements@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.28.5)': + '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) - '@babel/types': 7.28.5 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-regenerator@7.28.4(@babel/core@7.28.5)': + '@babel/plugin-transform-regenerator@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-regexp-modifiers@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-runtime@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-runtime@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.5) - babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.5) - babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + babel-plugin-polyfill-corejs2: 0.4.15(@babel/core@7.29.0) + babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.29.0) + babel-plugin-polyfill-regenerator: 0.6.6(@babel/core@7.29.0) semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-spread@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-spread@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-typescript@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-property-regex@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-unicode-property-regex@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-sets-regex@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-unicode-sets-regex@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/preset-env@7.28.5(@babel/core@7.28.5)': + '@babel/preset-env@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/compat-data': 7.28.5 - '@babel/core': 7.28.5 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/compat-data': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.3(@babel/core@7.28.5) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.5) - '@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.28.5) - '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-async-generator-functions': 7.28.0(@babel/core@7.28.5) - '@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-block-scoping': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-class-static-block': 7.28.3(@babel/core@7.28.5) - '@babel/plugin-transform-classes': 7.28.4(@babel/core@7.28.5) - '@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-transform-dotall-regex': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-explicit-resource-management': 7.28.0(@babel/core@7.28.5) - '@babel/plugin-transform-exponentiation-operator': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-json-strings': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-logical-assignment-operators': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-modules-systemjs': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-object-rest-spread': 7.28.4(@babel/core@7.28.5) - '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-optional-chaining': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.5) - '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-regenerator': 7.28.4(@babel/core@7.28.5) - '@babel/plugin-transform-regexp-modifiers': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-spread': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-unicode-property-regex': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-unicode-sets-regex': 7.27.1(@babel/core@7.28.5) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.28.5) - babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.5) - babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.5) - babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.5) - core-js-compat: 3.47.0 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0) + '@babel/plugin-syntax-import-assertions': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.29.0) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-async-generator-functions': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-async-to-generator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-static-block': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-classes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-computed-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-dotall-regex': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-explicit-resource-management': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-exponentiation-operator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-json-strings': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-logical-assignment-operators': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-systemjs': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-nullish-coalescing-operator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-numeric-separator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-object-rest-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-optional-catch-binding': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-regenerator': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-regexp-modifiers': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-property-regex': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-sets-regex': 7.28.6(@babel/core@7.29.0) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.0) + babel-plugin-polyfill-corejs2: 0.4.15(@babel/core@7.29.0) + babel-plugin-polyfill-corejs3: 0.14.0(@babel/core@7.29.0) + babel-plugin-polyfill-regenerator: 0.6.6(@babel/core@7.29.0) + core-js-compat: 3.48.0 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.28.5)': + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/types': 7.28.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/types': 7.29.0 esutils: 2.0.3 - '@babel/preset-react@7.28.5(@babel/core@7.28.5)': + '@babel/preset-react@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.28.5) - '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/preset-typescript@7.28.5(@babel/core@7.28.5)': + '@babel/preset-typescript@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-typescript': 7.28.5(@babel/core@7.28.5) + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/runtime@7.28.4': {} + '@babel/runtime@7.28.6': {} - '@babel/template@7.27.2': + '@babel/template@7.28.6': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 - '@babel/traverse@7.28.5': + '@babel/traverse@7.29.0': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.5 + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.5 - '@babel/template': 7.27.2 - '@babel/types': 7.28.5 + '@babel/parser': 7.29.0 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 debug: 4.4.3 transitivePeerDependencies: - supports-color - '@babel/types@7.28.5': + '@babel/types@7.29.0': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 - '@better-auth/cli@1.4.18(@better-fetch/fetch@1.1.21)(@libsql/client@0.14.0)(better-call@1.1.8(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.10)(vitest@4.0.18(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@better-auth/cli@1.4.21(@better-fetch/fetch@1.1.21)(@electric-sql/pglite@0.3.15)(@libsql/client@0.14.0)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(mongodb@7.1.0(socks@2.8.7))(mysql2@3.15.3)(nanostores@1.1.1)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(solid-js@1.9.10)(vitest@4.0.18(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - '@babel/core': 7.28.5 - '@babel/preset-react': 7.28.5(@babel/core@7.28.5) - '@babel/preset-typescript': 7.28.5(@babel/core@7.28.5) - '@better-auth/core': 1.4.18(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) - '@better-auth/telemetry': 1.4.18(@better-auth/core@1.4.18(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0)) + '@babel/core': 7.29.0 + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) + '@better-auth/core': 1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1) + '@better-auth/telemetry': 1.4.21(@better-auth/core@1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1)) '@better-auth/utils': 0.3.0 '@clack/prompts': 0.11.0 '@mrleebo/prisma-ast': 0.13.1 - '@prisma/client': 5.22.0 - '@types/pg': 8.16.0 - better-auth: 1.4.18(@prisma/client@5.22.0)(better-sqlite3@12.6.2)(drizzle-orm@0.41.0(@libsql/client@0.14.0)(@prisma/client@5.22.0)(@types/pg@8.16.0)(better-sqlite3@12.6.2)(kysely@0.28.11)(pg@8.18.0))(pg@8.18.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.10)(vitest@4.0.18(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + '@prisma/client': 5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) + '@types/pg': 8.18.0 + better-auth: 1.4.21(@prisma/client@5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(better-sqlite3@12.6.2)(drizzle-orm@0.41.0(@electric-sql/pglite@0.3.15)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.18.0)(better-sqlite3@12.6.2)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(mongodb@7.1.0(socks@2.8.7))(mysql2@3.15.3)(pg@8.20.0)(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(solid-js@1.9.10)(vitest@4.0.18(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) better-sqlite3: 12.6.2 c12: 3.3.3 chalk: 5.6.2 commander: 12.1.0 dotenv: 17.3.1 - drizzle-orm: 0.41.0(@libsql/client@0.14.0)(@prisma/client@5.22.0)(@types/pg@8.16.0)(better-sqlite3@12.6.2)(kysely@0.28.11)(pg@8.18.0) + drizzle-orm: 0.41.0(@electric-sql/pglite@0.3.15)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.18.0)(better-sqlite3@12.6.2)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) open: 10.2.0 - pg: 8.18.0 + pg: 8.20.0 prettier: 3.8.1 prompts: 2.4.2 semver: 7.7.4 @@ -12013,89 +12089,149 @@ snapshots: - vitest - vue - '@better-auth/core@1.4.18(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0)': + '@better-auth/core@1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1)': dependencies: '@better-auth/utils': 0.3.0 '@better-fetch/fetch': 1.1.21 '@standard-schema/spec': 1.1.0 better-call: 1.1.8(zod@4.3.6) - jose: 6.1.3 + jose: 6.2.0 + kysely: 0.28.11 + nanostores: 1.1.1 + zod: 4.3.6 + + '@better-auth/core@1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1)': + dependencies: + '@better-auth/utils': 0.3.0 + '@better-fetch/fetch': 1.1.21 + '@standard-schema/spec': 1.1.0 + better-call: 1.3.2(zod@4.3.6) + jose: 6.2.0 + kysely: 0.28.11 + nanostores: 1.1.1 + zod: 4.3.6 + + '@better-auth/core@1.5.4(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1)': + dependencies: + '@better-auth/utils': 0.3.1 + '@better-fetch/fetch': 1.1.21 + '@standard-schema/spec': 1.1.0 + better-call: 1.3.2(zod@4.3.6) + jose: 6.2.0 kysely: 0.28.11 - nanostores: 1.1.0 + nanostores: 1.1.1 zod: 4.3.6 - '@better-auth/telemetry@1.4.18(@better-auth/core@1.4.18(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))': + '@better-auth/drizzle-adapter@1.5.4(@better-auth/core@1.5.4(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1))(@better-auth/utils@0.3.1)(drizzle-orm@0.41.0(@electric-sql/pglite@0.3.15)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.18.0)(better-sqlite3@12.6.2)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))': + dependencies: + '@better-auth/core': 1.5.4(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1) + '@better-auth/utils': 0.3.1 + drizzle-orm: 0.41.0(@electric-sql/pglite@0.3.15)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.18.0)(better-sqlite3@12.6.2)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) + + '@better-auth/kysely-adapter@1.5.4(@better-auth/core@1.5.4(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1))(@better-auth/utils@0.3.1)(kysely@0.28.11)': + dependencies: + '@better-auth/core': 1.5.4(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1) + '@better-auth/utils': 0.3.1 + kysely: 0.28.11 + + '@better-auth/memory-adapter@1.5.4(@better-auth/core@1.5.4(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1))(@better-auth/utils@0.3.1)': + dependencies: + '@better-auth/core': 1.5.4(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1) + '@better-auth/utils': 0.3.1 + + '@better-auth/mongo-adapter@1.5.4(@better-auth/core@1.5.4(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1))(@better-auth/utils@0.3.1)(mongodb@7.1.0(socks@2.8.7))': + dependencies: + '@better-auth/core': 1.5.4(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1) + '@better-auth/utils': 0.3.1 + mongodb: 7.1.0(socks@2.8.7) + + '@better-auth/prisma-adapter@1.5.4(@better-auth/core@1.5.4(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1))(@better-auth/utils@0.3.1)(@prisma/client@5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))': dependencies: - '@better-auth/core': 1.4.18(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) + '@better-auth/core': 1.5.4(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1) + '@better-auth/utils': 0.3.1 + '@prisma/client': 5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) + prisma: 7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + + '@better-auth/telemetry@1.4.21(@better-auth/core@1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1))': + dependencies: + '@better-auth/core': 1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1) '@better-auth/utils': 0.3.0 '@better-fetch/fetch': 1.1.21 + '@better-auth/telemetry@1.5.4(@better-auth/core@1.5.4(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1))': + dependencies: + '@better-auth/core': 1.5.4(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1) + '@better-auth/utils': 0.3.1 + '@better-fetch/fetch': 1.1.21 + '@better-auth/utils@0.3.0': {} + '@better-auth/utils@0.3.1': {} + '@better-fetch/fetch@1.1.21': {} - '@bufbuild/buf-darwin-arm64@1.63.0': + '@bufbuild/buf-darwin-arm64@1.66.0': optional: true - '@bufbuild/buf-darwin-x64@1.63.0': + '@bufbuild/buf-darwin-x64@1.66.0': optional: true - '@bufbuild/buf-linux-aarch64@1.63.0': + '@bufbuild/buf-linux-aarch64@1.66.0': optional: true - '@bufbuild/buf-linux-armv7@1.63.0': + '@bufbuild/buf-linux-armv7@1.66.0': optional: true - '@bufbuild/buf-linux-x64@1.63.0': + '@bufbuild/buf-linux-x64@1.66.0': optional: true - '@bufbuild/buf-win32-arm64@1.63.0': + '@bufbuild/buf-win32-arm64@1.66.0': optional: true - '@bufbuild/buf-win32-x64@1.63.0': + '@bufbuild/buf-win32-x64@1.66.0': optional: true - '@bufbuild/buf@1.63.0': + '@bufbuild/buf@1.66.0': optionalDependencies: - '@bufbuild/buf-darwin-arm64': 1.63.0 - '@bufbuild/buf-darwin-x64': 1.63.0 - '@bufbuild/buf-linux-aarch64': 1.63.0 - '@bufbuild/buf-linux-armv7': 1.63.0 - '@bufbuild/buf-linux-x64': 1.63.0 - '@bufbuild/buf-win32-arm64': 1.63.0 - '@bufbuild/buf-win32-x64': 1.63.0 + '@bufbuild/buf-darwin-arm64': 1.66.0 + '@bufbuild/buf-darwin-x64': 1.66.0 + '@bufbuild/buf-linux-aarch64': 1.66.0 + '@bufbuild/buf-linux-armv7': 1.66.0 + '@bufbuild/buf-linux-x64': 1.66.0 + '@bufbuild/buf-win32-arm64': 1.66.0 + '@bufbuild/buf-win32-x64': 1.66.0 - '@bufbuild/cel-spec@0.3.0(@bufbuild/protobuf@2.10.2)': + '@bufbuild/cel-spec@0.4.0(@bufbuild/protobuf@2.11.0)': dependencies: - '@bufbuild/protobuf': 2.10.2 + '@bufbuild/protobuf': 2.11.0 - '@bufbuild/cel@0.3.0(@bufbuild/protobuf@2.10.2)': + '@bufbuild/cel@0.4.0(@bufbuild/protobuf@2.11.0)': dependencies: - '@bufbuild/cel-spec': 0.3.0(@bufbuild/protobuf@2.10.2) - '@bufbuild/protobuf': 2.10.2 + '@bufbuild/cel-spec': 0.4.0(@bufbuild/protobuf@2.11.0) + '@bufbuild/protobuf': 2.11.0 - '@bufbuild/protobuf@2.10.2': {} + '@bufbuild/protobuf@2.11.0': {} - '@bufbuild/protoc-gen-es@2.10.2(@bufbuild/protobuf@2.10.2)': + '@bufbuild/protoc-gen-es@2.11.0(@bufbuild/protobuf@2.11.0)': dependencies: - '@bufbuild/protoplugin': 2.10.2 + '@bufbuild/protoplugin': 2.11.0 optionalDependencies: - '@bufbuild/protobuf': 2.10.2 + '@bufbuild/protobuf': 2.11.0 transitivePeerDependencies: - supports-color - '@bufbuild/protoplugin@2.10.2': + '@bufbuild/protoplugin@2.11.0': dependencies: - '@bufbuild/protobuf': 2.10.2 - '@typescript/vfs': 1.6.2(typescript@5.4.5) + '@bufbuild/protobuf': 2.11.0 + '@typescript/vfs': 1.6.4(typescript@5.4.5) typescript: 5.4.5 transitivePeerDependencies: - supports-color - '@bufbuild/protovalidate@1.1.0(@bufbuild/protobuf@2.10.2)': + '@bufbuild/protovalidate@1.1.1(@bufbuild/protobuf@2.11.0)': dependencies: - '@bufbuild/cel': 0.3.0(@bufbuild/protobuf@2.10.2) - '@bufbuild/protobuf': 2.10.2 + '@bufbuild/cel': 0.4.0(@bufbuild/protobuf@2.11.0) + '@bufbuild/protobuf': 2.11.0 '@chevrotain/cst-dts-gen@10.5.0': dependencies: @@ -12112,11 +12248,6 @@ snapshots: '@chevrotain/utils@10.5.0': {} - '@clack/core@0.3.5': - dependencies: - picocolors: 1.1.1 - sisteransi: 1.0.5 - '@clack/core@0.5.0': dependencies: picocolors: 1.1.1 @@ -12128,12 +12259,6 @@ snapshots: picocolors: 1.1.1 sisteransi: 1.0.5 - '@clack/prompts@0.8.2': - dependencies: - '@clack/core': 0.3.5 - picocolors: 1.1.1 - sisteransi: 1.0.5 - '@codemirror/autocomplete@6.20.0': dependencies: '@codemirror/language': 6.12.1 @@ -12153,29 +12278,29 @@ snapshots: '@codemirror/autocomplete': 6.20.0 '@codemirror/language': 6.12.1 '@codemirror/state': 6.5.3 - '@lezer/common': 1.5.0 - '@lezer/css': 1.3.0 + '@lezer/common': 1.5.1 + '@lezer/css': 1.3.1 '@codemirror/lang-html@6.4.11': dependencies: '@codemirror/autocomplete': 6.20.0 '@codemirror/lang-css': 6.3.1 - '@codemirror/lang-javascript': 6.2.4 + '@codemirror/lang-javascript': 6.2.5 '@codemirror/language': 6.12.1 '@codemirror/state': 6.5.3 '@codemirror/view': 6.39.9 - '@lezer/common': 1.5.0 - '@lezer/css': 1.3.0 + '@lezer/common': 1.5.1 + '@lezer/css': 1.3.1 '@lezer/html': 1.3.13 - '@codemirror/lang-javascript@6.2.4': + '@codemirror/lang-javascript@6.2.5': dependencies: '@codemirror/autocomplete': 6.20.0 '@codemirror/language': 6.12.1 - '@codemirror/lint': 6.9.2 + '@codemirror/lint': 6.9.5 '@codemirror/state': 6.5.3 '@codemirror/view': 6.39.9 - '@lezer/common': 1.5.0 + '@lezer/common': 1.5.1 '@lezer/javascript': 1.5.4 '@codemirror/lang-json@6.0.2': @@ -12189,7 +12314,7 @@ snapshots: '@codemirror/language': 6.12.1 '@codemirror/state': 6.5.3 '@codemirror/view': 6.39.9 - '@lezer/common': 1.5.0 + '@lezer/common': 1.5.1 '@lezer/xml': 1.0.6 '@codemirror/language@6.12.1': @@ -12198,10 +12323,10 @@ snapshots: '@codemirror/view': 6.39.9 '@lezer/common': 1.5.1 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.7 + '@lezer/lr': 1.4.8 style-mod: 4.1.3 - '@codemirror/lint@6.9.2': + '@codemirror/lint@6.9.5': dependencies: '@codemirror/state': 6.5.3 '@codemirror/view': 6.39.9 @@ -12234,36 +12359,36 @@ snapshots: '@colors/colors@1.5.0': optional: true - '@connectrpc/connect-node@2.1.1(@bufbuild/protobuf@2.10.2)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.10.2))': + '@connectrpc/connect-node@2.1.1(@bufbuild/protobuf@2.11.0)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.11.0))': dependencies: - '@bufbuild/protobuf': 2.10.2 - '@connectrpc/connect': 2.1.1(@bufbuild/protobuf@2.10.2) + '@bufbuild/protobuf': 2.11.0 + '@connectrpc/connect': 2.1.1(@bufbuild/protobuf@2.11.0) - '@connectrpc/connect-query-core@2.2.0(@bufbuild/protobuf@2.10.2)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.10.2))(@tanstack/query-core@5.90.16)': + '@connectrpc/connect-query-core@2.2.0(@bufbuild/protobuf@2.11.0)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.11.0))(@tanstack/query-core@5.90.20)': dependencies: - '@bufbuild/protobuf': 2.10.2 - '@connectrpc/connect': 2.1.1(@bufbuild/protobuf@2.10.2) - '@tanstack/query-core': 5.90.16 + '@bufbuild/protobuf': 2.11.0 + '@connectrpc/connect': 2.1.1(@bufbuild/protobuf@2.11.0) + '@tanstack/query-core': 5.90.20 - '@connectrpc/connect-query@2.2.0(@bufbuild/protobuf@2.10.2)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.10.2))(@tanstack/query-core@5.90.16)(@tanstack/react-query@5.90.16(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@connectrpc/connect-query@2.2.0(@bufbuild/protobuf@2.11.0)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.11.0))(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@bufbuild/protobuf': 2.10.2 - '@connectrpc/connect': 2.1.1(@bufbuild/protobuf@2.10.2) - '@connectrpc/connect-query-core': 2.2.0(@bufbuild/protobuf@2.10.2)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.10.2))(@tanstack/query-core@5.90.16) - '@tanstack/react-query': 5.90.16(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@bufbuild/protobuf': 2.11.0 + '@connectrpc/connect': 2.1.1(@bufbuild/protobuf@2.11.0) + '@connectrpc/connect-query-core': 2.2.0(@bufbuild/protobuf@2.11.0)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.11.0))(@tanstack/query-core@5.90.20) + '@tanstack/react-query': 5.90.21(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) transitivePeerDependencies: - '@tanstack/query-core' - '@connectrpc/connect-web@2.1.1(@bufbuild/protobuf@2.10.2)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.10.2))': + '@connectrpc/connect-web@2.1.1(@bufbuild/protobuf@2.11.0)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.11.0))': dependencies: - '@bufbuild/protobuf': 2.10.2 - '@connectrpc/connect': 2.1.1(@bufbuild/protobuf@2.10.2) + '@bufbuild/protobuf': 2.11.0 + '@connectrpc/connect': 2.1.1(@bufbuild/protobuf@2.11.0) - '@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.10.2)': + '@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.11.0)': dependencies: - '@bufbuild/protobuf': 2.10.2 + '@bufbuild/protobuf': 2.11.0 '@cspotcode/source-map-support@0.8.1': dependencies: @@ -12271,134 +12396,144 @@ snapshots: '@develar/schema-utils@2.6.5': dependencies: - ajv: 6.12.6 - ajv-keywords: 3.5.2(ajv@6.12.6) + ajv: 6.14.0 + ajv-keywords: 3.5.2(ajv@6.14.0) - '@effect-atom/atom-react@0.4.4(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14)(react@19.2.3)(scheduler@0.27.0)': + '@effect-atom/atom-react@0.5.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19)(react@19.2.4)(scheduler@0.27.0)': dependencies: - '@effect-atom/atom': 0.4.11(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14) - effect: 3.19.14 - react: 19.2.3 + '@effect-atom/atom': 0.5.3(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19) + effect: 3.19.19 + react: 19.2.4 scheduler: 0.27.0 transitivePeerDependencies: - '@effect/experimental' - '@effect/platform' - '@effect/rpc' - '@effect-atom/atom@0.4.11(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14)': + '@effect-atom/atom@0.5.3(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19)': dependencies: - '@effect/experimental': 0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14) - '@effect/platform': 0.94.1(effect@3.19.14) - '@effect/rpc': 0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14) - effect: 3.19.14 + '@effect/experimental': 0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19) + '@effect/platform': 0.94.5(effect@3.19.19) + '@effect/rpc': 0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19) + effect: 3.19.19 - '@effect/cli@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(@effect/printer-ansi@0.47.0(@effect/typeclass@0.38.0(effect@3.19.14))(effect@3.19.14))(@effect/printer@0.47.0(@effect/typeclass@0.38.0(effect@3.19.14))(effect@3.19.14))(effect@3.19.14)': + '@effect/cli@0.73.2(@effect/platform@0.94.5(effect@3.19.19))(@effect/printer-ansi@0.47.0(@effect/typeclass@0.38.0(effect@3.19.19))(effect@3.19.19))(@effect/printer@0.47.0(@effect/typeclass@0.38.0(effect@3.19.19))(effect@3.19.19))(effect@3.19.19)': dependencies: - '@effect/platform': 0.94.1(effect@3.19.14) - '@effect/printer': 0.47.0(@effect/typeclass@0.38.0(effect@3.19.14))(effect@3.19.14) - '@effect/printer-ansi': 0.47.0(@effect/typeclass@0.38.0(effect@3.19.14))(effect@3.19.14) - effect: 3.19.14 + '@effect/platform': 0.94.5(effect@3.19.19) + '@effect/printer': 0.47.0(@effect/typeclass@0.38.0(effect@3.19.19))(effect@3.19.19) + '@effect/printer-ansi': 0.47.0(@effect/typeclass@0.38.0(effect@3.19.19))(effect@3.19.19) + effect: 3.19.19 ini: 4.1.3 toml: 3.0.0 yaml: 2.8.2 - '@effect/cluster@0.56.1(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14))(effect@3.19.14)': + '@effect/cluster@0.56.1(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19))(effect@3.19.19)': dependencies: - '@effect/platform': 0.94.1(effect@3.19.14) - '@effect/rpc': 0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14) - '@effect/sql': 0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14) - '@effect/workflow': 0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14) - effect: 3.19.14 + '@effect/platform': 0.94.5(effect@3.19.19) + '@effect/rpc': 0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19) + '@effect/sql': 0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19) + '@effect/workflow': 0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19) + effect: 3.19.19 kubernetes-types: 1.30.0 - '@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14)': + '@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19)': dependencies: - '@effect/platform': 0.94.1(effect@3.19.14) - effect: 3.19.14 + '@effect/platform': 0.94.5(effect@3.19.19) + effect: 3.19.19 uuid: 11.1.0 - '@effect/platform-browser@0.74.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14)': + '@effect/platform-browser@0.74.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19)': dependencies: - '@effect/platform': 0.94.1(effect@3.19.14) - effect: 3.19.14 + '@effect/platform': 0.94.5(effect@3.19.19) + effect: 3.19.19 multipasta: 0.2.7 - '@effect/platform-node-shared@0.57.0(patch_hash=0f57ae91978b8a7454da3f1d774942d9b9a6292e28f875c6b487454e91676fbf)(@effect/cluster@0.56.1(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14)': + '@effect/platform-node-shared@0.57.1(patch_hash=0f57ae91978b8a7454da3f1d774942d9b9a6292e28f875c6b487454e91676fbf)(@effect/cluster@0.56.1(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19)': dependencies: - '@effect/cluster': 0.56.1(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14))(effect@3.19.14) - '@effect/platform': 0.94.1(effect@3.19.14) - '@effect/rpc': 0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14) - '@effect/sql': 0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14) - '@parcel/watcher': 2.5.1 - effect: 3.19.14 + '@effect/cluster': 0.56.1(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19))(effect@3.19.19) + '@effect/platform': 0.94.5(effect@3.19.19) + '@effect/rpc': 0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19) + '@effect/sql': 0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19) + '@parcel/watcher': 2.5.6 + effect: 3.19.19 multipasta: 0.2.7 ws: 8.19.0 transitivePeerDependencies: - bufferutil - utf-8-validate - '@effect/platform-node@0.104.0(@effect/cluster@0.56.1(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14)': + '@effect/platform-node@0.104.1(@effect/cluster@0.56.1(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19)': dependencies: - '@effect/cluster': 0.56.1(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14))(effect@3.19.14) - '@effect/platform': 0.94.1(effect@3.19.14) - '@effect/platform-node-shared': 0.57.0(patch_hash=0f57ae91978b8a7454da3f1d774942d9b9a6292e28f875c6b487454e91676fbf)(@effect/cluster@0.56.1(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14) - '@effect/rpc': 0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14) - '@effect/sql': 0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14) - effect: 3.19.14 + '@effect/cluster': 0.56.1(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19))(effect@3.19.19) + '@effect/platform': 0.94.5(effect@3.19.19) + '@effect/platform-node-shared': 0.57.1(patch_hash=0f57ae91978b8a7454da3f1d774942d9b9a6292e28f875c6b487454e91676fbf)(@effect/cluster@0.56.1(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19) + '@effect/rpc': 0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19) + '@effect/sql': 0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19) + effect: 3.19.19 mime: 3.0.0 - undici: 7.18.2 + undici: 7.22.0 ws: 8.19.0 transitivePeerDependencies: - bufferutil - utf-8-validate - '@effect/platform@0.94.1(effect@3.19.14)': + '@effect/platform@0.94.5(effect@3.19.19)': dependencies: - effect: 3.19.14 + effect: 3.19.19 find-my-way-ts: 0.1.6 msgpackr: 1.11.8 multipasta: 0.2.7 - '@effect/printer-ansi@0.47.0(@effect/typeclass@0.38.0(effect@3.19.14))(effect@3.19.14)': + '@effect/printer-ansi@0.47.0(@effect/typeclass@0.38.0(effect@3.19.19))(effect@3.19.19)': dependencies: - '@effect/printer': 0.47.0(@effect/typeclass@0.38.0(effect@3.19.14))(effect@3.19.14) - '@effect/typeclass': 0.38.0(effect@3.19.14) - effect: 3.19.14 + '@effect/printer': 0.47.0(@effect/typeclass@0.38.0(effect@3.19.19))(effect@3.19.19) + '@effect/typeclass': 0.38.0(effect@3.19.19) + effect: 3.19.19 - '@effect/printer@0.47.0(@effect/typeclass@0.38.0(effect@3.19.14))(effect@3.19.14)': + '@effect/printer@0.47.0(@effect/typeclass@0.38.0(effect@3.19.19))(effect@3.19.19)': dependencies: - '@effect/typeclass': 0.38.0(effect@3.19.14) - effect: 3.19.14 + '@effect/typeclass': 0.38.0(effect@3.19.19) + effect: 3.19.19 - '@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14)': + '@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19)': dependencies: - '@effect/platform': 0.94.1(effect@3.19.14) - effect: 3.19.14 + '@effect/platform': 0.94.5(effect@3.19.19) + effect: 3.19.19 msgpackr: 1.11.8 - '@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14)': + '@effect/sql@0.49.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19)': dependencies: - '@effect/experimental': 0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14) - '@effect/platform': 0.94.1(effect@3.19.14) - effect: 3.19.14 + '@effect/experimental': 0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19) + '@effect/platform': 0.94.5(effect@3.19.19) + effect: 3.19.19 uuid: 11.1.0 - '@effect/typeclass@0.38.0(effect@3.19.14)': + '@effect/typeclass@0.38.0(effect@3.19.19)': + dependencies: + effect: 3.19.19 + + '@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(@effect/platform@0.94.5(effect@3.19.19))(@effect/rpc@0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19))(effect@3.19.19)': dependencies: - effect: 3.19.14 + '@effect/experimental': 0.57.11(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19) + '@effect/platform': 0.94.5(effect@3.19.19) + '@effect/rpc': 0.73.0(@effect/platform@0.94.5(effect@3.19.19))(effect@3.19.19) + effect: 3.19.19 - '@effect/workflow@0.16.0(@effect/experimental@0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(@effect/platform@0.94.1(effect@3.19.14))(@effect/rpc@0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14))(effect@3.19.14)': + '@electric-sql/pglite-socket@0.0.20(@electric-sql/pglite@0.3.15)': dependencies: - '@effect/experimental': 0.57.11(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14) - '@effect/platform': 0.94.1(effect@3.19.14) - '@effect/rpc': 0.73.0(@effect/platform@0.94.1(effect@3.19.14))(effect@3.19.14) - effect: 3.19.14 + '@electric-sql/pglite': 0.3.15 + + '@electric-sql/pglite-tools@0.2.20(@electric-sql/pglite@0.3.15)': + dependencies: + '@electric-sql/pglite': 0.3.15 + + '@electric-sql/pglite@0.3.15': {} '@electron/asar@3.4.1': dependencies: commander: 5.1.0 glob: 7.2.3 - minimatch: 3.1.2 + minimatch: 3.1.5 '@electron/fuses@1.8.0': dependencies: @@ -12420,6 +12555,20 @@ snapshots: transitivePeerDependencies: - supports-color + '@electron/get@3.1.0': + dependencies: + debug: 4.4.3 + env-paths: 2.2.1 + fs-extra: 8.1.0 + got: 11.8.6 + progress: 2.0.3 + semver: 6.3.1 + sumchecker: 3.0.1 + optionalDependencies: + global-agent: 3.0.0 + transitivePeerDependencies: + - supports-color + '@electron/notarize@2.5.0': dependencies: debug: 4.4.3 @@ -12447,25 +12596,43 @@ snapshots: detect-libc: 2.1.2 got: 11.8.6 graceful-fs: 4.2.11 - node-abi: 4.24.0 + node-abi: 4.26.0 node-api-version: 0.2.1 node-gyp: 11.5.0 ora: 5.4.1 read-binary-file-arch: 1.0.6 - semver: 7.7.3 + semver: 7.7.4 tar: 6.2.1 yargs: 17.7.2 transitivePeerDependencies: - supports-color - '@electron/universal@2.0.3': + '@electron/rebuild@4.0.3': dependencies: - '@electron/asar': 3.4.1 '@malept/cross-spawn-promise': 2.0.0 debug: 4.4.3 - dir-compare: 4.2.0 - fs-extra: 11.3.3 - minimatch: 9.0.5 + detect-libc: 2.1.2 + got: 11.8.6 + graceful-fs: 4.2.11 + node-abi: 4.26.0 + node-api-version: 0.2.1 + node-gyp: 11.5.0 + ora: 5.4.1 + read-binary-file-arch: 1.0.6 + semver: 7.7.4 + tar: 7.5.10 + yargs: 17.7.2 + transitivePeerDependencies: + - supports-color + + '@electron/universal@2.0.3': + dependencies: + '@electron/asar': 3.4.1 + '@malept/cross-spawn-promise': 2.0.0 + debug: 4.4.3 + dir-compare: 4.2.0 + fs-extra: 11.3.4 + minimatch: 9.0.9 plist: 3.1.0 transitivePeerDependencies: - supports-color @@ -12474,7 +12641,7 @@ snapshots: dependencies: cross-dirname: 0.1.0 debug: 4.4.3 - fs-extra: 11.3.3 + fs-extra: 11.3.4 minimist: 1.2.8 postject: 1.0.0-alpha.6 transitivePeerDependencies: @@ -12496,8 +12663,8 @@ snapshots: '@emotion/babel-plugin@11.13.5': dependencies: - '@babel/helper-module-imports': 7.27.1 - '@babel/runtime': 7.28.4 + '@babel/helper-module-imports': 7.28.6 + '@babel/runtime': 7.28.6 '@emotion/hash': 0.9.2 '@emotion/memoize': 0.9.0 '@emotion/serialize': 1.3.3 @@ -12526,19 +12693,19 @@ snapshots: '@emotion/memoize@0.9.0': {} - '@emotion/react@11.14.0(@types/react@19.2.7)(react@19.2.3)': + '@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.4)': dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 '@emotion/babel-plugin': 11.13.5 '@emotion/cache': 11.14.0 '@emotion/serialize': 1.3.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.3) + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.4) '@emotion/utils': 1.4.2 '@emotion/weak-memoize': 0.4.0 hoist-non-react-statics: 3.3.2 - react: 19.2.3 + react: 19.2.4 optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.14 transitivePeerDependencies: - supports-color @@ -12552,26 +12719,26 @@ snapshots: '@emotion/sheet@1.4.0': {} - '@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.7)(react@19.2.3))(@types/react@19.2.7)(react@19.2.3)': + '@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(react@19.2.4)': dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 '@emotion/babel-plugin': 11.13.5 '@emotion/is-prop-valid': 1.4.0 - '@emotion/react': 11.14.0(@types/react@19.2.7)(react@19.2.3) + '@emotion/react': 11.14.0(@types/react@19.2.14)(react@19.2.4) '@emotion/serialize': 1.3.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.3) + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.4) '@emotion/utils': 1.4.2 - react: 19.2.3 + react: 19.2.4 optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.14 transitivePeerDependencies: - supports-color '@emotion/unitless@0.10.0': {} - '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.2.3)': + '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.2.4)': dependencies: - react: 19.2.3 + react: 19.2.4 '@emotion/utils@1.4.2': {} @@ -12580,157 +12747,157 @@ snapshots: '@esbuild/aix-ppc64@0.25.12': optional: true - '@esbuild/aix-ppc64@0.27.2': + '@esbuild/aix-ppc64@0.27.3': optional: true '@esbuild/android-arm64@0.25.12': optional: true - '@esbuild/android-arm64@0.27.2': + '@esbuild/android-arm64@0.27.3': optional: true '@esbuild/android-arm@0.25.12': optional: true - '@esbuild/android-arm@0.27.2': + '@esbuild/android-arm@0.27.3': optional: true '@esbuild/android-x64@0.25.12': optional: true - '@esbuild/android-x64@0.27.2': + '@esbuild/android-x64@0.27.3': optional: true '@esbuild/darwin-arm64@0.25.12': optional: true - '@esbuild/darwin-arm64@0.27.2': + '@esbuild/darwin-arm64@0.27.3': optional: true '@esbuild/darwin-x64@0.25.12': optional: true - '@esbuild/darwin-x64@0.27.2': + '@esbuild/darwin-x64@0.27.3': optional: true '@esbuild/freebsd-arm64@0.25.12': optional: true - '@esbuild/freebsd-arm64@0.27.2': + '@esbuild/freebsd-arm64@0.27.3': optional: true '@esbuild/freebsd-x64@0.25.12': optional: true - '@esbuild/freebsd-x64@0.27.2': + '@esbuild/freebsd-x64@0.27.3': optional: true '@esbuild/linux-arm64@0.25.12': optional: true - '@esbuild/linux-arm64@0.27.2': + '@esbuild/linux-arm64@0.27.3': optional: true '@esbuild/linux-arm@0.25.12': optional: true - '@esbuild/linux-arm@0.27.2': + '@esbuild/linux-arm@0.27.3': optional: true '@esbuild/linux-ia32@0.25.12': optional: true - '@esbuild/linux-ia32@0.27.2': + '@esbuild/linux-ia32@0.27.3': optional: true '@esbuild/linux-loong64@0.25.12': optional: true - '@esbuild/linux-loong64@0.27.2': + '@esbuild/linux-loong64@0.27.3': optional: true '@esbuild/linux-mips64el@0.25.12': optional: true - '@esbuild/linux-mips64el@0.27.2': + '@esbuild/linux-mips64el@0.27.3': optional: true '@esbuild/linux-ppc64@0.25.12': optional: true - '@esbuild/linux-ppc64@0.27.2': + '@esbuild/linux-ppc64@0.27.3': optional: true '@esbuild/linux-riscv64@0.25.12': optional: true - '@esbuild/linux-riscv64@0.27.2': + '@esbuild/linux-riscv64@0.27.3': optional: true '@esbuild/linux-s390x@0.25.12': optional: true - '@esbuild/linux-s390x@0.27.2': + '@esbuild/linux-s390x@0.27.3': optional: true '@esbuild/linux-x64@0.25.12': optional: true - '@esbuild/linux-x64@0.27.2': + '@esbuild/linux-x64@0.27.3': optional: true '@esbuild/netbsd-arm64@0.25.12': optional: true - '@esbuild/netbsd-arm64@0.27.2': + '@esbuild/netbsd-arm64@0.27.3': optional: true '@esbuild/netbsd-x64@0.25.12': optional: true - '@esbuild/netbsd-x64@0.27.2': + '@esbuild/netbsd-x64@0.27.3': optional: true '@esbuild/openbsd-arm64@0.25.12': optional: true - '@esbuild/openbsd-arm64@0.27.2': + '@esbuild/openbsd-arm64@0.27.3': optional: true '@esbuild/openbsd-x64@0.25.12': optional: true - '@esbuild/openbsd-x64@0.27.2': + '@esbuild/openbsd-x64@0.27.3': optional: true '@esbuild/openharmony-arm64@0.25.12': optional: true - '@esbuild/openharmony-arm64@0.27.2': + '@esbuild/openharmony-arm64@0.27.3': optional: true '@esbuild/sunos-x64@0.25.12': optional: true - '@esbuild/sunos-x64@0.27.2': + '@esbuild/sunos-x64@0.27.3': optional: true '@esbuild/win32-arm64@0.25.12': optional: true - '@esbuild/win32-arm64@0.27.2': + '@esbuild/win32-arm64@0.27.3': optional: true '@esbuild/win32-ia32@0.25.12': optional: true - '@esbuild/win32-ia32@0.27.2': + '@esbuild/win32-ia32@0.27.3': optional: true '@esbuild/win32-x64@0.25.12': optional: true - '@esbuild/win32-x64@0.27.2': + '@esbuild/win32-x64@0.27.3': optional: true '@eslint-community/eslint-utils@4.9.1(eslint@9.39.2(jiti@2.6.1))': @@ -12740,9 +12907,9 @@ snapshots: '@eslint-community/regexpp@4.12.2': {} - '@eslint/compat@2.0.0(eslint@9.39.2(jiti@2.6.1))': + '@eslint/compat@2.0.2(eslint@9.39.2(jiti@2.6.1))': dependencies: - '@eslint/core': 1.0.0 + '@eslint/core': 1.1.0 optionalDependencies: eslint: 9.39.2(jiti@2.6.1) @@ -12750,7 +12917,7 @@ snapshots: dependencies: '@eslint/object-schema': 2.1.7 debug: 4.4.3 - minimatch: 3.1.2 + minimatch: 3.1.5 transitivePeerDependencies: - supports-color @@ -12762,25 +12929,25 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/core@1.0.0': + '@eslint/core@1.1.0': dependencies: '@types/json-schema': 7.0.15 - '@eslint/css-tree@3.6.8': + '@eslint/css-tree@3.6.9': dependencies: mdn-data: 2.23.0 source-map-js: 1.2.1 - '@eslint/eslintrc@3.3.3': + '@eslint/eslintrc@3.3.4': dependencies: - ajv: 6.12.6 + ajv: 6.14.0 debug: 4.4.3 espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.1 js-yaml: 4.1.1 - minimatch: 3.1.2 + minimatch: 3.1.5 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color @@ -12794,7 +12961,7 @@ snapshots: '@eslint/core': 0.17.0 levn: 0.4.1 - '@faker-js/faker@10.2.0': {} + '@faker-js/faker@10.3.0': {} '@fontsource-variable/dm-sans@5.2.8': {} @@ -12826,26 +12993,30 @@ snapshots: dependencies: tslib: 2.8.1 - '@hookform/devtools@4.4.0(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@hono/node-server@1.19.9(hono@4.11.4)': dependencies: - '@emotion/react': 11.14.0(@types/react@19.2.7)(react@19.2.3) - '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.7)(react@19.2.3))(@types/react@19.2.7)(react@19.2.3) - '@types/lodash': 4.17.21 - little-state-machine: 4.8.1(react@19.2.3) - lodash: 4.17.21 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - react-simple-animate: 3.5.3(react-dom@19.2.3(react@19.2.3)) - use-deep-compare-effect: 1.8.1(react@19.2.3) + hono: 4.11.4 + + '@hookform/devtools@4.4.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@emotion/react': 11.14.0(@types/react@19.2.14)(react@19.2.4) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(react@19.2.4) + '@types/lodash': 4.17.24 + little-state-machine: 4.8.1(react@19.2.4) + lodash: 4.17.23 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-simple-animate: 3.5.3(react-dom@19.2.4(react@19.2.4)) + use-deep-compare-effect: 1.8.1(react@19.2.4) uuid: 8.3.2 transitivePeerDependencies: - '@types/react' - supports-color - '@hookform/resolvers@5.2.2(react-hook-form@7.70.0(react@19.2.3))': + '@hookform/resolvers@5.2.2(react-hook-form@7.70.0(react@19.2.4))': dependencies: '@standard-schema/utils': 0.3.0 - react-hook-form: 7.70.0(react@19.2.3) + react-hook-form: 7.70.0(react@19.2.4) '@humanfs/core@0.19.1': {} @@ -12858,162 +13029,154 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} - '@inquirer/ansi@2.0.2': {} + '@inquirer/ansi@2.0.3': {} - '@inquirer/checkbox@5.0.3(@types/node@25.0.3)': + '@inquirer/checkbox@5.1.0(@types/node@25.3.5)': dependencies: - '@inquirer/ansi': 2.0.2 - '@inquirer/core': 11.1.0(@types/node@25.0.3) - '@inquirer/figures': 2.0.2 - '@inquirer/type': 4.0.2(@types/node@25.0.3) + '@inquirer/ansi': 2.0.3 + '@inquirer/core': 11.1.5(@types/node@25.3.5) + '@inquirer/figures': 2.0.3 + '@inquirer/type': 4.0.3(@types/node@25.3.5) optionalDependencies: - '@types/node': 25.0.3 + '@types/node': 25.3.5 - '@inquirer/confirm@6.0.3(@types/node@25.0.3)': + '@inquirer/confirm@6.0.8(@types/node@25.3.5)': dependencies: - '@inquirer/core': 11.1.0(@types/node@25.0.3) - '@inquirer/type': 4.0.2(@types/node@25.0.3) + '@inquirer/core': 11.1.5(@types/node@25.3.5) + '@inquirer/type': 4.0.3(@types/node@25.3.5) optionalDependencies: - '@types/node': 25.0.3 + '@types/node': 25.3.5 - '@inquirer/core@11.1.0(@types/node@25.0.3)': + '@inquirer/core@11.1.5(@types/node@25.3.5)': dependencies: - '@inquirer/ansi': 2.0.2 - '@inquirer/figures': 2.0.2 - '@inquirer/type': 4.0.2(@types/node@25.0.3) + '@inquirer/ansi': 2.0.3 + '@inquirer/figures': 2.0.3 + '@inquirer/type': 4.0.3(@types/node@25.3.5) cli-width: 4.1.0 + fast-wrap-ansi: 0.2.0 mute-stream: 3.0.0 signal-exit: 4.1.0 - wrap-ansi: 9.0.2 optionalDependencies: - '@types/node': 25.0.3 + '@types/node': 25.3.5 - '@inquirer/editor@5.0.3(@types/node@25.0.3)': + '@inquirer/editor@5.0.8(@types/node@25.3.5)': dependencies: - '@inquirer/core': 11.1.0(@types/node@25.0.3) - '@inquirer/external-editor': 2.0.2(@types/node@25.0.3) - '@inquirer/type': 4.0.2(@types/node@25.0.3) + '@inquirer/core': 11.1.5(@types/node@25.3.5) + '@inquirer/external-editor': 2.0.3(@types/node@25.3.5) + '@inquirer/type': 4.0.3(@types/node@25.3.5) optionalDependencies: - '@types/node': 25.0.3 + '@types/node': 25.3.5 - '@inquirer/expand@5.0.3(@types/node@25.0.3)': + '@inquirer/expand@5.0.8(@types/node@25.3.5)': dependencies: - '@inquirer/core': 11.1.0(@types/node@25.0.3) - '@inquirer/type': 4.0.2(@types/node@25.0.3) + '@inquirer/core': 11.1.5(@types/node@25.3.5) + '@inquirer/type': 4.0.3(@types/node@25.3.5) optionalDependencies: - '@types/node': 25.0.3 + '@types/node': 25.3.5 - '@inquirer/external-editor@2.0.2(@types/node@25.0.3)': + '@inquirer/external-editor@2.0.3(@types/node@25.3.5)': dependencies: chardet: 2.1.1 - iconv-lite: 0.7.1 + iconv-lite: 0.7.2 optionalDependencies: - '@types/node': 25.0.3 + '@types/node': 25.3.5 - '@inquirer/figures@2.0.2': {} + '@inquirer/figures@2.0.3': {} - '@inquirer/input@5.0.3(@types/node@25.0.3)': + '@inquirer/input@5.0.8(@types/node@25.3.5)': dependencies: - '@inquirer/core': 11.1.0(@types/node@25.0.3) - '@inquirer/type': 4.0.2(@types/node@25.0.3) + '@inquirer/core': 11.1.5(@types/node@25.3.5) + '@inquirer/type': 4.0.3(@types/node@25.3.5) optionalDependencies: - '@types/node': 25.0.3 + '@types/node': 25.3.5 - '@inquirer/number@4.0.3(@types/node@25.0.3)': + '@inquirer/number@4.0.8(@types/node@25.3.5)': dependencies: - '@inquirer/core': 11.1.0(@types/node@25.0.3) - '@inquirer/type': 4.0.2(@types/node@25.0.3) + '@inquirer/core': 11.1.5(@types/node@25.3.5) + '@inquirer/type': 4.0.3(@types/node@25.3.5) optionalDependencies: - '@types/node': 25.0.3 + '@types/node': 25.3.5 - '@inquirer/password@5.0.3(@types/node@25.0.3)': + '@inquirer/password@5.0.8(@types/node@25.3.5)': dependencies: - '@inquirer/ansi': 2.0.2 - '@inquirer/core': 11.1.0(@types/node@25.0.3) - '@inquirer/type': 4.0.2(@types/node@25.0.3) + '@inquirer/ansi': 2.0.3 + '@inquirer/core': 11.1.5(@types/node@25.3.5) + '@inquirer/type': 4.0.3(@types/node@25.3.5) optionalDependencies: - '@types/node': 25.0.3 - - '@inquirer/prompts@8.1.0(@types/node@25.0.3)': - dependencies: - '@inquirer/checkbox': 5.0.3(@types/node@25.0.3) - '@inquirer/confirm': 6.0.3(@types/node@25.0.3) - '@inquirer/editor': 5.0.3(@types/node@25.0.3) - '@inquirer/expand': 5.0.3(@types/node@25.0.3) - '@inquirer/input': 5.0.3(@types/node@25.0.3) - '@inquirer/number': 4.0.3(@types/node@25.0.3) - '@inquirer/password': 5.0.3(@types/node@25.0.3) - '@inquirer/rawlist': 5.1.0(@types/node@25.0.3) - '@inquirer/search': 4.0.3(@types/node@25.0.3) - '@inquirer/select': 5.0.3(@types/node@25.0.3) + '@types/node': 25.3.5 + + '@inquirer/prompts@8.3.0(@types/node@25.3.5)': + dependencies: + '@inquirer/checkbox': 5.1.0(@types/node@25.3.5) + '@inquirer/confirm': 6.0.8(@types/node@25.3.5) + '@inquirer/editor': 5.0.8(@types/node@25.3.5) + '@inquirer/expand': 5.0.8(@types/node@25.3.5) + '@inquirer/input': 5.0.8(@types/node@25.3.5) + '@inquirer/number': 4.0.8(@types/node@25.3.5) + '@inquirer/password': 5.0.8(@types/node@25.3.5) + '@inquirer/rawlist': 5.2.4(@types/node@25.3.5) + '@inquirer/search': 4.1.4(@types/node@25.3.5) + '@inquirer/select': 5.1.0(@types/node@25.3.5) optionalDependencies: - '@types/node': 25.0.3 + '@types/node': 25.3.5 - '@inquirer/rawlist@5.1.0(@types/node@25.0.3)': + '@inquirer/rawlist@5.2.4(@types/node@25.3.5)': dependencies: - '@inquirer/core': 11.1.0(@types/node@25.0.3) - '@inquirer/type': 4.0.2(@types/node@25.0.3) + '@inquirer/core': 11.1.5(@types/node@25.3.5) + '@inquirer/type': 4.0.3(@types/node@25.3.5) optionalDependencies: - '@types/node': 25.0.3 + '@types/node': 25.3.5 - '@inquirer/search@4.0.3(@types/node@25.0.3)': + '@inquirer/search@4.1.4(@types/node@25.3.5)': dependencies: - '@inquirer/core': 11.1.0(@types/node@25.0.3) - '@inquirer/figures': 2.0.2 - '@inquirer/type': 4.0.2(@types/node@25.0.3) + '@inquirer/core': 11.1.5(@types/node@25.3.5) + '@inquirer/figures': 2.0.3 + '@inquirer/type': 4.0.3(@types/node@25.3.5) optionalDependencies: - '@types/node': 25.0.3 + '@types/node': 25.3.5 - '@inquirer/select@5.0.3(@types/node@25.0.3)': + '@inquirer/select@5.1.0(@types/node@25.3.5)': dependencies: - '@inquirer/ansi': 2.0.2 - '@inquirer/core': 11.1.0(@types/node@25.0.3) - '@inquirer/figures': 2.0.2 - '@inquirer/type': 4.0.2(@types/node@25.0.3) + '@inquirer/ansi': 2.0.3 + '@inquirer/core': 11.1.5(@types/node@25.3.5) + '@inquirer/figures': 2.0.3 + '@inquirer/type': 4.0.3(@types/node@25.3.5) optionalDependencies: - '@types/node': 25.0.3 + '@types/node': 25.3.5 - '@inquirer/type@4.0.2(@types/node@25.0.3)': + '@inquirer/type@4.0.3(@types/node@25.3.5)': optionalDependencies: - '@types/node': 25.0.3 + '@types/node': 25.3.5 - '@internationalized/date@3.10.1': + '@internationalized/date@3.12.0': dependencies: - '@swc/helpers': 0.5.18 + '@swc/helpers': 0.5.19 '@internationalized/message@3.1.8': dependencies: - '@swc/helpers': 0.5.18 + '@swc/helpers': 0.5.19 intl-messageformat: 10.7.18 '@internationalized/number@3.6.5': dependencies: - '@swc/helpers': 0.5.18 + '@swc/helpers': 0.5.19 '@internationalized/string@3.2.7': dependencies: - '@swc/helpers': 0.5.18 - - '@isaacs/balanced-match@4.0.1': {} - - '@isaacs/brace-expansion@5.0.0': - dependencies: - '@isaacs/balanced-match': 4.0.1 + '@swc/helpers': 0.5.19 '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 strip-ansi-cjs: strip-ansi@6.0.1 wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 - '@isaacs/cliui@9.0.0': {} - '@isaacs/fs-minipass@4.0.1': dependencies: - minipass: 7.1.2 + minipass: 7.1.3 '@jest/diff-sequences@30.0.1': {} @@ -13021,13 +13184,13 @@ snapshots: '@jest/schemas@30.0.5': dependencies: - '@sinclair/typebox': 0.34.47 + '@sinclair/typebox': 0.34.48 - '@joshwooding/vite-plugin-react-docgen-typescript@0.6.3(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@joshwooding/vite-plugin-react-docgen-typescript@0.6.4(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - glob: 11.1.0 + glob: 13.0.6 react-docgen-typescript: 2.4.0(typescript@5.9.3) - vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) optionalDependencies: typescript: 5.9.3 @@ -13060,52 +13223,50 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@lezer/common@1.5.0': {} - '@lezer/common@1.5.1': {} - '@lezer/css@1.3.0': + '@lezer/css@1.3.1': dependencies: - '@lezer/common': 1.5.0 + '@lezer/common': 1.5.1 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.7 + '@lezer/lr': 1.4.8 '@lezer/generator@1.8.0': dependencies: - '@lezer/common': 1.5.0 - '@lezer/lr': 1.4.7 + '@lezer/common': 1.5.1 + '@lezer/lr': 1.4.8 '@lezer/highlight@1.2.3': dependencies: - '@lezer/common': 1.5.0 + '@lezer/common': 1.5.1 '@lezer/html@1.3.13': dependencies: - '@lezer/common': 1.5.0 + '@lezer/common': 1.5.1 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.7 + '@lezer/lr': 1.4.8 '@lezer/javascript@1.5.4': dependencies: - '@lezer/common': 1.5.0 + '@lezer/common': 1.5.1 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.7 + '@lezer/lr': 1.4.8 '@lezer/json@1.0.3': dependencies: - '@lezer/common': 1.5.0 + '@lezer/common': 1.5.1 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.7 + '@lezer/lr': 1.4.8 - '@lezer/lr@1.4.7': + '@lezer/lr@1.4.8': dependencies: - '@lezer/common': 1.5.0 + '@lezer/common': 1.5.1 '@lezer/xml@1.0.6': dependencies: - '@lezer/common': 1.5.0 + '@lezer/common': 1.5.1 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.7 + '@lezer/lr': 1.4.8 '@libsql/client@0.14.0': dependencies: @@ -13176,18 +13337,18 @@ snapshots: dependencies: debug: 4.4.3 fs-extra: 9.1.0 - lodash: 4.17.21 + lodash: 4.17.23 tmp-promise: 3.0.3 transitivePeerDependencies: - supports-color '@marijn/find-cluster-break@1.0.2': {} - '@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3)': + '@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4)': dependencies: '@types/mdx': 2.0.13 - '@types/react': 19.2.7 - react: 19.2.3 + '@types/react': 19.2.14 + react: 19.2.4 '@module-federation/bridge-react-webpack-plugin@0.21.6': dependencies: @@ -13195,9 +13356,9 @@ snapshots: '@types/semver': 7.5.8 semver: 7.6.3 - '@module-federation/bridge-react-webpack-plugin@0.22.0': + '@module-federation/bridge-react-webpack-plugin@2.1.0': dependencies: - '@module-federation/sdk': 0.22.0 + '@module-federation/sdk': 2.1.0 '@types/semver': 7.5.8 semver: 7.6.3 @@ -13216,10 +13377,10 @@ snapshots: - utf-8-validate - vue-tsc - '@module-federation/cli@0.22.0(typescript@5.9.3)': + '@module-federation/cli@2.1.0(typescript@5.9.3)': dependencies: - '@module-federation/dts-plugin': 0.22.0(typescript@5.9.3) - '@module-federation/sdk': 0.22.0 + '@module-federation/dts-plugin': 2.1.0(typescript@5.9.3) + '@module-federation/sdk': 2.1.0 chalk: 3.0.0 commander: 11.1.0 jiti: 2.4.2 @@ -13231,21 +13392,22 @@ snapshots: - utf-8-validate - vue-tsc - '@module-federation/data-prefetch@0.21.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@module-federation/data-prefetch@0.21.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@module-federation/runtime': 0.21.6 '@module-federation/sdk': 0.21.6 fs-extra: 9.1.0 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - '@module-federation/data-prefetch@0.22.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@module-federation/data-prefetch@2.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@module-federation/runtime': 0.22.0 - '@module-federation/sdk': 0.22.0 + '@module-federation/runtime': 2.1.0 + '@module-federation/sdk': 2.1.0 fs-extra: 9.1.0 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) '@module-federation/dts-plugin@0.21.6(typescript@5.9.3)': dependencies: @@ -13255,7 +13417,7 @@ snapshots: '@module-federation/third-party-dts-extractor': 0.21.6 adm-zip: 0.5.16 ansi-colors: 4.1.3 - axios: 1.13.2 + axios: 1.13.6 chalk: 3.0.0 fs-extra: 9.1.0 isomorphic-ws: 5.0.0(ws@8.18.0) @@ -13272,19 +13434,18 @@ snapshots: - supports-color - utf-8-validate - '@module-federation/dts-plugin@0.22.0(typescript@5.9.3)': + '@module-federation/dts-plugin@2.1.0(typescript@5.9.3)': dependencies: - '@module-federation/error-codes': 0.22.0 - '@module-federation/managers': 0.22.0 - '@module-federation/sdk': 0.22.0 - '@module-federation/third-party-dts-extractor': 0.22.0 + '@module-federation/error-codes': 2.1.0 + '@module-federation/managers': 2.1.0 + '@module-federation/sdk': 2.1.0 + '@module-federation/third-party-dts-extractor': 2.1.0 adm-zip: 0.5.16 ansi-colors: 4.1.3 - axios: 1.13.2 + axios: 1.13.6 chalk: 3.0.0 fs-extra: 9.1.0 isomorphic-ws: 5.0.0(ws@8.18.0) - koa: 3.0.3 lodash.clonedeepwith: 4.5.0 log4js: 6.9.1 node-schedule: 2.1.1 @@ -13297,17 +13458,17 @@ snapshots: - supports-color - utf-8-validate - '@module-federation/enhanced@0.21.6(@rspack/core@1.6.8(@swc/helpers@0.5.18))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18)))': + '@module-federation/enhanced@0.21.6(@rspack/core@1.6.8(@swc/helpers@0.5.19))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19)))': dependencies: '@module-federation/bridge-react-webpack-plugin': 0.21.6 '@module-federation/cli': 0.21.6(typescript@5.9.3) - '@module-federation/data-prefetch': 0.21.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@module-federation/data-prefetch': 0.21.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@module-federation/dts-plugin': 0.21.6(typescript@5.9.3) '@module-federation/error-codes': 0.21.6 '@module-federation/inject-external-runtime-core-plugin': 0.21.6(@module-federation/runtime-tools@0.21.6) '@module-federation/managers': 0.21.6 '@module-federation/manifest': 0.21.6(typescript@5.9.3) - '@module-federation/rspack': 0.21.6(@rspack/core@1.6.8(@swc/helpers@0.5.18))(typescript@5.9.3) + '@module-federation/rspack': 0.21.6(@rspack/core@1.6.8(@swc/helpers@0.5.19))(typescript@5.9.3) '@module-federation/runtime-tools': 0.21.6 '@module-federation/sdk': 0.21.6 btoa: 1.2.1 @@ -13315,7 +13476,7 @@ snapshots: upath: 2.0.1 optionalDependencies: typescript: 5.9.3 - webpack: 5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18)) + webpack: 5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19)) transitivePeerDependencies: - '@rspack/core' - bufferutil @@ -13325,25 +13486,25 @@ snapshots: - supports-color - utf-8-validate - '@module-federation/enhanced@0.22.0(@rspack/core@1.6.8(@swc/helpers@0.5.18))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18)))': - dependencies: - '@module-federation/bridge-react-webpack-plugin': 0.22.0 - '@module-federation/cli': 0.22.0(typescript@5.9.3) - '@module-federation/data-prefetch': 0.22.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@module-federation/dts-plugin': 0.22.0(typescript@5.9.3) - '@module-federation/error-codes': 0.22.0 - '@module-federation/inject-external-runtime-core-plugin': 0.22.0(@module-federation/runtime-tools@0.22.0) - '@module-federation/managers': 0.22.0 - '@module-federation/manifest': 0.22.0(typescript@5.9.3) - '@module-federation/rspack': 0.22.0(@rspack/core@1.6.8(@swc/helpers@0.5.18))(typescript@5.9.3) - '@module-federation/runtime-tools': 0.22.0 - '@module-federation/sdk': 0.22.0 + '@module-federation/enhanced@2.1.0(@rspack/core@1.6.8(@swc/helpers@0.5.19))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19)))': + dependencies: + '@module-federation/bridge-react-webpack-plugin': 2.1.0 + '@module-federation/cli': 2.1.0(typescript@5.9.3) + '@module-federation/data-prefetch': 2.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@module-federation/dts-plugin': 2.1.0(typescript@5.9.3) + '@module-federation/error-codes': 2.1.0 + '@module-federation/inject-external-runtime-core-plugin': 2.1.0(@module-federation/runtime-tools@2.1.0) + '@module-federation/managers': 2.1.0 + '@module-federation/manifest': 2.1.0(typescript@5.9.3) + '@module-federation/rspack': 2.1.0(@rspack/core@1.6.8(@swc/helpers@0.5.19))(typescript@5.9.3) + '@module-federation/runtime-tools': 2.1.0 + '@module-federation/sdk': 2.1.0 btoa: 1.2.1 schema-utils: 4.3.3 upath: 2.0.1 optionalDependencies: typescript: 5.9.3 - webpack: 5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18)) + webpack: 5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19)) transitivePeerDependencies: - '@rspack/core' - bufferutil @@ -13355,15 +13516,15 @@ snapshots: '@module-federation/error-codes@0.21.6': {} - '@module-federation/error-codes@0.22.0': {} + '@module-federation/error-codes@2.1.0': {} '@module-federation/inject-external-runtime-core-plugin@0.21.6(@module-federation/runtime-tools@0.21.6)': dependencies: '@module-federation/runtime-tools': 0.21.6 - '@module-federation/inject-external-runtime-core-plugin@0.22.0(@module-federation/runtime-tools@0.22.0)': + '@module-federation/inject-external-runtime-core-plugin@2.1.0(@module-federation/runtime-tools@2.1.0)': dependencies: - '@module-federation/runtime-tools': 0.22.0 + '@module-federation/runtime-tools': 2.1.0 '@module-federation/managers@0.21.6': dependencies: @@ -13371,9 +13532,9 @@ snapshots: find-pkg: 2.0.0 fs-extra: 9.1.0 - '@module-federation/managers@0.22.0': + '@module-federation/managers@2.1.0': dependencies: - '@module-federation/sdk': 0.22.0 + '@module-federation/sdk': 2.1.0 find-pkg: 2.0.0 fs-extra: 9.1.0 @@ -13392,11 +13553,11 @@ snapshots: - utf-8-validate - vue-tsc - '@module-federation/manifest@0.22.0(typescript@5.9.3)': + '@module-federation/manifest@2.1.0(typescript@5.9.3)': dependencies: - '@module-federation/dts-plugin': 0.22.0(typescript@5.9.3) - '@module-federation/managers': 0.22.0 - '@module-federation/sdk': 0.22.0 + '@module-federation/dts-plugin': 2.1.0(typescript@5.9.3) + '@module-federation/managers': 2.1.0 + '@module-federation/sdk': 2.1.0 chalk: 3.0.0 find-pkg: 2.0.0 transitivePeerDependencies: @@ -13407,28 +13568,28 @@ snapshots: - utf-8-validate - vue-tsc - '@module-federation/node@2.7.26(@rspack/core@1.6.8(@swc/helpers@0.5.18))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18)))': + '@module-federation/node@2.7.33(@rspack/core@1.6.8(@swc/helpers@0.5.19))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19)))': dependencies: - '@module-federation/enhanced': 0.22.0(@rspack/core@1.6.8(@swc/helpers@0.5.18))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@module-federation/runtime': 0.22.0 - '@module-federation/sdk': 0.22.0 + '@module-federation/enhanced': 2.1.0(@rspack/core@1.6.8(@swc/helpers@0.5.19))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@module-federation/runtime': 2.1.0 + '@module-federation/sdk': 2.1.0 btoa: 1.2.1 encoding: 0.1.13 node-fetch: 2.7.0(encoding@0.1.13) - webpack: 5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18)) optionalDependencies: - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + webpack: 5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19)) transitivePeerDependencies: - '@rspack/core' - bufferutil - debug + - react + - react-dom - supports-color - typescript - utf-8-validate - vue-tsc - '@module-federation/rspack@0.21.6(@rspack/core@1.6.8(@swc/helpers@0.5.18))(typescript@5.9.3)': + '@module-federation/rspack@0.21.6(@rspack/core@1.6.8(@swc/helpers@0.5.19))(typescript@5.9.3)': dependencies: '@module-federation/bridge-react-webpack-plugin': 0.21.6 '@module-federation/dts-plugin': 0.21.6(typescript@5.9.3) @@ -13437,7 +13598,7 @@ snapshots: '@module-federation/manifest': 0.21.6(typescript@5.9.3) '@module-federation/runtime-tools': 0.21.6 '@module-federation/sdk': 0.21.6 - '@rspack/core': 1.6.8(@swc/helpers@0.5.18) + '@rspack/core': 1.6.8(@swc/helpers@0.5.19) btoa: 1.2.1 optionalDependencies: typescript: 5.9.3 @@ -13447,16 +13608,16 @@ snapshots: - supports-color - utf-8-validate - '@module-federation/rspack@0.22.0(@rspack/core@1.6.8(@swc/helpers@0.5.18))(typescript@5.9.3)': + '@module-federation/rspack@2.1.0(@rspack/core@1.6.8(@swc/helpers@0.5.19))(typescript@5.9.3)': dependencies: - '@module-federation/bridge-react-webpack-plugin': 0.22.0 - '@module-federation/dts-plugin': 0.22.0(typescript@5.9.3) - '@module-federation/inject-external-runtime-core-plugin': 0.22.0(@module-federation/runtime-tools@0.22.0) - '@module-federation/managers': 0.22.0 - '@module-federation/manifest': 0.22.0(typescript@5.9.3) - '@module-federation/runtime-tools': 0.22.0 - '@module-federation/sdk': 0.22.0 - '@rspack/core': 1.6.8(@swc/helpers@0.5.18) + '@module-federation/bridge-react-webpack-plugin': 2.1.0 + '@module-federation/dts-plugin': 2.1.0(typescript@5.9.3) + '@module-federation/inject-external-runtime-core-plugin': 2.1.0(@module-federation/runtime-tools@2.1.0) + '@module-federation/managers': 2.1.0 + '@module-federation/manifest': 2.1.0(typescript@5.9.3) + '@module-federation/runtime-tools': 2.1.0 + '@module-federation/sdk': 2.1.0 + '@rspack/core': 1.6.8(@swc/helpers@0.5.19) btoa: 1.2.1 optionalDependencies: typescript: 5.9.3 @@ -13471,20 +13632,20 @@ snapshots: '@module-federation/error-codes': 0.21.6 '@module-federation/sdk': 0.21.6 - '@module-federation/runtime-core@0.22.0': + '@module-federation/runtime-core@2.1.0': dependencies: - '@module-federation/error-codes': 0.22.0 - '@module-federation/sdk': 0.22.0 + '@module-federation/error-codes': 2.1.0 + '@module-federation/sdk': 2.1.0 '@module-federation/runtime-tools@0.21.6': dependencies: '@module-federation/runtime': 0.21.6 '@module-federation/webpack-bundler-runtime': 0.21.6 - '@module-federation/runtime-tools@0.22.0': + '@module-federation/runtime-tools@2.1.0': dependencies: - '@module-federation/runtime': 0.22.0 - '@module-federation/webpack-bundler-runtime': 0.22.0 + '@module-federation/runtime': 2.1.0 + '@module-federation/webpack-bundler-runtime': 2.1.0 '@module-federation/runtime@0.21.6': dependencies: @@ -13492,15 +13653,15 @@ snapshots: '@module-federation/runtime-core': 0.21.6 '@module-federation/sdk': 0.21.6 - '@module-federation/runtime@0.22.0': + '@module-federation/runtime@2.1.0': dependencies: - '@module-federation/error-codes': 0.22.0 - '@module-federation/runtime-core': 0.22.0 - '@module-federation/sdk': 0.22.0 + '@module-federation/error-codes': 2.1.0 + '@module-federation/runtime-core': 2.1.0 + '@module-federation/sdk': 2.1.0 '@module-federation/sdk@0.21.6': {} - '@module-federation/sdk@0.22.0': {} + '@module-federation/sdk@2.1.0': {} '@module-federation/third-party-dts-extractor@0.21.6': dependencies: @@ -13508,7 +13669,7 @@ snapshots: fs-extra: 9.1.0 resolve: 1.22.8 - '@module-federation/third-party-dts-extractor@0.22.0': + '@module-federation/third-party-dts-extractor@2.1.0': dependencies: find-pkg: 2.0.0 fs-extra: 9.1.0 @@ -13519,10 +13680,14 @@ snapshots: '@module-federation/runtime': 0.21.6 '@module-federation/sdk': 0.21.6 - '@module-federation/webpack-bundler-runtime@0.22.0': + '@module-federation/webpack-bundler-runtime@2.1.0': dependencies: - '@module-federation/runtime': 0.22.0 - '@module-federation/sdk': 0.22.0 + '@module-federation/runtime': 2.1.0 + '@module-federation/sdk': 2.1.0 + + '@mongodb-js/saslprep@1.4.6': + dependencies: + sparse-bitfield: 3.0.3 '@mrleebo/prisma-ast@0.13.1': dependencies: @@ -13608,27 +13773,27 @@ snapshots: agent-base: 7.1.4 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 - lru-cache: 11.2.4 + lru-cache: 11.2.6 socks-proxy-agent: 8.0.5 transitivePeerDependencies: - supports-color '@npmcli/fs@4.0.0': dependencies: - semver: 7.7.3 + semver: 7.7.4 '@npmcli/fs@5.0.0': dependencies: - semver: 7.7.3 + semver: 7.7.2 '@npmcli/redact@4.0.0': {} - '@nx/cypress@22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)))(typescript@5.9.3)': + '@nx/cypress@22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)))(typescript@5.9.3)': dependencies: - '@nx/devkit': 22.3.3(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@nx/eslint': 22.3.3(patch_hash=45d7a0a2e2d55c4ffd4beb467a0e02fac3f27bc1857270f522acafd5365d2c6b)(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@nx/js': 22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@phenomnomnominal/tsquery': 5.0.1(typescript@5.9.3) + '@nx/devkit': 22.5.4(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@nx/eslint': 22.5.4(patch_hash=45d7a0a2e2d55c4ffd4beb467a0e02fac3f27bc1857270f522acafd5365d2c6b)(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@nx/js': 22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@phenomnomnominal/tsquery': 6.1.4(typescript@5.9.3) detect-port: 1.6.1 semver: 7.7.4 tree-kill: 1.2.2 @@ -13645,21 +13810,21 @@ snapshots: - typescript - verdaccio - '@nx/devkit@22.3.3(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)))': + '@nx/devkit@22.5.4(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)))': dependencies: '@zkochan/js-yaml': 0.0.7 ejs: 3.1.10 enquirer: 2.3.6 - minimatch: 9.0.3 - nx: 22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)) + minimatch: 10.2.4 + nx: 22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)) semver: 7.7.4 tslib: 2.8.1 yargs-parser: 21.1.1 - '@nx/eslint@22.3.3(patch_hash=45d7a0a2e2d55c4ffd4beb467a0e02fac3f27bc1857270f522acafd5365d2c6b)(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)))': + '@nx/eslint@22.5.4(patch_hash=45d7a0a2e2d55c4ffd4beb467a0e02fac3f27bc1857270f522acafd5365d2c6b)(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)))': dependencies: - '@nx/devkit': 22.3.3(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@nx/js': 22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) + '@nx/devkit': 22.5.4(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@nx/js': 22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) eslint: 9.39.2(jiti@2.6.1) semver: 7.7.4 tslib: 2.8.1 @@ -13675,21 +13840,21 @@ snapshots: - supports-color - verdaccio - '@nx/js@22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)))': - dependencies: - '@babel/core': 7.28.5 - '@babel/plugin-proposal-decorators': 7.28.0(@babel/core@7.28.5) - '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-runtime': 7.28.5(@babel/core@7.28.5) - '@babel/preset-env': 7.28.5(@babel/core@7.28.5) - '@babel/preset-typescript': 7.28.5(@babel/core@7.28.5) - '@babel/runtime': 7.28.4 - '@nx/devkit': 22.3.3(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@nx/workspace': 22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)) + '@nx/js@22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)))': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-proposal-decorators': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-runtime': 7.29.0(@babel/core@7.29.0) + '@babel/preset-env': 7.29.0(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) + '@babel/runtime': 7.28.6 + '@nx/devkit': 22.5.4(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@nx/workspace': 22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)) '@zkochan/js-yaml': 0.0.7 - babel-plugin-const-enum: 1.2.0(@babel/core@7.28.5) + babel-plugin-const-enum: 1.2.0(@babel/core@7.29.0) babel-plugin-macros: 3.1.0 - babel-plugin-transform-typescript-metadata: 0.3.2(@babel/core@7.28.5)(@babel/traverse@7.28.5) + babel-plugin-transform-typescript-metadata: 0.3.2(@babel/core@7.29.0)(@babel/traverse@7.29.0) chalk: 4.1.2 columnify: 1.6.0 detect-port: 1.6.1 @@ -13711,20 +13876,20 @@ snapshots: - nx - supports-color - '@nx/module-federation@22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/helpers@0.5.18)(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': + '@nx/module-federation@22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/helpers@0.5.19)(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)': dependencies: - '@module-federation/enhanced': 0.21.6(@rspack/core@1.6.8(@swc/helpers@0.5.18))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@module-federation/node': 2.7.26(@rspack/core@1.6.8(@swc/helpers@0.5.18))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))) + '@module-federation/enhanced': 0.21.6(@rspack/core@1.6.8(@swc/helpers@0.5.19))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@module-federation/node': 2.7.33(@rspack/core@1.6.8(@swc/helpers@0.5.19))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))) '@module-federation/sdk': 0.21.6 - '@nx/devkit': 22.3.3(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@nx/js': 22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@nx/web': 22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@rspack/core': 1.6.8(@swc/helpers@0.5.18) + '@nx/devkit': 22.5.4(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@nx/js': 22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@nx/web': 22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@rspack/core': 1.6.8(@swc/helpers@0.5.19) express: 4.22.1 http-proxy-middleware: 3.0.5 picocolors: 1.1.1 tslib: 2.8.1 - webpack: 5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18)) + webpack: 5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19)) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -13733,7 +13898,6 @@ snapshots: - bufferutil - debug - esbuild - - next - nx - react - react-dom @@ -13745,55 +13909,54 @@ snapshots: - vue-tsc - webpack-cli - '@nx/nx-darwin-arm64@22.3.3': + '@nx/nx-darwin-arm64@22.5.4': optional: true - '@nx/nx-darwin-x64@22.3.3': + '@nx/nx-darwin-x64@22.5.4': optional: true - '@nx/nx-freebsd-x64@22.3.3': + '@nx/nx-freebsd-x64@22.5.4': optional: true - '@nx/nx-linux-arm-gnueabihf@22.3.3': + '@nx/nx-linux-arm-gnueabihf@22.5.4': optional: true - '@nx/nx-linux-arm64-gnu@22.3.3': + '@nx/nx-linux-arm64-gnu@22.5.4': optional: true - '@nx/nx-linux-arm64-musl@22.3.3': + '@nx/nx-linux-arm64-musl@22.5.4': optional: true - '@nx/nx-linux-x64-gnu@22.3.3': + '@nx/nx-linux-x64-gnu@22.5.4': optional: true - '@nx/nx-linux-x64-musl@22.3.3': + '@nx/nx-linux-x64-musl@22.5.4': optional: true - '@nx/nx-win32-arm64-msvc@22.3.3': + '@nx/nx-win32-arm64-msvc@22.5.4': optional: true - '@nx/nx-win32-x64-msvc@22.3.3': + '@nx/nx-win32-x64-msvc@22.5.4': optional: true - '@nx/react@22.3.3(@babel/core@7.28.5)(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/helpers@0.5.18)(@types/babel__core@7.20.5)(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(ts-node@10.9.2(@swc/core@1.15.8(@swc/helpers@0.5.18))(@types/node@25.0.3)(typescript@5.9.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18)))': + '@nx/react@22.5.4(@babel/core@7.29.0)(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/helpers@0.5.19)(@types/babel__core@7.20.5)(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - '@nx/devkit': 22.3.3(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@nx/eslint': 22.3.3(patch_hash=45d7a0a2e2d55c4ffd4beb467a0e02fac3f27bc1857270f522acafd5365d2c6b)(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@nx/js': 22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@nx/module-federation': 22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/helpers@0.5.18)(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@nx/rollup': 22.3.3(@babel/core@7.28.5)(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(@types/babel__core@7.20.5)(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)))(ts-node@10.9.2(@swc/core@1.15.8(@swc/helpers@0.5.18))(@types/node@25.0.3)(typescript@5.9.3))(typescript@5.9.3) - '@nx/web': 22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@phenomnomnominal/tsquery': 5.0.1(typescript@5.9.3) + '@nx/devkit': 22.5.4(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@nx/eslint': 22.5.4(patch_hash=45d7a0a2e2d55c4ffd4beb467a0e02fac3f27bc1857270f522acafd5365d2c6b)(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@nx/js': 22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@nx/module-federation': 22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/helpers@0.5.19)(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + '@nx/rollup': 22.5.4(@babel/core@7.29.0)(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(@types/babel__core@7.20.5)(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)))(typescript@5.9.3) + '@nx/web': 22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@phenomnomnominal/tsquery': 6.1.4(typescript@5.9.3) '@svgr/webpack': 8.1.0(typescript@5.9.3) express: 4.22.1 - file-loader: 6.2.0(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))) http-proxy-middleware: 3.0.5 - minimatch: 9.0.3 + minimatch: 10.2.4 picocolors: 1.1.1 semver: 7.7.4 tslib: 2.8.1 optionalDependencies: - '@nx/vite': 22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + '@nx/vite': 22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)))(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) transitivePeerDependencies: - '@babel/core' - '@babel/traverse' @@ -13806,12 +13969,10 @@ snapshots: - debug - esbuild - eslint - - next - nx - react - react-dom - supports-color - - ts-node - typescript - uglify-js - utf-8-validate @@ -13819,26 +13980,26 @@ snapshots: - vite - vitest - vue-tsc - - webpack - webpack-cli - '@nx/rollup@22.3.3(@babel/core@7.28.5)(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(@types/babel__core@7.20.5)(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)))(ts-node@10.9.2(@swc/core@1.15.8(@swc/helpers@0.5.18))(@types/node@25.0.3)(typescript@5.9.3))(typescript@5.9.3)': - dependencies: - '@nx/devkit': 22.3.3(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@nx/js': 22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@rollup/plugin-babel': 6.1.0(@babel/core@7.28.5)(@types/babel__core@7.20.5)(rollup@4.55.1) - '@rollup/plugin-commonjs': 25.0.8(rollup@4.55.1) - '@rollup/plugin-image': 3.0.3(rollup@4.55.1) - '@rollup/plugin-json': 6.1.0(rollup@4.55.1) - '@rollup/plugin-node-resolve': 15.3.1(rollup@4.55.1) - '@rollup/plugin-typescript': 12.3.0(rollup@4.55.1)(tslib@2.8.1)(typescript@5.9.3) - autoprefixer: 10.4.23(postcss@8.5.6) + '@nx/rollup@22.5.4(@babel/core@7.29.0)(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(@types/babel__core@7.20.5)(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)))(typescript@5.9.3)': + dependencies: + '@nx/devkit': 22.5.4(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@nx/js': 22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@rollup/plugin-babel': 6.1.0(@babel/core@7.29.0)(@types/babel__core@7.20.5)(rollup@4.59.0) + '@rollup/plugin-commonjs': 25.0.8(rollup@4.59.0) + '@rollup/plugin-image': 3.0.3(rollup@4.59.0) + '@rollup/plugin-json': 6.1.0(rollup@4.59.0) + '@rollup/plugin-node-resolve': 15.3.1(rollup@4.59.0) + '@rollup/plugin-typescript': 12.3.0(rollup@4.59.0)(tslib@2.8.1)(typescript@5.9.3) + autoprefixer: 10.4.27(postcss@8.5.8) + concat-with-sourcemaps: 1.1.0 picocolors: 1.1.1 picomatch: 4.0.2 - postcss: 8.5.6 - rollup: 4.55.1 - rollup-plugin-postcss: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.15.8(@swc/helpers@0.5.18))(@types/node@25.0.3)(typescript@5.9.3)) - rollup-plugin-typescript2: 0.36.0(rollup@4.55.1)(typescript@5.9.3) + postcss: 8.5.8 + postcss-modules: 6.0.1(postcss@8.5.8) + rollup: 4.59.0 + rollup-plugin-typescript2: 0.36.0(rollup@4.59.0)(typescript@5.9.3) tslib: 2.8.1 transitivePeerDependencies: - '@babel/core' @@ -13849,19 +14010,18 @@ snapshots: - debug - nx - supports-color - - ts-node - typescript - verdaccio - '@nx/storybook@22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)))(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.7.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)': + '@nx/storybook@22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)))(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)': dependencies: - '@nx/cypress': 22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)))(typescript@5.9.3) - '@nx/devkit': 22.3.3(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@nx/eslint': 22.3.3(patch_hash=45d7a0a2e2d55c4ffd4beb467a0e02fac3f27bc1857270f522acafd5365d2c6b)(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@nx/js': 22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@phenomnomnominal/tsquery': 5.0.1(typescript@5.9.3) + '@nx/cypress': 22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)))(typescript@5.9.3) + '@nx/devkit': 22.5.4(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@nx/eslint': 22.5.4(patch_hash=45d7a0a2e2d55c4ffd4beb467a0e02fac3f27bc1857270f522acafd5365d2c6b)(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(@zkochan/js-yaml@0.0.7)(eslint@9.39.2(jiti@2.6.1))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@nx/js': 22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@phenomnomnominal/tsquery': 6.1.4(typescript@5.9.3) semver: 7.7.4 - storybook: 10.1.11(@testing-library/dom@10.4.1)(prettier@3.7.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + storybook: 10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) tslib: 2.8.1 transitivePeerDependencies: - '@babel/traverse' @@ -13876,20 +14036,20 @@ snapshots: - typescript - verdaccio - '@nx/vite@22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@nx/vite@22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)))(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - '@nx/devkit': 22.3.3(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@nx/js': 22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@nx/vitest': 22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) - '@phenomnomnominal/tsquery': 5.0.1(typescript@5.9.3) - ajv: 8.17.1 + '@nx/devkit': 22.5.4(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@nx/js': 22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@nx/vitest': 22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)))(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@phenomnomnominal/tsquery': 6.1.4(typescript@5.9.3) + ajv: 8.18.0 enquirer: 2.3.6 picomatch: 4.0.2 semver: 7.7.4 tsconfig-paths: 4.2.0 tslib: 2.8.1 - vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) - vitest: 4.0.18(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vitest: 4.0.18(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -13900,16 +14060,16 @@ snapshots: - typescript - verdaccio - '@nx/vitest@22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@nx/vitest@22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)))(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - '@nx/devkit': 22.3.3(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@nx/js': 22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@phenomnomnominal/tsquery': 5.0.1(typescript@5.9.3) + '@nx/devkit': 22.5.4(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@nx/js': 22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@phenomnomnominal/tsquery': 6.1.4(typescript@5.9.3) semver: 7.7.4 tslib: 2.8.1 optionalDependencies: - vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) - vitest: 4.0.18(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vitest: 4.0.18(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -13920,10 +14080,10 @@ snapshots: - typescript - verdaccio - '@nx/web@22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)))': + '@nx/web@22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)))': dependencies: - '@nx/devkit': 22.3.3(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) - '@nx/js': 22.3.3(@babel/traverse@7.28.5)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) + '@nx/devkit': 22.5.4(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) + '@nx/js': 22.5.4(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) detect-port: 1.6.1 http-server: 14.1.1 picocolors: 1.1.1 @@ -13937,13 +14097,13 @@ snapshots: - supports-color - verdaccio - '@nx/workspace@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))': + '@nx/workspace@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))': dependencies: - '@nx/devkit': 22.3.3(nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18))) + '@nx/devkit': 22.5.4(nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19))) '@zkochan/js-yaml': 0.0.7 chalk: 4.1.2 enquirer: 2.3.6 - nx: 22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)) + nx: 22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)) picomatch: 4.0.2 semver: 7.7.4 tslib: 2.8.1 @@ -13964,20 +14124,20 @@ snapshots: dependencies: '@octokit/auth-token': 6.0.0 '@octokit/graphql': 9.0.3 - '@octokit/request': 10.0.7 + '@octokit/request': 10.0.8 '@octokit/request-error': 7.1.0 '@octokit/types': 16.0.0 before-after-hook: 4.0.0 universal-user-agent: 7.0.3 - '@octokit/endpoint@11.0.2': + '@octokit/endpoint@11.0.3': dependencies: '@octokit/types': 16.0.0 universal-user-agent: 7.0.3 '@octokit/graphql@9.0.3': dependencies: - '@octokit/request': 10.0.7 + '@octokit/request': 10.0.8 '@octokit/types': 16.0.0 universal-user-agent: 7.0.3 @@ -14001,12 +14161,13 @@ snapshots: dependencies: '@octokit/types': 16.0.0 - '@octokit/request@10.0.7': + '@octokit/request@10.0.8': dependencies: - '@octokit/endpoint': 11.0.2 + '@octokit/endpoint': 11.0.3 '@octokit/request-error': 7.1.0 '@octokit/types': 16.0.0 fast-content-type-parse: 3.0.0 + json-with-bigint: 3.5.7 universal-user-agent: 7.0.3 '@octokit/rest@22.0.1': @@ -14020,1252 +14181,1320 @@ snapshots: dependencies: '@octokit/openapi-types': 27.0.0 - '@oxc-resolver/binding-android-arm-eabi@11.16.2': + '@oxc-resolver/binding-android-arm-eabi@11.19.1': optional: true - '@oxc-resolver/binding-android-arm64@11.16.2': + '@oxc-resolver/binding-android-arm64@11.19.1': optional: true - '@oxc-resolver/binding-darwin-arm64@11.16.2': + '@oxc-resolver/binding-darwin-arm64@11.19.1': optional: true - '@oxc-resolver/binding-darwin-x64@11.16.2': + '@oxc-resolver/binding-darwin-x64@11.19.1': optional: true - '@oxc-resolver/binding-freebsd-x64@11.16.2': + '@oxc-resolver/binding-freebsd-x64@11.19.1': optional: true - '@oxc-resolver/binding-linux-arm-gnueabihf@11.16.2': + '@oxc-resolver/binding-linux-arm-gnueabihf@11.19.1': optional: true - '@oxc-resolver/binding-linux-arm-musleabihf@11.16.2': + '@oxc-resolver/binding-linux-arm-musleabihf@11.19.1': optional: true - '@oxc-resolver/binding-linux-arm64-gnu@11.16.2': + '@oxc-resolver/binding-linux-arm64-gnu@11.19.1': optional: true - '@oxc-resolver/binding-linux-arm64-musl@11.16.2': + '@oxc-resolver/binding-linux-arm64-musl@11.19.1': optional: true - '@oxc-resolver/binding-linux-ppc64-gnu@11.16.2': + '@oxc-resolver/binding-linux-ppc64-gnu@11.19.1': optional: true - '@oxc-resolver/binding-linux-riscv64-gnu@11.16.2': + '@oxc-resolver/binding-linux-riscv64-gnu@11.19.1': optional: true - '@oxc-resolver/binding-linux-riscv64-musl@11.16.2': + '@oxc-resolver/binding-linux-riscv64-musl@11.19.1': optional: true - '@oxc-resolver/binding-linux-s390x-gnu@11.16.2': + '@oxc-resolver/binding-linux-s390x-gnu@11.19.1': optional: true - '@oxc-resolver/binding-linux-x64-gnu@11.16.2': + '@oxc-resolver/binding-linux-x64-gnu@11.19.1': optional: true - '@oxc-resolver/binding-linux-x64-musl@11.16.2': + '@oxc-resolver/binding-linux-x64-musl@11.19.1': optional: true - '@oxc-resolver/binding-openharmony-arm64@11.16.2': + '@oxc-resolver/binding-openharmony-arm64@11.19.1': optional: true - '@oxc-resolver/binding-wasm32-wasi@11.16.2': + '@oxc-resolver/binding-wasm32-wasi@11.19.1': dependencies: '@napi-rs/wasm-runtime': 1.1.1 optional: true - '@oxc-resolver/binding-win32-arm64-msvc@11.16.2': + '@oxc-resolver/binding-win32-arm64-msvc@11.19.1': optional: true - '@oxc-resolver/binding-win32-ia32-msvc@11.16.2': + '@oxc-resolver/binding-win32-ia32-msvc@11.19.1': optional: true - '@oxc-resolver/binding-win32-x64-msvc@11.16.2': + '@oxc-resolver/binding-win32-x64-msvc@11.19.1': optional: true - '@parcel/watcher-android-arm64@2.5.1': + '@parcel/watcher-android-arm64@2.5.6': optional: true - '@parcel/watcher-darwin-arm64@2.5.1': + '@parcel/watcher-darwin-arm64@2.5.6': optional: true - '@parcel/watcher-darwin-x64@2.5.1': + '@parcel/watcher-darwin-x64@2.5.6': optional: true - '@parcel/watcher-freebsd-x64@2.5.1': + '@parcel/watcher-freebsd-x64@2.5.6': optional: true - '@parcel/watcher-linux-arm-glibc@2.5.1': + '@parcel/watcher-linux-arm-glibc@2.5.6': optional: true - '@parcel/watcher-linux-arm-musl@2.5.1': + '@parcel/watcher-linux-arm-musl@2.5.6': optional: true - '@parcel/watcher-linux-arm64-glibc@2.5.1': + '@parcel/watcher-linux-arm64-glibc@2.5.6': optional: true - '@parcel/watcher-linux-arm64-musl@2.5.1': + '@parcel/watcher-linux-arm64-musl@2.5.6': optional: true - '@parcel/watcher-linux-x64-glibc@2.5.1': + '@parcel/watcher-linux-x64-glibc@2.5.6': optional: true - '@parcel/watcher-linux-x64-musl@2.5.1': + '@parcel/watcher-linux-x64-musl@2.5.6': optional: true - '@parcel/watcher-win32-arm64@2.5.1': + '@parcel/watcher-win32-arm64@2.5.6': optional: true - '@parcel/watcher-win32-ia32@2.5.1': + '@parcel/watcher-win32-ia32@2.5.6': optional: true - '@parcel/watcher-win32-x64@2.5.1': + '@parcel/watcher-win32-x64@2.5.6': optional: true - '@parcel/watcher@2.5.1': + '@parcel/watcher@2.5.6': dependencies: - detect-libc: 1.0.3 + detect-libc: 2.1.2 is-glob: 4.0.3 - micromatch: 4.0.8 node-addon-api: 7.1.1 + picomatch: 4.0.3 optionalDependencies: - '@parcel/watcher-android-arm64': 2.5.1 - '@parcel/watcher-darwin-arm64': 2.5.1 - '@parcel/watcher-darwin-x64': 2.5.1 - '@parcel/watcher-freebsd-x64': 2.5.1 - '@parcel/watcher-linux-arm-glibc': 2.5.1 - '@parcel/watcher-linux-arm-musl': 2.5.1 - '@parcel/watcher-linux-arm64-glibc': 2.5.1 - '@parcel/watcher-linux-arm64-musl': 2.5.1 - '@parcel/watcher-linux-x64-glibc': 2.5.1 - '@parcel/watcher-linux-x64-musl': 2.5.1 - '@parcel/watcher-win32-arm64': 2.5.1 - '@parcel/watcher-win32-ia32': 2.5.1 - '@parcel/watcher-win32-x64': 2.5.1 - - '@phenomnomnominal/tsquery@5.0.1(typescript@5.9.3)': - dependencies: + '@parcel/watcher-android-arm64': 2.5.6 + '@parcel/watcher-darwin-arm64': 2.5.6 + '@parcel/watcher-darwin-x64': 2.5.6 + '@parcel/watcher-freebsd-x64': 2.5.6 + '@parcel/watcher-linux-arm-glibc': 2.5.6 + '@parcel/watcher-linux-arm-musl': 2.5.6 + '@parcel/watcher-linux-arm64-glibc': 2.5.6 + '@parcel/watcher-linux-arm64-musl': 2.5.6 + '@parcel/watcher-linux-x64-glibc': 2.5.6 + '@parcel/watcher-linux-x64-musl': 2.5.6 + '@parcel/watcher-win32-arm64': 2.5.6 + '@parcel/watcher-win32-ia32': 2.5.6 + '@parcel/watcher-win32-x64': 2.5.6 + + '@phenomnomnominal/tsquery@6.1.4(typescript@5.9.3)': + dependencies: + '@types/esquery': 1.5.4 esquery: 1.7.0 typescript: 5.9.3 - '@pivanov/utils@0.0.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - '@pkgjs/parseargs@0.11.0': optional: true '@pkgr/core@0.2.9': {} - '@preact/signals-core@1.12.1': {} + '@preact/signals-core@1.13.0': {} - '@preact/signals@1.3.2(preact@10.28.2)': + '@preact/signals@1.3.4(preact@10.28.4)': dependencies: - '@preact/signals-core': 1.12.1 - preact: 10.28.2 + '@preact/signals-core': 1.13.0 + preact: 10.28.4 - '@prettier/plugin-xml@3.4.2(prettier@3.7.4)': + '@prettier/plugin-xml@3.4.2(prettier@3.8.1)': dependencies: '@xml-tools/parser': 1.0.11 - prettier: 3.7.4 - - '@prisma/client@5.22.0': {} - - '@react-aria/autocomplete@3.0.0-rc.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/combobox': 3.14.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/focus': 3.21.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/listbox': 3.15.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/searchfield': 3.8.10(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/textfield': 3.18.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/autocomplete': 3.0.0-beta.4(react@19.2.3) - '@react-stately/combobox': 3.12.1(react@19.2.3) - '@react-types/autocomplete': 3.0.0-alpha.36(react@19.2.3) - '@react-types/button': 3.14.1(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/breadcrumbs@3.5.30(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/link': 3.8.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-types/breadcrumbs': 3.7.17(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/button@3.14.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/toolbar': 3.0.0-beta.22(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/toggle': 3.9.3(react@19.2.3) - '@react-types/button': 3.14.1(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/calendar@3.9.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@internationalized/date': 3.10.1 - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + prettier: 3.8.1 + + '@prisma/client@5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))': + optionalDependencies: + prisma: 7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + + '@prisma/config@7.4.2': + dependencies: + c12: 3.1.0 + deepmerge-ts: 7.1.5 + effect: 3.18.4 + empathic: 2.0.0 + transitivePeerDependencies: + - magicast + + '@prisma/debug@7.2.0': {} + + '@prisma/debug@7.4.2': {} + + '@prisma/dev@0.20.0(typescript@5.9.3)': + dependencies: + '@electric-sql/pglite': 0.3.15 + '@electric-sql/pglite-socket': 0.0.20(@electric-sql/pglite@0.3.15) + '@electric-sql/pglite-tools': 0.2.20(@electric-sql/pglite@0.3.15) + '@hono/node-server': 1.19.9(hono@4.11.4) + '@mrleebo/prisma-ast': 0.13.1 + '@prisma/get-platform': 7.2.0 + '@prisma/query-plan-executor': 7.2.0 + foreground-child: 3.3.1 + get-port-please: 3.2.0 + hono: 4.11.4 + http-status-codes: 2.3.0 + pathe: 2.0.3 + proper-lockfile: 4.1.2 + remeda: 2.33.4 + std-env: 3.10.0 + valibot: 1.2.0(typescript@5.9.3) + zeptomatch: 2.1.0 + transitivePeerDependencies: + - typescript + + '@prisma/engines-version@7.5.0-10.94a226be1cf2967af2541cca5529f0f7ba866919': {} + + '@prisma/engines@7.4.2': + dependencies: + '@prisma/debug': 7.4.2 + '@prisma/engines-version': 7.5.0-10.94a226be1cf2967af2541cca5529f0f7ba866919 + '@prisma/fetch-engine': 7.4.2 + '@prisma/get-platform': 7.4.2 + + '@prisma/fetch-engine@7.4.2': + dependencies: + '@prisma/debug': 7.4.2 + '@prisma/engines-version': 7.5.0-10.94a226be1cf2967af2541cca5529f0f7ba866919 + '@prisma/get-platform': 7.4.2 + + '@prisma/get-platform@7.2.0': + dependencies: + '@prisma/debug': 7.2.0 + + '@prisma/get-platform@7.4.2': + dependencies: + '@prisma/debug': 7.4.2 + + '@prisma/query-plan-executor@7.2.0': {} + + '@prisma/studio-core@0.13.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@types/react': 19.2.14 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/autocomplete@3.0.0-rc.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/combobox': 3.15.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/focus': 3.21.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/listbox': 3.15.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/searchfield': 3.8.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/textfield': 3.18.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/autocomplete': 3.0.0-beta.4(react@19.2.4) + '@react-stately/combobox': 3.13.0(react@19.2.4) + '@react-types/autocomplete': 3.0.0-alpha.38(react@19.2.4) + '@react-types/button': 3.15.1(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/breadcrumbs@3.5.32(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/link': 3.8.9(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/breadcrumbs': 3.7.19(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/button@3.14.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/toolbar': 3.0.0-beta.24(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/toggle': 3.9.5(react@19.2.4) + '@react-types/button': 3.15.1(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/calendar@3.9.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@internationalized/date': 3.12.0 + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@react-aria/live-announcer': 3.4.4 - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/calendar': 3.9.1(react@19.2.3) - '@react-types/button': 3.14.1(react@19.2.3) - '@react-types/calendar': 3.8.1(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/checkbox@3.16.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/form': 3.1.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/label': 3.7.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/toggle': 3.12.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/checkbox': 3.7.3(react@19.2.3) - '@react-stately/form': 3.2.2(react@19.2.3) - '@react-stately/toggle': 3.9.3(react@19.2.3) - '@react-types/checkbox': 3.10.2(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/collections@3.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/ssr': 3.9.10(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - use-sync-external-store: 1.6.0(react@19.2.3) - - '@react-aria/color@3.1.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/numberfield': 3.12.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/slider': 3.8.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/spinbutton': 3.7.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/textfield': 3.18.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/visually-hidden': 3.8.29(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/color': 3.9.3(react@19.2.3) - '@react-stately/form': 3.2.2(react@19.2.3) - '@react-types/color': 3.1.2(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/combobox@3.14.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/focus': 3.21.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/listbox': 3.15.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/calendar': 3.9.3(react@19.2.4) + '@react-types/button': 3.15.1(react@19.2.4) + '@react-types/calendar': 3.8.3(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/checkbox@3.16.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/form': 3.1.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/label': 3.7.25(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/toggle': 3.12.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/checkbox': 3.7.5(react@19.2.4) + '@react-stately/form': 3.2.4(react@19.2.4) + '@react-stately/toggle': 3.9.5(react@19.2.4) + '@react-types/checkbox': 3.10.4(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/collections@3.0.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/ssr': 3.9.10(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + use-sync-external-store: 1.6.0(react@19.2.4) + + '@react-aria/color@3.1.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/numberfield': 3.12.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/slider': 3.8.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/spinbutton': 3.7.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/textfield': 3.18.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/visually-hidden': 3.8.31(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/color': 3.9.5(react@19.2.4) + '@react-stately/form': 3.2.4(react@19.2.4) + '@react-types/color': 3.1.4(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/combobox@3.15.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/focus': 3.21.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/listbox': 3.15.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@react-aria/live-announcer': 3.4.4 - '@react-aria/menu': 3.19.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/overlays': 3.31.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/selection': 3.27.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/textfield': 3.18.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/collections': 3.12.8(react@19.2.3) - '@react-stately/combobox': 3.12.1(react@19.2.3) - '@react-stately/form': 3.2.2(react@19.2.3) - '@react-types/button': 3.14.1(react@19.2.3) - '@react-types/combobox': 3.13.10(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/datepicker@3.15.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@internationalized/date': 3.10.1 + '@react-aria/menu': 3.21.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/overlays': 3.31.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/selection': 3.27.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/textfield': 3.18.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/collections': 3.12.10(react@19.2.4) + '@react-stately/combobox': 3.13.0(react@19.2.4) + '@react-stately/form': 3.2.4(react@19.2.4) + '@react-types/button': 3.15.1(react@19.2.4) + '@react-types/combobox': 3.14.0(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/datepicker@3.16.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@internationalized/date': 3.12.0 '@internationalized/number': 3.6.5 '@internationalized/string': 3.2.7 - '@react-aria/focus': 3.21.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/form': 3.1.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/label': 3.7.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/spinbutton': 3.7.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/datepicker': 3.15.3(react@19.2.3) - '@react-stately/form': 3.2.2(react@19.2.3) - '@react-types/button': 3.14.1(react@19.2.3) - '@react-types/calendar': 3.8.1(react@19.2.3) - '@react-types/datepicker': 3.13.3(react@19.2.3) - '@react-types/dialog': 3.5.22(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/dialog@3.5.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/overlays': 3.31.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-types/dialog': 3.5.22(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/disclosure@3.1.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/ssr': 3.9.10(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/disclosure': 3.0.9(react@19.2.3) - '@react-types/button': 3.14.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/dnd@3.11.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@react-aria/focus': 3.21.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/form': 3.1.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/label': 3.7.25(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/spinbutton': 3.7.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/datepicker': 3.16.1(react@19.2.4) + '@react-stately/form': 3.2.4(react@19.2.4) + '@react-types/button': 3.15.1(react@19.2.4) + '@react-types/calendar': 3.8.3(react@19.2.4) + '@react-types/datepicker': 3.13.5(react@19.2.4) + '@react-types/dialog': 3.5.24(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/dialog@3.5.34(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/overlays': 3.31.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/dialog': 3.5.24(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/disclosure@3.1.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/ssr': 3.9.10(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/disclosure': 3.0.11(react@19.2.4) + '@react-types/button': 3.15.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/dnd@3.11.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@internationalized/string': 3.2.7 - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@react-aria/live-announcer': 3.4.4 - '@react-aria/overlays': 3.31.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/collections': 3.12.8(react@19.2.3) - '@react-stately/dnd': 3.7.2(react@19.2.3) - '@react-types/button': 3.14.1(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/focus@3.21.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 + '@react-aria/overlays': 3.31.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/collections': 3.12.10(react@19.2.4) + '@react-stately/dnd': 3.7.4(react@19.2.4) + '@react-types/button': 3.15.1(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/focus@3.21.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 clsx: 2.1.1 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - '@react-aria/form@3.1.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@react-aria/form@3.1.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/form': 3.2.2(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/form': 3.2.4(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - '@react-aria/grid@3.14.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@react-aria/grid@3.14.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@react-aria/focus': 3.21.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@react-aria/focus': 3.21.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@react-aria/live-announcer': 3.4.4 - '@react-aria/selection': 3.27.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/collections': 3.12.8(react@19.2.3) - '@react-stately/grid': 3.11.7(react@19.2.3) - '@react-stately/selection': 3.20.7(react@19.2.3) - '@react-types/checkbox': 3.10.2(react@19.2.3) - '@react-types/grid': 3.3.6(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/gridlist@3.14.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/focus': 3.21.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/grid': 3.14.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/selection': 3.27.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/list': 3.13.2(react@19.2.3) - '@react-stately/tree': 3.9.4(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/i18n@3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@internationalized/date': 3.10.1 + '@react-aria/selection': 3.27.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/collections': 3.12.10(react@19.2.4) + '@react-stately/grid': 3.11.9(react@19.2.4) + '@react-stately/selection': 3.20.9(react@19.2.4) + '@react-types/checkbox': 3.10.4(react@19.2.4) + '@react-types/grid': 3.3.8(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/gridlist@3.14.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/focus': 3.21.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/grid': 3.14.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/selection': 3.27.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/list': 3.13.4(react@19.2.4) + '@react-stately/tree': 3.9.6(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/i18n@3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@internationalized/date': 3.12.0 '@internationalized/message': 3.1.8 '@internationalized/number': 3.6.5 '@internationalized/string': 3.2.7 - '@react-aria/ssr': 3.9.10(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@react-aria/ssr': 3.9.10(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - '@react-aria/interactions@3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@react-aria/interactions@3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@react-aria/ssr': 3.9.10(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@react-aria/ssr': 3.9.10(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@react-stately/flags': 3.1.2 - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/label@3.7.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/landmark@3.0.8(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - use-sync-external-store: 1.6.0(react@19.2.3) - - '@react-aria/link@3.8.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-types/link': 3.6.5(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/listbox@3.15.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/label': 3.7.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/selection': 3.27.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/collections': 3.12.8(react@19.2.3) - '@react-stately/list': 3.13.2(react@19.2.3) - '@react-types/listbox': 3.7.4(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/label@3.7.25(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/landmark@3.0.10(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + use-sync-external-store: 1.6.0(react@19.2.4) + + '@react-aria/link@3.8.9(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/link': 3.6.7(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/listbox@3.15.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/label': 3.7.25(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/selection': 3.27.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/collections': 3.12.10(react@19.2.4) + '@react-stately/list': 3.13.4(react@19.2.4) + '@react-types/listbox': 3.7.6(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) '@react-aria/live-announcer@3.4.4': dependencies: - '@swc/helpers': 0.5.18 - - '@react-aria/menu@3.19.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/focus': 3.21.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/overlays': 3.31.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/selection': 3.27.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/collections': 3.12.8(react@19.2.3) - '@react-stately/menu': 3.9.9(react@19.2.3) - '@react-stately/selection': 3.20.7(react@19.2.3) - '@react-stately/tree': 3.9.4(react@19.2.3) - '@react-types/button': 3.14.1(react@19.2.3) - '@react-types/menu': 3.10.5(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/meter@3.4.28(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/progress': 3.4.28(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-types/meter': 3.4.13(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/numberfield@3.12.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/spinbutton': 3.7.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/textfield': 3.18.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/form': 3.2.2(react@19.2.3) - '@react-stately/numberfield': 3.10.3(react@19.2.3) - '@react-types/button': 3.14.1(react@19.2.3) - '@react-types/numberfield': 3.8.16(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/overlays@3.31.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/focus': 3.21.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/ssr': 3.9.10(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/visually-hidden': 3.8.29(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/overlays': 3.6.21(react@19.2.3) - '@react-types/button': 3.14.1(react@19.2.3) - '@react-types/overlays': 3.9.2(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/progress@3.4.28(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/label': 3.7.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-types/progress': 3.5.16(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/radio@3.12.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/focus': 3.21.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/form': 3.1.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/label': 3.7.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/radio': 3.11.3(react@19.2.3) - '@react-types/radio': 3.9.2(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/searchfield@3.8.10(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/textfield': 3.18.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/searchfield': 3.5.17(react@19.2.3) - '@react-types/button': 3.14.1(react@19.2.3) - '@react-types/searchfield': 3.6.6(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/select@3.17.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/form': 3.1.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/label': 3.7.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/listbox': 3.15.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/menu': 3.19.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/selection': 3.27.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/visually-hidden': 3.8.29(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/select': 3.9.0(react@19.2.3) - '@react-types/button': 3.14.1(react@19.2.3) - '@react-types/select': 3.12.0(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/selection@3.27.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/focus': 3.21.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/selection': 3.20.7(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/separator@3.4.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/slider@3.8.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/label': 3.7.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/slider': 3.7.3(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@react-types/slider': 3.8.2(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/spinbutton@3.7.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@swc/helpers': 0.5.19 + + '@react-aria/menu@3.21.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/focus': 3.21.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/overlays': 3.31.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/selection': 3.27.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/collections': 3.12.10(react@19.2.4) + '@react-stately/menu': 3.9.11(react@19.2.4) + '@react-stately/selection': 3.20.9(react@19.2.4) + '@react-stately/tree': 3.9.6(react@19.2.4) + '@react-types/button': 3.15.1(react@19.2.4) + '@react-types/menu': 3.10.7(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/meter@3.4.30(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/progress': 3.4.30(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/meter': 3.4.15(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/numberfield@3.12.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/live-announcer': 3.4.4 + '@react-aria/spinbutton': 3.7.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/textfield': 3.18.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/form': 3.2.4(react@19.2.4) + '@react-stately/numberfield': 3.11.0(react@19.2.4) + '@react-types/button': 3.15.1(react@19.2.4) + '@react-types/numberfield': 3.8.18(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/overlays@3.31.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/focus': 3.21.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/ssr': 3.9.10(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/visually-hidden': 3.8.31(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/flags': 3.1.2 + '@react-stately/overlays': 3.6.23(react@19.2.4) + '@react-types/button': 3.15.1(react@19.2.4) + '@react-types/overlays': 3.9.4(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/progress@3.4.30(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/label': 3.7.25(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/progress': 3.5.18(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/radio@3.12.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/focus': 3.21.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/form': 3.1.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/label': 3.7.25(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/radio': 3.11.5(react@19.2.4) + '@react-types/radio': 3.9.4(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/searchfield@3.8.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/textfield': 3.18.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/searchfield': 3.5.19(react@19.2.4) + '@react-types/button': 3.15.1(react@19.2.4) + '@react-types/searchfield': 3.6.8(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/select@3.17.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/form': 3.1.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/label': 3.7.25(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/listbox': 3.15.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/menu': 3.21.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/selection': 3.27.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/visually-hidden': 3.8.31(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/select': 3.9.2(react@19.2.4) + '@react-types/button': 3.15.1(react@19.2.4) + '@react-types/select': 3.12.2(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/selection@3.27.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/focus': 3.21.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/selection': 3.20.9(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/separator@3.4.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/slider@3.8.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/label': 3.7.25(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/slider': 3.7.5(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@react-types/slider': 3.8.4(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/spinbutton@3.7.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@react-aria/live-announcer': 3.4.4 - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-types/button': 3.14.1(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/ssr@3.9.10(react@19.2.3)': - dependencies: - '@swc/helpers': 0.5.18 - react: 19.2.3 - - '@react-aria/switch@3.7.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/toggle': 3.12.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/toggle': 3.9.3(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@react-types/switch': 3.5.15(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/table@3.17.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/focus': 3.21.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/grid': 3.14.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/button': 3.15.1(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/ssr@3.9.10(react@19.2.4)': + dependencies: + '@swc/helpers': 0.5.19 + react: 19.2.4 + + '@react-aria/switch@3.7.11(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/toggle': 3.12.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/toggle': 3.9.5(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@react-types/switch': 3.5.17(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/table@3.17.11(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/focus': 3.21.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/grid': 3.14.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@react-aria/live-announcer': 3.4.4 - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/visually-hidden': 3.8.29(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/collections': 3.12.8(react@19.2.3) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/visually-hidden': 3.8.31(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/collections': 3.12.10(react@19.2.4) '@react-stately/flags': 3.1.2 - '@react-stately/table': 3.15.2(patch_hash=5ac384399a7b8e18c4e19f25e434b2f2f27fbd45e7a91cdeb30408330b7243b4)(react@19.2.3) - '@react-types/checkbox': 3.10.2(react@19.2.3) - '@react-types/grid': 3.3.6(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@react-types/table': 3.13.4(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/tabs@3.10.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/focus': 3.21.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/selection': 3.27.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/tabs': 3.8.7(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@react-types/tabs': 3.3.20(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/tag@3.7.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/gridlist': 3.14.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/label': 3.7.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/selection': 3.27.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/list': 3.13.2(react@19.2.3) - '@react-types/button': 3.14.1(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/textfield@3.18.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/form': 3.1.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/label': 3.7.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/form': 3.2.2(react@19.2.3) - '@react-stately/utils': 3.11.0(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@react-types/textfield': 3.12.6(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/toast@3.0.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/landmark': 3.0.8(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/toast': 3.1.2(react@19.2.3) - '@react-types/button': 3.14.1(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/toggle@3.12.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/toggle': 3.9.3(react@19.2.3) - '@react-types/checkbox': 3.10.2(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/toolbar@3.0.0-beta.22(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/focus': 3.21.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/tooltip@3.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/tooltip': 3.5.9(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@react-types/tooltip': 3.5.0(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/tree@3.1.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/gridlist': 3.14.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/selection': 3.27.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/tree': 3.9.4(react@19.2.3) - '@react-types/button': 3.14.1(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@react-aria/utils@3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@react-aria/ssr': 3.9.10(react@19.2.3) + '@react-stately/table': 3.15.4(patch_hash=5ac384399a7b8e18c4e19f25e434b2f2f27fbd45e7a91cdeb30408330b7243b4)(react@19.2.4) + '@react-types/checkbox': 3.10.4(react@19.2.4) + '@react-types/grid': 3.3.8(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@react-types/table': 3.13.6(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/tabs@3.11.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/focus': 3.21.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/selection': 3.27.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/tabs': 3.8.9(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@react-types/tabs': 3.3.22(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/tag@3.8.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/gridlist': 3.14.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/label': 3.7.25(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/selection': 3.27.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/list': 3.13.4(react@19.2.4) + '@react-types/button': 3.15.1(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/textfield@3.18.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/form': 3.1.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/label': 3.7.25(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/form': 3.2.4(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@react-types/textfield': 3.12.8(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/toast@3.0.11(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/landmark': 3.0.10(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/toast': 3.1.3(react@19.2.4) + '@react-types/button': 3.15.1(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/toggle@3.12.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/toggle': 3.9.5(react@19.2.4) + '@react-types/checkbox': 3.10.4(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/toolbar@3.0.0-beta.24(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/focus': 3.21.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/tooltip@3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/tooltip': 3.5.11(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@react-types/tooltip': 3.5.2(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/tree@3.1.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/gridlist': 3.14.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/selection': 3.27.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/tree': 3.9.6(react@19.2.4) + '@react-types/button': 3.15.1(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/utils@3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/ssr': 3.9.10(react@19.2.4) '@react-stately/flags': 3.1.2 - '@react-stately/utils': 3.11.0(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 clsx: 2.1.1 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - '@react-aria/virtualizer@4.1.11(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@react-aria/virtualizer@4.1.13(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/virtualizer': 4.4.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/virtualizer': 4.4.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - '@react-aria/visually-hidden@3.8.29(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@react-aria/visually-hidden@3.8.31(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - '@react-stately/autocomplete@3.0.0-beta.4(react@19.2.3)': + '@react-stately/autocomplete@3.0.0-beta.4(react@19.2.4)': dependencies: - '@react-stately/utils': 3.11.0(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-stately/utils': 3.11.0(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/calendar@3.9.1(react@19.2.3)': + '@react-stately/calendar@3.9.3(react@19.2.4)': dependencies: - '@internationalized/date': 3.10.1 - '@react-stately/utils': 3.11.0(react@19.2.3) - '@react-types/calendar': 3.8.1(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@internationalized/date': 3.12.0 + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/calendar': 3.8.3(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/checkbox@3.7.3(react@19.2.3)': + '@react-stately/checkbox@3.7.5(react@19.2.4)': dependencies: - '@react-stately/form': 3.2.2(react@19.2.3) - '@react-stately/utils': 3.11.0(react@19.2.3) - '@react-types/checkbox': 3.10.2(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-stately/form': 3.2.4(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/checkbox': 3.10.4(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/collections@3.12.8(react@19.2.3)': + '@react-stately/collections@3.12.10(react@19.2.4)': dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/color@3.9.3(react@19.2.3)': + '@react-stately/color@3.9.5(react@19.2.4)': dependencies: '@internationalized/number': 3.6.5 '@internationalized/string': 3.2.7 - '@react-stately/form': 3.2.2(react@19.2.3) - '@react-stately/numberfield': 3.10.3(react@19.2.3) - '@react-stately/slider': 3.7.3(react@19.2.3) - '@react-stately/utils': 3.11.0(react@19.2.3) - '@react-types/color': 3.1.2(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - - '@react-stately/combobox@3.12.1(react@19.2.3)': - dependencies: - '@react-stately/collections': 3.12.8(react@19.2.3) - '@react-stately/form': 3.2.2(react@19.2.3) - '@react-stately/list': 3.13.2(react@19.2.3) - '@react-stately/overlays': 3.6.21(react@19.2.3) - '@react-stately/utils': 3.11.0(react@19.2.3) - '@react-types/combobox': 3.13.10(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - - '@react-stately/data@3.15.0(react@19.2.3)': - dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - - '@react-stately/datepicker@3.15.3(react@19.2.3)': - dependencies: - '@internationalized/date': 3.10.1 + '@react-stately/form': 3.2.4(react@19.2.4) + '@react-stately/numberfield': 3.11.0(react@19.2.4) + '@react-stately/slider': 3.7.5(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/color': 3.1.4(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + + '@react-stately/combobox@3.13.0(react@19.2.4)': + dependencies: + '@react-stately/collections': 3.12.10(react@19.2.4) + '@react-stately/form': 3.2.4(react@19.2.4) + '@react-stately/list': 3.13.4(react@19.2.4) + '@react-stately/overlays': 3.6.23(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/combobox': 3.14.0(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + + '@react-stately/data@3.15.2(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + + '@react-stately/datepicker@3.16.1(react@19.2.4)': + dependencies: + '@internationalized/date': 3.12.0 + '@internationalized/number': 3.6.5 '@internationalized/string': 3.2.7 - '@react-stately/form': 3.2.2(react@19.2.3) - '@react-stately/overlays': 3.6.21(react@19.2.3) - '@react-stately/utils': 3.11.0(react@19.2.3) - '@react-types/datepicker': 3.13.3(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-stately/form': 3.2.4(react@19.2.4) + '@react-stately/overlays': 3.6.23(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/datepicker': 3.13.5(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/disclosure@3.0.9(react@19.2.3)': + '@react-stately/disclosure@3.0.11(react@19.2.4)': dependencies: - '@react-stately/utils': 3.11.0(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/dnd@3.7.2(react@19.2.3)': + '@react-stately/dnd@3.7.4(react@19.2.4)': dependencies: - '@react-stately/selection': 3.20.7(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-stately/selection': 3.20.9(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 '@react-stately/flags@3.1.2': dependencies: - '@swc/helpers': 0.5.18 + '@swc/helpers': 0.5.19 - '@react-stately/form@3.2.2(react@19.2.3)': + '@react-stately/form@3.2.4(react@19.2.4)': dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/grid@3.11.7(react@19.2.3)': + '@react-stately/grid@3.11.9(react@19.2.4)': dependencies: - '@react-stately/collections': 3.12.8(react@19.2.3) - '@react-stately/selection': 3.20.7(react@19.2.3) - '@react-types/grid': 3.3.6(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-stately/collections': 3.12.10(react@19.2.4) + '@react-stately/selection': 3.20.9(react@19.2.4) + '@react-types/grid': 3.3.8(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/layout@4.5.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@react-stately/layout@4.6.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@react-stately/collections': 3.12.8(react@19.2.3) - '@react-stately/table': 3.15.2(patch_hash=5ac384399a7b8e18c4e19f25e434b2f2f27fbd45e7a91cdeb30408330b7243b4)(react@19.2.3) - '@react-stately/virtualizer': 4.4.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-types/grid': 3.3.6(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@react-types/table': 3.13.4(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@react-stately/collections': 3.12.10(react@19.2.4) + '@react-stately/table': 3.15.4(patch_hash=5ac384399a7b8e18c4e19f25e434b2f2f27fbd45e7a91cdeb30408330b7243b4)(react@19.2.4) + '@react-stately/virtualizer': 4.4.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/grid': 3.3.8(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@react-types/table': 3.13.6(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - '@react-stately/list@3.13.2(react@19.2.3)': + '@react-stately/list@3.13.4(react@19.2.4)': dependencies: - '@react-stately/collections': 3.12.8(react@19.2.3) - '@react-stately/selection': 3.20.7(react@19.2.3) - '@react-stately/utils': 3.11.0(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-stately/collections': 3.12.10(react@19.2.4) + '@react-stately/selection': 3.20.9(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/menu@3.9.9(react@19.2.3)': + '@react-stately/menu@3.9.11(react@19.2.4)': dependencies: - '@react-stately/overlays': 3.6.21(react@19.2.3) - '@react-types/menu': 3.10.5(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-stately/overlays': 3.6.23(react@19.2.4) + '@react-types/menu': 3.10.7(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/numberfield@3.10.3(react@19.2.3)': + '@react-stately/numberfield@3.11.0(react@19.2.4)': dependencies: '@internationalized/number': 3.6.5 - '@react-stately/form': 3.2.2(react@19.2.3) - '@react-stately/utils': 3.11.0(react@19.2.3) - '@react-types/numberfield': 3.8.16(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-stately/form': 3.2.4(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/numberfield': 3.8.18(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/overlays@3.6.21(react@19.2.3)': + '@react-stately/overlays@3.6.23(react@19.2.4)': dependencies: - '@react-stately/utils': 3.11.0(react@19.2.3) - '@react-types/overlays': 3.9.2(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/overlays': 3.9.4(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/radio@3.11.3(react@19.2.3)': + '@react-stately/radio@3.11.5(react@19.2.4)': dependencies: - '@react-stately/form': 3.2.2(react@19.2.3) - '@react-stately/utils': 3.11.0(react@19.2.3) - '@react-types/radio': 3.9.2(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-stately/form': 3.2.4(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/radio': 3.9.4(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/searchfield@3.5.17(react@19.2.3)': + '@react-stately/searchfield@3.5.19(react@19.2.4)': dependencies: - '@react-stately/utils': 3.11.0(react@19.2.3) - '@react-types/searchfield': 3.6.6(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/searchfield': 3.6.8(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/select@3.9.0(react@19.2.3)': + '@react-stately/select@3.9.2(react@19.2.4)': dependencies: - '@react-stately/form': 3.2.2(react@19.2.3) - '@react-stately/list': 3.13.2(react@19.2.3) - '@react-stately/overlays': 3.6.21(react@19.2.3) - '@react-stately/utils': 3.11.0(react@19.2.3) - '@react-types/select': 3.12.0(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-stately/form': 3.2.4(react@19.2.4) + '@react-stately/list': 3.13.4(react@19.2.4) + '@react-stately/overlays': 3.6.23(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/select': 3.12.2(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/selection@3.20.7(react@19.2.3)': + '@react-stately/selection@3.20.9(react@19.2.4)': dependencies: - '@react-stately/collections': 3.12.8(react@19.2.3) - '@react-stately/utils': 3.11.0(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-stately/collections': 3.12.10(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/slider@3.7.3(react@19.2.3)': + '@react-stately/slider@3.7.5(react@19.2.4)': dependencies: - '@react-stately/utils': 3.11.0(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@react-types/slider': 3.8.2(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@react-types/slider': 3.8.4(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/table@3.15.2(patch_hash=5ac384399a7b8e18c4e19f25e434b2f2f27fbd45e7a91cdeb30408330b7243b4)(react@19.2.3)': + '@react-stately/table@3.15.4(patch_hash=5ac384399a7b8e18c4e19f25e434b2f2f27fbd45e7a91cdeb30408330b7243b4)(react@19.2.4)': dependencies: - '@react-stately/collections': 3.12.8(react@19.2.3) + '@react-stately/collections': 3.12.10(react@19.2.4) '@react-stately/flags': 3.1.2 - '@react-stately/grid': 3.11.7(react@19.2.3) - '@react-stately/selection': 3.20.7(react@19.2.3) - '@react-stately/utils': 3.11.0(react@19.2.3) - '@react-types/grid': 3.3.6(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@react-types/table': 3.13.4(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-stately/grid': 3.11.9(react@19.2.4) + '@react-stately/selection': 3.20.9(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/grid': 3.3.8(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@react-types/table': 3.13.6(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/tabs@3.8.7(react@19.2.3)': + '@react-stately/tabs@3.8.9(react@19.2.4)': dependencies: - '@react-stately/list': 3.13.2(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@react-types/tabs': 3.3.20(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-stately/list': 3.13.4(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@react-types/tabs': 3.3.22(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/toast@3.1.2(react@19.2.3)': + '@react-stately/toast@3.1.3(react@19.2.4)': dependencies: - '@swc/helpers': 0.5.18 - react: 19.2.3 - use-sync-external-store: 1.6.0(react@19.2.3) + '@swc/helpers': 0.5.19 + react: 19.2.4 + use-sync-external-store: 1.6.0(react@19.2.4) - '@react-stately/toggle@3.9.3(react@19.2.3)': + '@react-stately/toggle@3.9.5(react@19.2.4)': dependencies: - '@react-stately/utils': 3.11.0(react@19.2.3) - '@react-types/checkbox': 3.10.2(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/checkbox': 3.10.4(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/tooltip@3.5.9(react@19.2.3)': + '@react-stately/tooltip@3.5.11(react@19.2.4)': dependencies: - '@react-stately/overlays': 3.6.21(react@19.2.3) - '@react-types/tooltip': 3.5.0(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-stately/overlays': 3.6.23(react@19.2.4) + '@react-types/tooltip': 3.5.2(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/tree@3.9.4(react@19.2.3)': + '@react-stately/tree@3.9.6(react@19.2.4)': dependencies: - '@react-stately/collections': 3.12.8(react@19.2.3) - '@react-stately/selection': 3.20.7(react@19.2.3) - '@react-stately/utils': 3.11.0(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@react-stately/collections': 3.12.10(react@19.2.4) + '@react-stately/selection': 3.20.9(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/utils@3.11.0(react@19.2.3)': + '@react-stately/utils@3.11.0(react@19.2.4)': dependencies: - '@swc/helpers': 0.5.18 - react: 19.2.3 + '@swc/helpers': 0.5.19 + react: 19.2.4 - '@react-stately/virtualizer@4.4.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@react-stately/virtualizer@4.4.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - '@swc/helpers': 0.5.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@react-types/shared': 3.33.1(react@19.2.4) + '@swc/helpers': 0.5.19 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - '@react-types/autocomplete@3.0.0-alpha.36(react@19.2.3)': + '@react-types/autocomplete@3.0.0-alpha.38(react@19.2.4)': dependencies: - '@react-types/combobox': 3.13.10(react@19.2.3) - '@react-types/searchfield': 3.6.6(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/combobox': 3.14.0(react@19.2.4) + '@react-types/searchfield': 3.6.8(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/breadcrumbs@3.7.17(react@19.2.3)': + '@react-types/breadcrumbs@3.7.19(react@19.2.4)': dependencies: - '@react-types/link': 3.6.5(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/link': 3.6.7(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/button@3.14.1(react@19.2.3)': + '@react-types/button@3.15.1(react@19.2.4)': dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/calendar@3.8.1(react@19.2.3)': + '@react-types/calendar@3.8.3(react@19.2.4)': dependencies: - '@internationalized/date': 3.10.1 - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@internationalized/date': 3.12.0 + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/checkbox@3.10.2(react@19.2.3)': + '@react-types/checkbox@3.10.4(react@19.2.4)': dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/color@3.1.2(react@19.2.3)': + '@react-types/color@3.1.4(react@19.2.4)': dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - '@react-types/slider': 3.8.2(react@19.2.3) - react: 19.2.3 + '@react-types/shared': 3.33.1(react@19.2.4) + '@react-types/slider': 3.8.4(react@19.2.4) + react: 19.2.4 - '@react-types/combobox@3.13.10(react@19.2.3)': + '@react-types/combobox@3.14.0(react@19.2.4)': dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/datepicker@3.13.3(react@19.2.3)': + '@react-types/datepicker@3.13.5(react@19.2.4)': dependencies: - '@internationalized/date': 3.10.1 - '@react-types/calendar': 3.8.1(react@19.2.3) - '@react-types/overlays': 3.9.2(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@internationalized/date': 3.12.0 + '@react-types/calendar': 3.8.3(react@19.2.4) + '@react-types/overlays': 3.9.4(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/dialog@3.5.22(react@19.2.3)': + '@react-types/dialog@3.5.24(react@19.2.4)': dependencies: - '@react-types/overlays': 3.9.2(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/overlays': 3.9.4(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/form@3.7.16(react@19.2.3)': + '@react-types/form@3.7.18(react@19.2.4)': dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/grid@3.3.6(react@19.2.3)': + '@react-types/grid@3.3.8(react@19.2.4)': dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/link@3.6.5(react@19.2.3)': + '@react-types/link@3.6.7(react@19.2.4)': dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/listbox@3.7.4(react@19.2.3)': + '@react-types/listbox@3.7.6(react@19.2.4)': dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/menu@3.10.5(react@19.2.3)': + '@react-types/menu@3.10.7(react@19.2.4)': dependencies: - '@react-types/overlays': 3.9.2(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/overlays': 3.9.4(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/meter@3.4.13(react@19.2.3)': + '@react-types/meter@3.4.15(react@19.2.4)': dependencies: - '@react-types/progress': 3.5.16(react@19.2.3) - react: 19.2.3 + '@react-types/progress': 3.5.18(react@19.2.4) + react: 19.2.4 - '@react-types/numberfield@3.8.16(react@19.2.3)': + '@react-types/numberfield@3.8.18(react@19.2.4)': dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/overlays@3.9.2(react@19.2.3)': + '@react-types/overlays@3.9.4(react@19.2.4)': dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/progress@3.5.16(react@19.2.3)': + '@react-types/progress@3.5.18(react@19.2.4)': dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/radio@3.9.2(react@19.2.3)': + '@react-types/radio@3.9.4(react@19.2.4)': dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/searchfield@3.6.6(react@19.2.3)': + '@react-types/searchfield@3.6.8(react@19.2.4)': dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - '@react-types/textfield': 3.12.6(react@19.2.3) - react: 19.2.3 + '@react-types/shared': 3.33.1(react@19.2.4) + '@react-types/textfield': 3.12.8(react@19.2.4) + react: 19.2.4 - '@react-types/select@3.12.0(react@19.2.3)': + '@react-types/select@3.12.2(react@19.2.4)': dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/shared@3.32.1(react@19.2.3)': + '@react-types/shared@3.33.1(react@19.2.4)': dependencies: - react: 19.2.3 + react: 19.2.4 - '@react-types/slider@3.8.2(react@19.2.3)': + '@react-types/slider@3.8.4(react@19.2.4)': dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/switch@3.5.15(react@19.2.3)': + '@react-types/switch@3.5.17(react@19.2.4)': dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/table@3.13.4(react@19.2.3)': + '@react-types/table@3.13.6(react@19.2.4)': dependencies: - '@react-types/grid': 3.3.6(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/grid': 3.3.8(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/tabs@3.3.20(react@19.2.3)': + '@react-types/tabs@3.3.22(react@19.2.4)': dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/textfield@3.12.6(react@19.2.3)': + '@react-types/textfield@3.12.8(react@19.2.4)': dependencies: - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@react-types/tooltip@3.5.0(react@19.2.3)': + '@react-types/tooltip@3.5.2(react@19.2.4)': dependencies: - '@react-types/overlays': 3.9.2(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 + '@react-types/overlays': 3.9.4(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 - '@rolldown/pluginutils@1.0.0-beta.53': {} + '@rolldown/pluginutils@1.0.0-rc.3': {} - '@rollup/plugin-babel@6.1.0(@babel/core@7.28.5)(@types/babel__core@7.20.5)(rollup@4.55.1)': + '@rollup/plugin-babel@6.1.0(@babel/core@7.29.0)(@types/babel__core@7.20.5)(rollup@4.59.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-imports': 7.27.1 - '@rollup/pluginutils': 5.3.0(rollup@4.55.1) + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) optionalDependencies: '@types/babel__core': 7.20.5 - rollup: 4.55.1 + rollup: 4.59.0 transitivePeerDependencies: - supports-color - '@rollup/plugin-commonjs@25.0.8(rollup@4.55.1)': + '@rollup/plugin-commonjs@25.0.8(rollup@4.59.0)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.55.1) + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) commondir: 1.0.1 estree-walker: 2.0.2 glob: 8.1.0 is-reference: 1.2.1 magic-string: 0.30.21 optionalDependencies: - rollup: 4.55.1 + rollup: 4.59.0 - '@rollup/plugin-image@3.0.3(rollup@4.55.1)': + '@rollup/plugin-image@3.0.3(rollup@4.59.0)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.55.1) + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) mini-svg-data-uri: 1.4.4 optionalDependencies: - rollup: 4.55.1 + rollup: 4.59.0 - '@rollup/plugin-json@6.1.0(rollup@4.55.1)': + '@rollup/plugin-json@6.1.0(rollup@4.59.0)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.55.1) + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) optionalDependencies: - rollup: 4.55.1 + rollup: 4.59.0 - '@rollup/plugin-node-resolve@15.3.1(rollup@4.55.1)': + '@rollup/plugin-node-resolve@15.3.1(rollup@4.59.0)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.55.1) + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 resolve: 1.22.11 optionalDependencies: - rollup: 4.55.1 + rollup: 4.59.0 - '@rollup/plugin-typescript@12.3.0(rollup@4.55.1)(tslib@2.8.1)(typescript@5.9.3)': + '@rollup/plugin-typescript@12.3.0(rollup@4.59.0)(tslib@2.8.1)(typescript@5.9.3)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.55.1) + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) resolve: 1.22.11 typescript: 5.9.3 optionalDependencies: - rollup: 4.55.1 + rollup: 4.59.0 tslib: 2.8.1 '@rollup/pluginutils@4.2.1': @@ -15273,87 +15502,87 @@ snapshots: estree-walker: 2.0.2 picomatch: 2.3.1 - '@rollup/pluginutils@5.3.0(rollup@4.55.1)': + '@rollup/pluginutils@5.3.0(rollup@4.59.0)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 picomatch: 4.0.3 optionalDependencies: - rollup: 4.55.1 + rollup: 4.59.0 - '@rollup/rollup-android-arm-eabi@4.55.1': + '@rollup/rollup-android-arm-eabi@4.59.0': optional: true - '@rollup/rollup-android-arm64@4.55.1': + '@rollup/rollup-android-arm64@4.59.0': optional: true - '@rollup/rollup-darwin-arm64@4.55.1': + '@rollup/rollup-darwin-arm64@4.59.0': optional: true - '@rollup/rollup-darwin-x64@4.55.1': + '@rollup/rollup-darwin-x64@4.59.0': optional: true - '@rollup/rollup-freebsd-arm64@4.55.1': + '@rollup/rollup-freebsd-arm64@4.59.0': optional: true - '@rollup/rollup-freebsd-x64@4.55.1': + '@rollup/rollup-freebsd-x64@4.59.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.55.1': + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.55.1': + '@rollup/rollup-linux-arm-musleabihf@4.59.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.55.1': + '@rollup/rollup-linux-arm64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.55.1': + '@rollup/rollup-linux-arm64-musl@4.59.0': optional: true - '@rollup/rollup-linux-loong64-gnu@4.55.1': + '@rollup/rollup-linux-loong64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-loong64-musl@4.55.1': + '@rollup/rollup-linux-loong64-musl@4.59.0': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.55.1': + '@rollup/rollup-linux-ppc64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-ppc64-musl@4.55.1': + '@rollup/rollup-linux-ppc64-musl@4.59.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.55.1': + '@rollup/rollup-linux-riscv64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-riscv64-musl@4.55.1': + '@rollup/rollup-linux-riscv64-musl@4.59.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.55.1': + '@rollup/rollup-linux-s390x-gnu@4.59.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.55.1': + '@rollup/rollup-linux-x64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-x64-musl@4.55.1': + '@rollup/rollup-linux-x64-musl@4.59.0': optional: true - '@rollup/rollup-openbsd-x64@4.55.1': + '@rollup/rollup-openbsd-x64@4.59.0': optional: true - '@rollup/rollup-openharmony-arm64@4.55.1': + '@rollup/rollup-openharmony-arm64@4.59.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.55.1': + '@rollup/rollup-win32-arm64-msvc@4.59.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.55.1': + '@rollup/rollup-win32-ia32-msvc@4.59.0': optional: true - '@rollup/rollup-win32-x64-gnu@4.55.1': + '@rollup/rollup-win32-x64-gnu@4.59.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.55.1': + '@rollup/rollup-win32-x64-msvc@4.59.0': optional: true '@rspack/binding-darwin-arm64@1.6.8': @@ -15401,17 +15630,17 @@ snapshots: '@rspack/binding-win32-ia32-msvc': 1.6.8 '@rspack/binding-win32-x64-msvc': 1.6.8 - '@rspack/core@1.6.8(@swc/helpers@0.5.18)': + '@rspack/core@1.6.8(@swc/helpers@0.5.19)': dependencies: '@module-federation/runtime-tools': 0.21.6 '@rspack/binding': 1.6.8 '@rspack/lite-tapable': 1.1.0 optionalDependencies: - '@swc/helpers': 0.5.18 + '@swc/helpers': 0.5.19 '@rspack/lite-tapable@1.1.0': {} - '@sinclair/typebox@0.34.47': {} + '@sinclair/typebox@0.34.48': {} '@sindresorhus/is@4.6.0': {} @@ -15423,15 +15652,15 @@ snapshots: '@standard-schema/utils@0.3.0': {} - '@storybook/addon-docs@10.1.11(@types/react@19.2.7)(esbuild@0.27.2)(rollup@4.55.1)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2))': + '@storybook/addon-docs@10.2.16(@types/react@19.2.14)(esbuild@0.27.3)(rollup@4.59.0)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3))': dependencies: - '@mdx-js/react': 3.1.1(@types/react@19.2.7)(react@19.2.3) - '@storybook/csf-plugin': 10.1.11(esbuild@0.27.2)(rollup@4.55.1)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2)) - '@storybook/icons': 2.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@storybook/react-dom-shim': 10.1.11(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - storybook: 10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.4) + '@storybook/csf-plugin': 10.2.16(esbuild@0.27.3)(rollup@4.59.0)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3)) + '@storybook/icons': 2.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@storybook/react-dom-shim': 10.2.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + storybook: 10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) ts-dedent: 2.2.0 transitivePeerDependencies: - '@types/react' @@ -15440,191 +15669,123 @@ snapshots: - vite - webpack - '@storybook/builder-vite@10.1.11(esbuild@0.27.2)(rollup@4.55.1)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.7.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2))': - dependencies: - '@storybook/csf-plugin': 10.1.11(esbuild@0.27.2)(rollup@4.55.1)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.7.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2)) - '@vitest/mocker': 3.2.4(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) - storybook: 10.1.11(@testing-library/dom@10.4.1)(prettier@3.7.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - ts-dedent: 2.2.0 - vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) - transitivePeerDependencies: - - esbuild - - msw - - rollup - - webpack - - '@storybook/builder-vite@10.1.11(esbuild@0.27.2)(rollup@4.55.1)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2))': + '@storybook/builder-vite@10.2.16(esbuild@0.27.3)(rollup@4.59.0)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3))': dependencies: - '@storybook/csf-plugin': 10.1.11(esbuild@0.27.2)(rollup@4.55.1)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2)) - '@vitest/mocker': 3.2.4(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) - storybook: 10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@storybook/csf-plugin': 10.2.16(esbuild@0.27.3)(rollup@4.59.0)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3)) + storybook: 10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) ts-dedent: 2.2.0 - vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - esbuild - - msw - rollup - webpack - '@storybook/csf-plugin@10.1.11(esbuild@0.27.2)(rollup@4.55.1)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.7.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2))': - dependencies: - storybook: 10.1.11(@testing-library/dom@10.4.1)(prettier@3.7.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - unplugin: 2.3.11 - optionalDependencies: - esbuild: 0.27.2 - rollup: 4.55.1 - vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) - webpack: 5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2) - - '@storybook/csf-plugin@10.1.11(esbuild@0.27.2)(rollup@4.55.1)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2))': + '@storybook/csf-plugin@10.2.16(esbuild@0.27.3)(rollup@4.59.0)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3))': dependencies: - storybook: 10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + storybook: 10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) unplugin: 2.3.11 optionalDependencies: - esbuild: 0.27.2 - rollup: 4.55.1 - vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) - webpack: 5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2) + esbuild: 0.27.3 + rollup: 4.59.0 + vite: 7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + webpack: 5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3) '@storybook/global@5.0.0': {} - '@storybook/icons@2.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@storybook/react-dom-shim@10.1.11(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.7.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': + '@storybook/icons@2.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - storybook: 10.1.11(@testing-library/dom@10.4.1)(prettier@3.7.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - '@storybook/react-dom-shim@10.1.11(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': + '@storybook/react-dom-shim@10.2.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': dependencies: - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - storybook: 10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - - '@storybook/react-vite@10.1.11(esbuild@0.27.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.55.1)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.7.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2))': - dependencies: - '@joshwooding/vite-plugin-react-docgen-typescript': 0.6.3(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) - '@rollup/pluginutils': 5.3.0(rollup@4.55.1) - '@storybook/builder-vite': 10.1.11(esbuild@0.27.2)(rollup@4.55.1)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.7.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2)) - '@storybook/react': 10.1.11(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.7.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3) - empathic: 2.0.0 - magic-string: 0.30.21 - react: 19.2.3 - react-docgen: 8.0.2 - react-dom: 19.2.3(react@19.2.3) - resolve: 1.22.11 - storybook: 10.1.11(@testing-library/dom@10.4.1)(prettier@3.7.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - tsconfig-paths: 4.2.0 - vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) - transitivePeerDependencies: - - esbuild - - msw - - rollup - - supports-color - - typescript - - webpack + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + storybook: 10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@storybook/react-vite@10.1.11(esbuild@0.27.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.55.1)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2))': + '@storybook/react-vite@10.2.16(esbuild@0.27.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.59.0)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3))': dependencies: - '@joshwooding/vite-plugin-react-docgen-typescript': 0.6.3(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) - '@rollup/pluginutils': 5.3.0(rollup@4.55.1) - '@storybook/builder-vite': 10.1.11(esbuild@0.27.2)(rollup@4.55.1)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2)) - '@storybook/react': 10.1.11(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3) + '@joshwooding/vite-plugin-react-docgen-typescript': 0.6.4(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) + '@storybook/builder-vite': 10.2.16(esbuild@0.27.3)(rollup@4.59.0)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3)) + '@storybook/react': 10.2.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) empathic: 2.0.0 magic-string: 0.30.21 - react: 19.2.3 + react: 19.2.4 react-docgen: 8.0.2 - react-dom: 19.2.3(react@19.2.3) + react-dom: 19.2.4(react@19.2.4) resolve: 1.22.11 - storybook: 10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + storybook: 10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) tsconfig-paths: 4.2.0 - vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - esbuild - - msw - rollup - supports-color - typescript - webpack - '@storybook/react@10.1.11(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.7.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)': - dependencies: - '@storybook/global': 5.0.0 - '@storybook/react-dom-shim': 10.1.11(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.7.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) - react: 19.2.3 - react-docgen: 8.0.2 - react-dom: 19.2.3(react@19.2.3) - storybook: 10.1.11(@testing-library/dom@10.4.1)(prettier@3.7.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@storybook/react@10.1.11(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)': + '@storybook/react@10.2.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)': dependencies: '@storybook/global': 5.0.0 - '@storybook/react-dom-shim': 10.1.11(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) - react: 19.2.3 + '@storybook/react-dom-shim': 10.2.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) + react: 19.2.4 react-docgen: 8.0.2 - react-dom: 19.2.3(react@19.2.3) - storybook: 10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react-dom: 19.2.4(react@19.2.4) + storybook: 10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.28.5)': + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 - '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.28.5)': + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 - '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.28.5)': + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 - '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.28.5)': + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 - '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.28.5)': + '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 - '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.28.5)': + '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 - '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.28.5)': + '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 - '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.28.5)': + '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 - '@svgr/babel-preset@8.1.0(@babel/core@7.28.5)': + '@svgr/babel-preset@8.1.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.28.5) - '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.28.5) - '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.28.5) - '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.28.5) - '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.28.5) - '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.28.5) - '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.28.5) - '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.29.0) + '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.29.0) '@svgr/core@8.1.0(typescript@5.9.3)': dependencies: - '@babel/core': 7.28.5 - '@svgr/babel-preset': 8.1.0(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@svgr/babel-preset': 8.1.0(@babel/core@7.29.0) camelcase: 6.3.0 cosmiconfig: 8.3.6(typescript@5.9.3) snake-case: 3.0.4 @@ -15634,13 +15795,13 @@ snapshots: '@svgr/hast-util-to-babel-ast@8.0.0': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 entities: 4.5.0 '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.9.3))': dependencies: - '@babel/core': 7.28.5 - '@svgr/babel-preset': 8.1.0(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@svgr/babel-preset': 8.1.0(@babel/core@7.29.0) '@svgr/core': 8.1.0(typescript@5.9.3) '@svgr/hast-util-to-babel-ast': 8.0.0 svg-parser: 2.0.4 @@ -15652,17 +15813,17 @@ snapshots: '@svgr/core': 8.1.0(typescript@5.9.3) cosmiconfig: 8.3.6(typescript@5.9.3) deepmerge: 4.3.1 - svgo: 3.3.2 + svgo: 3.3.3 transitivePeerDependencies: - typescript '@svgr/webpack@8.1.0(typescript@5.9.3)': dependencies: - '@babel/core': 7.28.5 - '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.28.5) - '@babel/preset-env': 7.28.5(@babel/core@7.28.5) - '@babel/preset-react': 7.28.5(@babel/core@7.28.5) - '@babel/preset-typescript': 7.28.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.29.0) + '@babel/preset-env': 7.29.0(@babel/core@7.29.0) + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) '@svgr/core': 8.1.0(typescript@5.9.3) '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3)) '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3))(typescript@5.9.3) @@ -15670,19 +15831,19 @@ snapshots: - supports-color - typescript - '@swc-node/core@1.14.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)': + '@swc-node/core@1.14.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)': dependencies: - '@swc/core': 1.15.8(@swc/helpers@0.5.18) + '@swc/core': 1.15.8(@swc/helpers@0.5.19) '@swc/types': 0.1.25 - '@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3)': + '@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3)': dependencies: - '@swc-node/core': 1.14.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25) + '@swc-node/core': 1.14.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25) '@swc-node/sourcemap-support': 0.6.1 - '@swc/core': 1.15.8(@swc/helpers@0.5.18) + '@swc/core': 1.15.8(@swc/helpers@0.5.19) colorette: 2.0.20 debug: 4.4.3 - oxc-resolver: 11.16.2 + oxc-resolver: 11.19.1 pirates: 4.0.7 tslib: 2.8.1 typescript: 5.9.3 @@ -15725,7 +15886,7 @@ snapshots: '@swc/core-win32-x64-msvc@1.15.8': optional: true - '@swc/core@1.15.8(@swc/helpers@0.5.18)': + '@swc/core@1.15.8(@swc/helpers@0.5.19)': dependencies: '@swc/counter': 0.1.3 '@swc/types': 0.1.25 @@ -15740,11 +15901,11 @@ snapshots: '@swc/core-win32-arm64-msvc': 1.15.8 '@swc/core-win32-ia32-msvc': 1.15.8 '@swc/core-win32-x64-msvc': 1.15.8 - '@swc/helpers': 0.5.18 + '@swc/helpers': 0.5.19 '@swc/counter@0.1.3': {} - '@swc/helpers@0.5.18': + '@swc/helpers@0.5.19': dependencies: tslib: 2.8.1 @@ -15756,183 +15917,181 @@ snapshots: dependencies: defer-to-connect: 2.0.1 - '@tailwindcss/node@4.1.18': + '@tailwindcss/node@4.2.1': dependencies: '@jridgewell/remapping': 2.3.5 - enhanced-resolve: 5.18.4 + enhanced-resolve: 5.20.0 jiti: 2.6.1 - lightningcss: 1.30.2 + lightningcss: 1.31.1 magic-string: 0.30.21 source-map-js: 1.2.1 - tailwindcss: 4.1.18 + tailwindcss: 4.2.1 - '@tailwindcss/oxide-android-arm64@4.1.18': + '@tailwindcss/oxide-android-arm64@4.2.1': optional: true - '@tailwindcss/oxide-darwin-arm64@4.1.18': + '@tailwindcss/oxide-darwin-arm64@4.2.1': optional: true - '@tailwindcss/oxide-darwin-x64@4.1.18': + '@tailwindcss/oxide-darwin-x64@4.2.1': optional: true - '@tailwindcss/oxide-freebsd-x64@4.1.18': + '@tailwindcss/oxide-freebsd-x64@4.2.1': optional: true - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18': + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.1': optional: true - '@tailwindcss/oxide-linux-arm64-gnu@4.1.18': + '@tailwindcss/oxide-linux-arm64-gnu@4.2.1': optional: true - '@tailwindcss/oxide-linux-arm64-musl@4.1.18': + '@tailwindcss/oxide-linux-arm64-musl@4.2.1': optional: true - '@tailwindcss/oxide-linux-x64-gnu@4.1.18': + '@tailwindcss/oxide-linux-x64-gnu@4.2.1': optional: true - '@tailwindcss/oxide-linux-x64-musl@4.1.18': + '@tailwindcss/oxide-linux-x64-musl@4.2.1': optional: true - '@tailwindcss/oxide-wasm32-wasi@4.1.18': + '@tailwindcss/oxide-wasm32-wasi@4.2.1': optional: true - '@tailwindcss/oxide-win32-arm64-msvc@4.1.18': + '@tailwindcss/oxide-win32-arm64-msvc@4.2.1': optional: true - '@tailwindcss/oxide-win32-x64-msvc@4.1.18': + '@tailwindcss/oxide-win32-x64-msvc@4.2.1': optional: true - '@tailwindcss/oxide@4.1.18': + '@tailwindcss/oxide@4.2.1': optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.1.18 - '@tailwindcss/oxide-darwin-arm64': 4.1.18 - '@tailwindcss/oxide-darwin-x64': 4.1.18 - '@tailwindcss/oxide-freebsd-x64': 4.1.18 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.18 - '@tailwindcss/oxide-linux-arm64-gnu': 4.1.18 - '@tailwindcss/oxide-linux-arm64-musl': 4.1.18 - '@tailwindcss/oxide-linux-x64-gnu': 4.1.18 - '@tailwindcss/oxide-linux-x64-musl': 4.1.18 - '@tailwindcss/oxide-wasm32-wasi': 4.1.18 - '@tailwindcss/oxide-win32-arm64-msvc': 4.1.18 - '@tailwindcss/oxide-win32-x64-msvc': 4.1.18 - - '@tailwindcss/typography@0.5.19(tailwindcss@4.1.18)': + '@tailwindcss/oxide-android-arm64': 4.2.1 + '@tailwindcss/oxide-darwin-arm64': 4.2.1 + '@tailwindcss/oxide-darwin-x64': 4.2.1 + '@tailwindcss/oxide-freebsd-x64': 4.2.1 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.1 + '@tailwindcss/oxide-linux-arm64-gnu': 4.2.1 + '@tailwindcss/oxide-linux-arm64-musl': 4.2.1 + '@tailwindcss/oxide-linux-x64-gnu': 4.2.1 + '@tailwindcss/oxide-linux-x64-musl': 4.2.1 + '@tailwindcss/oxide-wasm32-wasi': 4.2.1 + '@tailwindcss/oxide-win32-arm64-msvc': 4.2.1 + '@tailwindcss/oxide-win32-x64-msvc': 4.2.1 + + '@tailwindcss/typography@0.5.19(tailwindcss@4.2.1)': dependencies: postcss-selector-parser: 6.0.10 - tailwindcss: 4.1.18 + tailwindcss: 4.2.1 - '@tailwindcss/vite@4.1.18(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@tailwindcss/vite@4.2.1(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - '@tailwindcss/node': 4.1.18 - '@tailwindcss/oxide': 4.1.18 - tailwindcss: 4.1.18 - vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + '@tailwindcss/node': 4.2.1 + '@tailwindcss/oxide': 4.2.1 + tailwindcss: 4.2.1 + vite: 7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - '@tanstack/db-ivm@0.1.14(typescript@5.9.3)': + '@tanstack/db-ivm@0.1.17(typescript@5.9.3)': dependencies: fractional-indexing: 3.2.0 sorted-btree: 1.8.1 typescript: 5.9.3 - '@tanstack/db@0.5.16(typescript@5.9.3)': + '@tanstack/db@0.5.30(typescript@5.9.3)': dependencies: '@standard-schema/spec': 1.1.0 - '@tanstack/db-ivm': 0.1.14(typescript@5.9.3) - '@tanstack/pacer-lite': 0.1.1 + '@tanstack/db-ivm': 0.1.17(typescript@5.9.3) + '@tanstack/pacer-lite': 0.2.1 typescript: 5.9.3 - '@tanstack/eslint-plugin-router@1.141.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@tanstack/eslint-plugin-router@1.161.4(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/utils': 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) transitivePeerDependencies: - supports-color - typescript - '@tanstack/history@1.145.7': {} + '@tanstack/history@1.161.4': {} - '@tanstack/pacer-lite@0.1.1': {} + '@tanstack/pacer-lite@0.2.1': {} - '@tanstack/query-core@5.90.16': {} + '@tanstack/query-core@5.90.20': {} - '@tanstack/query-devtools@5.92.0': {} + '@tanstack/query-devtools@5.93.0': {} - '@tanstack/react-db@0.1.60(react@19.2.3)(typescript@5.9.3)': + '@tanstack/react-db@0.1.74(react@19.2.4)(typescript@5.9.3)': dependencies: - '@tanstack/db': 0.5.16(typescript@5.9.3) - react: 19.2.3 - use-sync-external-store: 1.6.0(react@19.2.3) + '@tanstack/db': 0.5.30(typescript@5.9.3) + react: 19.2.4 + use-sync-external-store: 1.6.0(react@19.2.4) transitivePeerDependencies: - typescript - '@tanstack/react-query-devtools@5.91.2(@tanstack/react-query@5.90.16(react@19.2.3))(react@19.2.3)': + '@tanstack/react-query-devtools@5.91.3(@tanstack/react-query@5.90.21(react@19.2.4))(react@19.2.4)': dependencies: - '@tanstack/query-devtools': 5.92.0 - '@tanstack/react-query': 5.90.16(react@19.2.3) - react: 19.2.3 + '@tanstack/query-devtools': 5.93.0 + '@tanstack/react-query': 5.90.21(react@19.2.4) + react: 19.2.4 - '@tanstack/react-query@5.90.16(react@19.2.3)': + '@tanstack/react-query@5.90.21(react@19.2.4)': dependencies: - '@tanstack/query-core': 5.90.16 - react: 19.2.3 + '@tanstack/query-core': 5.90.20 + react: 19.2.4 - '@tanstack/react-router-devtools@1.145.7(@tanstack/react-router@1.145.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.145.7)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.10)': + '@tanstack/react-router-devtools@1.166.2(@tanstack/react-router@1.166.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@tanstack/router-core@1.166.2)(csstype@3.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@tanstack/react-router': 1.145.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-devtools-core': 1.145.7(@tanstack/router-core@1.145.7)(csstype@3.2.3)(solid-js@1.9.10) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@tanstack/react-router': 1.166.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tanstack/router-devtools-core': 1.166.2(@tanstack/router-core@1.166.2)(csstype@3.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@tanstack/router-core': 1.145.7 + '@tanstack/router-core': 1.166.2 transitivePeerDependencies: - csstype - - solid-js - '@tanstack/react-router@1.145.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-router@1.166.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@tanstack/history': 1.145.7 - '@tanstack/react-store': 0.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-core': 1.145.7 - isbot: 5.1.32 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@tanstack/history': 1.161.4 + '@tanstack/react-store': 0.9.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tanstack/router-core': 1.166.2 + isbot: 5.1.35 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/react-store@0.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-store@0.9.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@tanstack/store': 0.8.0 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - use-sync-external-store: 1.6.0(react@19.2.3) + '@tanstack/store': 0.9.1 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + use-sync-external-store: 1.6.0(react@19.2.4) - '@tanstack/router-core@1.145.7': + '@tanstack/router-core@1.166.2': dependencies: - '@tanstack/history': 1.145.7 - '@tanstack/store': 0.8.0 + '@tanstack/history': 1.161.4 + '@tanstack/store': 0.9.1 cookie-es: 2.0.0 - seroval: 1.4.2 - seroval-plugins: 1.4.2(seroval@1.4.2) + seroval: 1.5.0 + seroval-plugins: 1.5.0(seroval@1.5.0) tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/router-devtools-core@1.145.7(@tanstack/router-core@1.145.7)(csstype@3.2.3)(solid-js@1.9.10)': + '@tanstack/router-devtools-core@1.166.2(@tanstack/router-core@1.166.2)(csstype@3.2.3)': dependencies: - '@tanstack/router-core': 1.145.7 + '@tanstack/router-core': 1.166.2 clsx: 2.1.1 goober: 2.1.18(csstype@3.2.3) - solid-js: 1.9.10 tiny-invariant: 1.3.3 optionalDependencies: csstype: 3.2.3 - '@tanstack/router-generator@1.145.7': + '@tanstack/router-generator@1.166.2': dependencies: - '@tanstack/router-core': 1.145.7 - '@tanstack/router-utils': 1.143.11 - '@tanstack/virtual-file-routes': 1.145.4 - prettier: 3.7.4 + '@tanstack/router-core': 1.166.2 + '@tanstack/router-utils': 1.161.4 + '@tanstack/virtual-file-routes': 1.161.4 + prettier: 3.8.1 recast: 0.23.11 source-map: 0.7.6 tsx: 4.21.0 @@ -15940,49 +16099,50 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.145.10(@tanstack/react-router@1.145.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2))': - dependencies: - '@babel/core': 7.28.5 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5) - '@babel/template': 7.27.2 - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 - '@tanstack/router-core': 1.145.7 - '@tanstack/router-generator': 1.145.7 - '@tanstack/router-utils': 1.143.11 - '@tanstack/virtual-file-routes': 1.145.4 - babel-dead-code-elimination: 1.0.11 + '@tanstack/router-plugin@1.166.2(@tanstack/react-router@1.166.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3))': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@tanstack/router-core': 1.166.2 + '@tanstack/router-generator': 1.166.2 + '@tanstack/router-utils': 1.161.4 + '@tanstack/virtual-file-routes': 1.161.4 chokidar: 3.6.0 unplugin: 2.3.11 zod: 3.25.76 optionalDependencies: - '@tanstack/react-router': 1.145.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) - webpack: 5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2) + '@tanstack/react-router': 1.166.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + vite: 7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + webpack: 5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3) transitivePeerDependencies: - supports-color - '@tanstack/router-utils@1.143.11': + '@tanstack/router-utils@1.161.4': dependencies: - '@babel/core': 7.28.5 - '@babel/generator': 7.28.5 - '@babel/parser': 7.28.5 + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 ansis: 4.2.0 - diff: 8.0.2 + babel-dead-code-elimination: 1.0.12 + diff: 8.0.3 pathe: 2.0.3 tinyglobby: 0.2.15 transitivePeerDependencies: - supports-color - '@tanstack/store@0.8.0': {} + '@tanstack/store@0.9.1': {} - '@tanstack/virtual-file-routes@1.145.4': {} + '@tanstack/virtual-file-routes@1.161.4': {} '@testing-library/dom@10.4.1': dependencies: '@babel/code-frame': 7.29.0 - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 '@types/aria-query': 5.0.4 aria-query: 5.3.0 dom-accessibility-api: 0.5.16 @@ -16003,8 +16163,6 @@ snapshots: dependencies: '@testing-library/dom': 10.4.1 - '@trysound/sax@0.2.0': {} - '@tsconfig/node10@1.0.12': {} '@tsconfig/node12@1.0.11': {} @@ -16028,30 +16186,30 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.28.0 '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 '@types/babel__traverse@7.28.0': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@types/cacheable-request@6.0.3': dependencies: - '@types/http-cache-semantics': 4.0.4 + '@types/http-cache-semantics': 4.2.0 '@types/keyv': 3.1.4 - '@types/node': 25.0.3 + '@types/node': 24.12.0 '@types/responselike': 1.0.3 '@types/chai@5.2.3': @@ -16099,6 +16257,10 @@ snapshots: dependencies: '@types/estree': 1.0.8 + '@types/esquery@1.5.4': + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx@1.0.5': dependencies: '@types/estree': 1.0.8 @@ -16107,25 +16269,25 @@ snapshots: '@types/fs-extra@9.0.13': dependencies: - '@types/node': 25.0.3 + '@types/node': 25.3.5 '@types/hast@3.0.4': dependencies: '@types/unist': 3.0.3 - '@types/http-cache-semantics@4.0.4': {} + '@types/http-cache-semantics@4.2.0': {} '@types/http-proxy@1.17.17': dependencies: - '@types/node': 25.0.3 + '@types/node': 25.3.5 '@types/json-schema@7.0.15': {} '@types/keyv@3.1.4': dependencies: - '@types/node': 25.0.3 + '@types/node': 24.12.0 - '@types/lodash@4.17.21': {} + '@types/lodash@4.17.24': {} '@types/mdast@4.0.4': dependencies: @@ -16135,56 +16297,47 @@ snapshots: '@types/ms@2.1.0': {} - '@types/node-fetch@2.6.13': - dependencies: - '@types/node': 25.0.3 - form-data: 4.0.5 - - '@types/node@18.19.130': - dependencies: - undici-types: 5.26.5 - - '@types/node@20.19.27': + '@types/node@20.19.37': dependencies: undici-types: 6.21.0 - '@types/node@22.19.3': + '@types/node@24.12.0': dependencies: - undici-types: 6.21.0 + undici-types: 7.16.0 - '@types/node@25.0.3': + '@types/node@25.3.5': dependencies: - undici-types: 7.16.0 + undici-types: 7.18.2 '@types/parse-json@4.0.2': {} - '@types/pg@8.16.0': + '@types/pg@8.18.0': dependencies: - '@types/node': 25.0.3 - pg-protocol: 1.11.0 + '@types/node': 25.3.5 + pg-protocol: 1.13.0 pg-types: 2.2.0 '@types/plist@3.0.5': dependencies: - '@types/node': 25.0.3 + '@types/node': 25.3.5 xmlbuilder: 15.1.1 optional: true - '@types/react-dom@19.2.3(@types/react@19.2.7)': + '@types/react-dom@19.2.3(@types/react@19.2.14)': dependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.14 - '@types/react-reconciler@0.28.9(@types/react@19.2.7)': + '@types/react-reconciler@0.28.9(@types/react@19.2.14)': dependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.14 - '@types/react-timeago@8.0.0(react@19.2.3)': + '@types/react-timeago@8.0.0(react@19.2.4)': dependencies: - react-timeago: 8.3.0(react@19.2.3) + react-timeago: 8.3.0(react@19.2.4) transitivePeerDependencies: - react - '@types/react@19.2.7': + '@types/react@19.2.14': dependencies: csstype: 3.2.3 @@ -16194,7 +16347,7 @@ snapshots: '@types/responselike@1.0.3': dependencies: - '@types/node': 25.0.3 + '@types/node': 24.12.0 '@types/semver@7.5.8': {} @@ -16205,24 +16358,30 @@ snapshots: '@types/verror@1.10.11': optional: true + '@types/webidl-conversions@7.0.3': {} + + '@types/whatwg-url@13.0.0': + dependencies: + '@types/webidl-conversions': 7.0.3 + '@types/ws@8.18.1': dependencies: - '@types/node': 25.0.3 + '@types/node': 25.3.5 optional: true '@types/yauzl@2.10.3': dependencies: - '@types/node': 25.0.3 + '@types/node': 24.12.0 optional: true - '@typescript-eslint/eslint-plugin@8.52.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.52.0 - '@typescript-eslint/type-utils': 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.52.0 + '@typescript-eslint/parser': 8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.56.1 + '@typescript-eslint/type-utils': 8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.56.1 eslint: 9.39.2(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 @@ -16231,41 +16390,41 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.52.0 - '@typescript-eslint/types': 8.52.0 - '@typescript-eslint/typescript-estree': 8.52.0(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.52.0 + '@typescript-eslint/scope-manager': 8.56.1 + '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.56.1 debug: 4.4.3 eslint: 9.39.2(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.52.0(typescript@5.9.3)': + '@typescript-eslint/project-service@8.56.1(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.52.0(typescript@5.9.3) - '@typescript-eslint/types': 8.52.0 + '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3) + '@typescript-eslint/types': 8.56.1 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.52.0': + '@typescript-eslint/scope-manager@8.56.1': dependencies: - '@typescript-eslint/types': 8.52.0 - '@typescript-eslint/visitor-keys': 8.52.0 + '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/visitor-keys': 8.56.1 - '@typescript-eslint/tsconfig-utils@8.52.0(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.56.1(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.52.0 - '@typescript-eslint/typescript-estree': 8.52.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 eslint: 9.39.2(jiti@2.6.1) ts-api-utils: 2.4.0(typescript@5.9.3) @@ -16273,60 +16432,60 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.52.0': {} + '@typescript-eslint/types@8.56.1': {} - '@typescript-eslint/typescript-estree@8.52.0(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.56.1(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.52.0(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.52.0(typescript@5.9.3) - '@typescript-eslint/types': 8.52.0 - '@typescript-eslint/visitor-keys': 8.52.0 + '@typescript-eslint/project-service': 8.56.1(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3) + '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/visitor-keys': 8.56.1 debug: 4.4.3 - minimatch: 9.0.5 - semver: 7.7.3 + minimatch: 10.2.4 + semver: 7.7.4 tinyglobby: 0.2.15 ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.52.0 - '@typescript-eslint/types': 8.52.0 - '@typescript-eslint/typescript-estree': 8.52.0(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.56.1 + '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.52.0': + '@typescript-eslint/visitor-keys@8.56.1': dependencies: - '@typescript-eslint/types': 8.52.0 - eslint-visitor-keys: 4.2.1 + '@typescript-eslint/types': 8.56.1 + eslint-visitor-keys: 5.0.1 - '@typescript/vfs@1.6.2(typescript@5.4.5)': + '@typescript/vfs@1.6.4(typescript@5.4.5)': dependencies: debug: 4.4.3 typescript: 5.4.5 transitivePeerDependencies: - supports-color - '@typespec/compiler@1.7.1(@types/node@25.0.3)': + '@typespec/compiler@1.9.0(@types/node@25.3.5)': dependencies: - '@babel/code-frame': 7.27.1 - '@inquirer/prompts': 8.1.0(@types/node@25.0.3) + '@babel/code-frame': 7.28.6 + '@inquirer/prompts': 8.3.0(@types/node@25.3.5) ajv: 8.17.1 change-case: 5.4.4 env-paths: 3.0.0 - globby: 16.0.0 + globby: 16.1.1 is-unicode-supported: 2.1.0 mustache: 4.2.0 picocolors: 1.1.1 - prettier: 3.6.2 - semver: 7.7.3 - tar: 7.5.2 + prettier: 3.8.1 + semver: 7.7.4 + tar: 7.5.10 temporal-polyfill: 0.3.0 vscode-languageserver: 9.0.1 vscode-languageserver-textdocument: 1.0.12 @@ -16335,38 +16494,39 @@ snapshots: transitivePeerDependencies: - '@types/node' - '@typespec/emitter-framework@0.14.0(@alloy-js/core@0.22.0)(@alloy-js/csharp@0.21.0)(@alloy-js/typescript@0.22.0)(@typespec/compiler@1.7.1(@types/node@25.0.3))': + '@typespec/emitter-framework@0.16.0(@alloy-js/core@0.22.0)(@alloy-js/csharp@0.21.0)(@alloy-js/python@0.3.0)(@alloy-js/typescript@0.22.0)(@typespec/compiler@1.9.0(@types/node@25.3.5))': dependencies: '@alloy-js/core': 0.22.0 '@alloy-js/csharp': 0.21.0 + '@alloy-js/python': 0.3.0 '@alloy-js/typescript': 0.22.0 - '@typespec/compiler': 1.7.1(@types/node@25.0.3) + '@typespec/compiler': 1.9.0(@types/node@25.3.5) - '@typespec/prettier-plugin-typespec@1.7.0': + '@typespec/prettier-plugin-typespec@1.9.0': dependencies: - prettier: 3.6.2 + prettier: 3.8.1 - '@uiw/codemirror-extensions-basic-setup@4.25.4(@codemirror/autocomplete@6.20.0)(@codemirror/commands@6.10.1)(@codemirror/language@6.12.1)(@codemirror/lint@6.9.2)(@codemirror/search@6.5.11)(@codemirror/state@6.5.3)(@codemirror/view@6.39.9)': + '@uiw/codemirror-extensions-basic-setup@4.25.7(@codemirror/autocomplete@6.20.0)(@codemirror/commands@6.10.1)(@codemirror/language@6.12.1)(@codemirror/lint@6.9.5)(@codemirror/search@6.5.11)(@codemirror/state@6.5.3)(@codemirror/view@6.39.9)': dependencies: '@codemirror/autocomplete': 6.20.0 '@codemirror/commands': 6.10.1 '@codemirror/language': 6.12.1 - '@codemirror/lint': 6.9.2 + '@codemirror/lint': 6.9.5 '@codemirror/search': 6.5.11 '@codemirror/state': 6.5.3 '@codemirror/view': 6.39.9 - '@uiw/react-codemirror@4.25.4(@babel/runtime@7.28.4)(@codemirror/autocomplete@6.20.0)(@codemirror/language@6.12.1)(@codemirror/lint@6.9.2)(@codemirror/search@6.5.11)(@codemirror/state@6.5.3)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.39.9)(codemirror@6.0.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@uiw/react-codemirror@4.25.7(@babel/runtime@7.28.6)(@codemirror/autocomplete@6.20.0)(@codemirror/language@6.12.1)(@codemirror/lint@6.9.5)(@codemirror/search@6.5.11)(@codemirror/state@6.5.3)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.39.9)(codemirror@6.0.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 '@codemirror/commands': 6.10.1 '@codemirror/state': 6.5.3 '@codemirror/theme-one-dark': 6.1.3 '@codemirror/view': 6.39.9 - '@uiw/codemirror-extensions-basic-setup': 4.25.4(@codemirror/autocomplete@6.20.0)(@codemirror/commands@6.10.1)(@codemirror/language@6.12.1)(@codemirror/lint@6.9.2)(@codemirror/search@6.5.11)(@codemirror/state@6.5.3)(@codemirror/view@6.39.9) + '@uiw/codemirror-extensions-basic-setup': 4.25.7(@codemirror/autocomplete@6.20.0)(@codemirror/commands@6.10.1)(@codemirror/language@6.12.1)(@codemirror/lint@6.9.5)(@codemirror/search@6.5.11)(@codemirror/state@6.5.3)(@codemirror/view@6.39.9) codemirror: 6.0.2 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) transitivePeerDependencies: - '@codemirror/autocomplete' - '@codemirror/language' @@ -16434,15 +16594,19 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.11.1': optional: true - '@vitejs/plugin-react@5.1.2(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@valibot/to-json-schema@1.5.0(valibot@1.2.0(typescript@5.9.3))': + dependencies: + valibot: 1.2.0(typescript@5.9.3) + + '@vitejs/plugin-react@5.1.4(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - '@babel/core': 7.28.5 - '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.5) - '@rolldown/pluginutils': 1.0.0-beta.53 + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) + '@rolldown/pluginutils': 1.0.0-rc.3 '@types/babel__core': 7.20.5 react-refresh: 0.18.0 - vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color @@ -16463,21 +16627,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.0.3 - '@vitest/mocker@3.2.4(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': - dependencies: - '@vitest/spy': 3.2.4 - estree-walker: 3.0.3 - magic-string: 0.30.21 - optionalDependencies: - vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) - - '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@vitest/spy': 4.0.18 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) '@vitest/pretty-format@3.2.4': dependencies: @@ -16515,17 +16671,11 @@ snapshots: '@vitest/pretty-format': 4.0.18 tinyrainbow: 3.0.3 - '@vue/reactivity@3.5.26': - dependencies: - '@vue/shared': 3.5.26 - - '@vue/reactivity@3.5.28': + '@vue/reactivity@3.5.29': dependencies: - '@vue/shared': 3.5.28 - - '@vue/shared@3.5.26': {} + '@vue/shared': 3.5.29 - '@vue/shared@3.5.28': {} + '@vue/shared@3.5.29': {} '@webassemblyjs/ast@1.14.1': dependencies: @@ -16613,13 +16763,13 @@ snapshots: '@xtuc/long@4.2.2': {} - '@xyflow/react@12.10.1(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@xyflow/react@12.10.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@xyflow/system': 0.0.75 classcat: 5.0.5 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - zustand: 4.5.7(@types/react@19.2.7)(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + zustand: 4.5.7(@types/react@19.2.14)(react@19.2.4) transitivePeerDependencies: - '@types/react' - immer @@ -16658,19 +16808,19 @@ snapshots: mime-types: 2.1.35 negotiator: 0.6.3 - acorn-import-phases@1.0.4(acorn@8.15.0): + acorn-import-phases@1.0.4(acorn@8.16.0): dependencies: - acorn: 8.15.0 + acorn: 8.16.0 - acorn-jsx@5.3.2(acorn@8.15.0): + acorn-jsx@5.3.2(acorn@8.16.0): dependencies: - acorn: 8.15.0 + acorn: 8.16.0 - acorn-walk@8.3.4: + acorn-walk@8.3.5: dependencies: - acorn: 8.15.0 + acorn: 8.16.0 - acorn@8.15.0: {} + acorn@8.16.0: {} address@1.2.2: {} @@ -16678,24 +16828,20 @@ snapshots: agent-base@7.1.4: {} - agentkeepalive@4.6.0: - dependencies: - humanize-ms: 1.2.1 - - ajv-formats@2.1.1(ajv@8.17.1): + ajv-formats@2.1.1(ajv@8.18.0): optionalDependencies: - ajv: 8.17.1 + ajv: 8.18.0 - ajv-keywords@3.5.2(ajv@6.12.6): + ajv-keywords@3.5.2(ajv@6.14.0): dependencies: - ajv: 6.12.6 + ajv: 6.14.0 - ajv-keywords@5.1.0(ajv@8.17.1): + ajv-keywords@5.1.0(ajv@8.18.0): dependencies: - ajv: 8.17.1 + ajv: 8.18.0 fast-deep-equal: 3.1.3 - ajv@6.12.6: + ajv@6.14.0: dependencies: fast-deep-equal: 3.1.3 fast-json-stable-stringify: 2.1.0 @@ -16709,6 +16855,13 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 + ajv@8.18.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + ansi-colors@4.1.3: {} ansi-regex@5.0.1: {} @@ -16734,7 +16887,7 @@ snapshots: app-builder-bin@5.0.0-alpha.12: {} - app-builder-lib@26.3.1(dmg-builder@26.3.1)(electron-builder-squirrel-windows@26.4.0): + app-builder-lib@26.4.0(dmg-builder@26.8.1)(electron-builder-squirrel-windows@26.4.0): dependencies: '@develar/schema-utils': 2.6.5 '@electron/asar': 3.4.1 @@ -16746,17 +16899,17 @@ snapshots: '@malept/flatpak-bundler': 0.4.0 '@types/fs-extra': 9.0.13 async-exit-hook: 2.0.1 - builder-util: 26.3.1 + builder-util: 26.3.4 builder-util-runtime: 9.5.1 chromium-pickle-js: 0.2.0 ci-info: 4.3.1 debug: 4.4.3 - dmg-builder: 26.3.1(electron-builder-squirrel-windows@26.4.0) + dmg-builder: 26.8.1(electron-builder-squirrel-windows@26.4.0) dotenv: 16.6.1 dotenv-expand: 11.0.7 ejs: 3.1.10 - electron-builder-squirrel-windows: 26.4.0(dmg-builder@26.3.1) - electron-publish: 26.3.1 + electron-builder-squirrel-windows: 26.4.0(dmg-builder@26.8.1) + electron-publish: 26.3.4 fs-extra: 10.1.0 hosted-git-info: 4.1.0 isbinaryfile: 5.0.7 @@ -16764,10 +16917,10 @@ snapshots: js-yaml: 4.1.1 json5: 2.2.3 lazy-val: 1.0.5 - minimatch: 10.1.1 + minimatch: 10.2.4 plist: 3.1.0 resedit: 1.7.2 - semver: 7.7.2 + semver: 7.7.4 tar: 6.2.1 temp-file: 3.4.0 tiny-async-pool: 1.3.0 @@ -16775,29 +16928,30 @@ snapshots: transitivePeerDependencies: - supports-color - app-builder-lib@26.4.0(dmg-builder@26.3.1)(electron-builder-squirrel-windows@26.4.0): + app-builder-lib@26.8.1(dmg-builder@26.8.1)(electron-builder-squirrel-windows@26.4.0): dependencies: '@develar/schema-utils': 2.6.5 '@electron/asar': 3.4.1 '@electron/fuses': 1.8.0 + '@electron/get': 3.1.0 '@electron/notarize': 2.5.0 '@electron/osx-sign': 1.3.3 - '@electron/rebuild': 4.0.1 + '@electron/rebuild': 4.0.3 '@electron/universal': 2.0.3 '@malept/flatpak-bundler': 0.4.0 '@types/fs-extra': 9.0.13 async-exit-hook: 2.0.1 - builder-util: 26.3.4 + builder-util: 26.8.1 builder-util-runtime: 9.5.1 chromium-pickle-js: 0.2.0 ci-info: 4.3.1 debug: 4.4.3 - dmg-builder: 26.3.1(electron-builder-squirrel-windows@26.4.0) + dmg-builder: 26.8.1(electron-builder-squirrel-windows@26.4.0) dotenv: 16.6.1 dotenv-expand: 11.0.7 ejs: 3.1.10 - electron-builder-squirrel-windows: 26.4.0(dmg-builder@26.3.1) - electron-publish: 26.3.4 + electron-builder-squirrel-windows: 26.4.0(dmg-builder@26.8.1) + electron-publish: 26.8.1 fs-extra: 10.1.0 hosted-git-info: 4.1.0 isbinaryfile: 5.0.7 @@ -16805,17 +16959,42 @@ snapshots: js-yaml: 4.1.1 json5: 2.2.3 lazy-val: 1.0.5 - minimatch: 10.2.1 + minimatch: 10.2.4 plist: 3.1.0 + proper-lockfile: 4.1.2 resedit: 1.7.2 semver: 7.7.4 - tar: 6.2.1 + tar: 7.5.10 temp-file: 3.4.0 tiny-async-pool: 1.3.0 which: 5.0.0 transitivePeerDependencies: - supports-color + archiver-utils@5.0.2: + dependencies: + glob: 10.5.0 + graceful-fs: 4.2.11 + is-stream: 2.0.1 + lazystream: 1.0.1 + lodash: 4.17.23 + normalize-path: 3.0.0 + readable-stream: 4.7.0 + + archiver@7.0.1: + dependencies: + archiver-utils: 5.0.2 + async: 3.2.6 + buffer-crc32: 1.0.0 + readable-stream: 4.7.0 + readdir-glob: 1.1.3 + tar-stream: 3.1.8 + zip-stream: 6.0.1 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + arg@4.1.3: {} argparse@1.0.10: @@ -16913,22 +17092,24 @@ snapshots: at-least-node@1.0.0: {} - autoprefixer@10.4.23(postcss@8.5.6): + autoprefixer@10.4.27(postcss@8.5.8): dependencies: browserslist: 4.28.1 - caniuse-lite: 1.0.30001762 + caniuse-lite: 1.0.30001777 fraction.js: 5.3.4 picocolors: 1.1.1 - postcss: 8.5.6 + postcss: 8.5.8 postcss-value-parser: 4.2.0 available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.1.0 + aws-ssl-profiles@1.1.2: {} + axe-core@4.11.1: {} - axios@1.13.2: + axios@1.13.6: dependencies: follow-redirects: 1.15.11(debug@4.4.3) form-data: 4.0.5 @@ -16938,76 +17119,117 @@ snapshots: axobject-query@4.1.0: {} - babel-dead-code-elimination@1.0.11: + b4a@1.8.0: {} + + babel-dead-code-elimination@1.0.12: dependencies: - '@babel/core': 7.28.5 - '@babel/parser': 7.28.5 - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/core': 7.29.0 + '@babel/parser': 7.29.0 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color - babel-plugin-const-enum@1.2.0(@babel/core@7.28.5): + babel-plugin-const-enum@1.2.0(@babel/core@7.29.0): dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5) - '@babel/traverse': 7.28.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color babel-plugin-macros@3.1.0: dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 cosmiconfig: 7.1.0 resolve: 1.22.11 - babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.5): + babel-plugin-polyfill-corejs2@0.4.15(@babel/core@7.29.0): dependencies: - '@babel/compat-data': 7.28.5 - '@babel/core': 7.28.5 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5) + '@babel/compat-data': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) semver: 6.3.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.28.5): + babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) + core-js-compat: 3.48.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs3@0.14.0(@babel/core@7.29.0): dependencies: - '@babel/core': 7.28.5 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5) - core-js-compat: 3.47.0 + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) + core-js-compat: 3.48.0 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.28.5): + babel-plugin-polyfill-regenerator@0.6.6(@babel/core@7.29.0): dependencies: - '@babel/core': 7.28.5 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color babel-plugin-react-compiler@19.1.0-rc.3: dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 - babel-plugin-transform-typescript-metadata@0.3.2(@babel/core@7.28.5)(@babel/traverse@7.28.5): + babel-plugin-transform-typescript-metadata@0.3.2(@babel/core@7.29.0)(@babel/traverse@7.29.0): dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 optionalDependencies: - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.29.0 bail@2.0.2: {} balanced-match@1.0.2: {} - balanced-match@4.0.2: + balanced-match@4.0.4: {} + + bare-events@2.8.2: {} + + bare-fs@4.5.5: + dependencies: + bare-events: 2.8.2 + bare-path: 3.0.0 + bare-stream: 2.8.0(bare-events@2.8.2) + bare-url: 2.3.2 + fast-fifo: 1.3.2 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + bare-os@3.7.1: {} + + bare-path@3.0.0: + dependencies: + bare-os: 3.7.1 + + bare-stream@2.8.0(bare-events@2.8.2): dependencies: - jackspeak: 4.2.3 + streamx: 2.23.0 + teex: 1.0.1 + optionalDependencies: + bare-events: 2.8.2 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + bare-url@2.3.2: + dependencies: + bare-path: 3.0.0 base64-js@1.5.1: {} - baseline-browser-mapping@2.9.11: {} + baseline-browser-mapping@2.10.0: {} basic-auth@2.0.1: dependencies: @@ -17015,29 +17237,66 @@ snapshots: before-after-hook@4.0.0: {} - better-auth@1.4.18(@prisma/client@5.22.0)(better-sqlite3@12.6.2)(drizzle-orm@0.41.0(@libsql/client@0.14.0)(@prisma/client@5.22.0)(@types/pg@8.16.0)(better-sqlite3@12.6.2)(kysely@0.28.11)(pg@8.18.0))(pg@8.18.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.10)(vitest@4.0.18(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)): + better-auth@1.4.21(@prisma/client@5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(better-sqlite3@12.6.2)(drizzle-orm@0.41.0(@electric-sql/pglite@0.3.15)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.18.0)(better-sqlite3@12.6.2)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(mongodb@7.1.0(socks@2.8.7))(mysql2@3.15.3)(pg@8.20.0)(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(solid-js@1.9.10)(vitest@4.0.18(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): dependencies: - '@better-auth/core': 1.4.18(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) - '@better-auth/telemetry': 1.4.18(@better-auth/core@1.4.18(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0)) + '@better-auth/core': 1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1) + '@better-auth/telemetry': 1.4.21(@better-auth/core@1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1)) '@better-auth/utils': 0.3.0 '@better-fetch/fetch': 1.1.21 '@noble/ciphers': 2.1.1 '@noble/hashes': 2.0.1 better-call: 1.1.8(zod@4.3.6) defu: 6.1.4 - jose: 6.1.3 + jose: 6.2.0 + kysely: 0.28.11 + nanostores: 1.1.1 + zod: 4.3.6 + optionalDependencies: + '@prisma/client': 5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) + better-sqlite3: 12.6.2 + drizzle-orm: 0.41.0(@electric-sql/pglite@0.3.15)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.18.0)(better-sqlite3@12.6.2)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) + mongodb: 7.1.0(socks@2.8.7) + mysql2: 3.15.3 + pg: 8.20.0 + prisma: 7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + solid-js: 1.9.10 + vitest: 4.0.18(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + better-auth@1.5.4(@prisma/client@5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(better-sqlite3@12.6.2)(drizzle-orm@0.41.0(@electric-sql/pglite@0.3.15)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.18.0)(better-sqlite3@12.6.2)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(mongodb@7.1.0(socks@2.8.7))(mysql2@3.15.3)(pg@8.20.0)(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(solid-js@1.9.10)(vitest@4.0.18(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + dependencies: + '@better-auth/core': 1.5.4(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1) + '@better-auth/drizzle-adapter': 1.5.4(@better-auth/core@1.5.4(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1))(@better-auth/utils@0.3.1)(drizzle-orm@0.41.0(@electric-sql/pglite@0.3.15)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.18.0)(better-sqlite3@12.6.2)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))) + '@better-auth/kysely-adapter': 1.5.4(@better-auth/core@1.5.4(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1))(@better-auth/utils@0.3.1)(kysely@0.28.11) + '@better-auth/memory-adapter': 1.5.4(@better-auth/core@1.5.4(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1))(@better-auth/utils@0.3.1) + '@better-auth/mongo-adapter': 1.5.4(@better-auth/core@1.5.4(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1))(@better-auth/utils@0.3.1)(mongodb@7.1.0(socks@2.8.7)) + '@better-auth/prisma-adapter': 1.5.4(@better-auth/core@1.5.4(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1))(@better-auth/utils@0.3.1)(@prisma/client@5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) + '@better-auth/telemetry': 1.5.4(@better-auth/core@1.5.4(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.0)(kysely@0.28.11)(nanostores@1.1.1)) + '@better-auth/utils': 0.3.1 + '@better-fetch/fetch': 1.1.21 + '@noble/ciphers': 2.1.1 + '@noble/hashes': 2.0.1 + better-call: 1.3.2(zod@4.3.6) + defu: 6.1.4 + jose: 6.2.0 kysely: 0.28.11 - nanostores: 1.1.0 + nanostores: 1.1.1 zod: 4.3.6 optionalDependencies: - '@prisma/client': 5.22.0 + '@prisma/client': 5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) better-sqlite3: 12.6.2 - drizzle-orm: 0.41.0(@libsql/client@0.14.0)(@prisma/client@5.22.0)(@types/pg@8.16.0)(better-sqlite3@12.6.2)(kysely@0.28.11)(pg@8.18.0) - pg: 8.18.0 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + drizzle-orm: 0.41.0(@electric-sql/pglite@0.3.15)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.18.0)(better-sqlite3@12.6.2)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) + mongodb: 7.1.0(socks@2.8.7) + mysql2: 3.15.3 + pg: 8.20.0 + prisma: 7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) solid-js: 1.9.10 - vitest: 4.0.18(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vitest: 4.0.18(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - '@cloudflare/workers-types' better-call@1.1.8(zod@4.3.6): dependencies: @@ -17048,23 +17307,30 @@ snapshots: optionalDependencies: zod: 4.3.6 + better-call@1.3.2(zod@4.3.6): + dependencies: + '@better-auth/utils': 0.3.1 + '@better-fetch/fetch': 1.1.21 + rou3: 0.7.12 + set-cookie-parser: 3.0.1 + optionalDependencies: + zod: 4.3.6 + better-sqlite3@12.6.2: dependencies: bindings: 1.5.0 prebuild-install: 7.1.3 - big.js@5.2.2: {} - binary-extensions@2.3.0: {} bindings@1.5.0: dependencies: file-uri-to-path: 1.0.0 - bippy@0.3.34(@types/react@19.2.7)(react@19.2.3): + bippy@0.5.30(@types/react@19.2.14)(react@19.2.4): dependencies: - '@types/react-reconciler': 0.28.9(@types/react@19.2.7) - react: 19.2.3 + '@types/react-reconciler': 0.28.9(@types/react@19.2.14) + react: 19.2.4 transitivePeerDependencies: - '@types/react' @@ -17084,7 +17350,7 @@ snapshots: http-errors: 2.0.1 iconv-lite: 0.4.24 on-finished: 2.4.1 - qs: 6.14.1 + qs: 6.14.2 raw-body: 2.5.3 type-is: 1.6.18 unpipe: 1.0.0 @@ -17105,9 +17371,9 @@ snapshots: dependencies: balanced-match: 1.0.2 - brace-expansion@5.0.2: + brace-expansion@5.0.4: dependencies: - balanced-match: 4.0.2 + balanced-match: 4.0.4 braces@3.0.3: dependencies: @@ -17115,16 +17381,20 @@ snapshots: browserslist@4.28.1: dependencies: - baseline-browser-mapping: 2.9.11 - caniuse-lite: 1.0.30001762 - electron-to-chromium: 1.5.267 - node-releases: 2.0.27 + baseline-browser-mapping: 2.10.0 + caniuse-lite: 1.0.30001777 + electron-to-chromium: 1.5.307 + node-releases: 2.0.36 update-browserslist-db: 1.2.3(browserslist@4.28.1) + bson@7.2.0: {} + btoa@1.2.1: {} buffer-crc32@0.2.13: {} + buffer-crc32@1.0.0: {} + buffer-from@1.1.2: {} buffer@5.7.1: @@ -17132,21 +17402,25 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + builder-util-runtime@9.5.1: dependencies: debug: 4.4.3 - sax: 1.4.3 + sax: 1.5.0 transitivePeerDependencies: - supports-color - builder-util@26.3.1: + builder-util@26.3.4: dependencies: 7zip-bin: 5.2.0 '@types/debug': 4.1.12 app-builder-bin: 5.0.0-alpha.12 builder-util-runtime: 9.5.1 chalk: 4.1.2 - ci-info: 4.3.1 cross-spawn: 7.0.6 debug: 4.4.3 fs-extra: 10.1.0 @@ -17161,7 +17435,7 @@ snapshots: transitivePeerDependencies: - supports-color - builder-util@26.3.4: + builder-util@26.8.1: dependencies: 7zip-bin: 5.2.0 '@types/debug': 4.1.12 @@ -17186,57 +17460,72 @@ snapshots: dependencies: run-applescript: 7.1.0 - bundle-require@5.1.0(esbuild@0.27.2): + bundle-require@5.1.0(esbuild@0.27.3): dependencies: - esbuild: 0.27.2 + esbuild: 0.27.3 load-tsconfig: 0.2.5 bytes@3.1.2: {} - c12@3.3.3: + c12@3.1.0: dependencies: - chokidar: 5.0.0 + chokidar: 4.0.3 confbox: 0.2.4 defu: 6.1.4 - dotenv: 17.3.1 + dotenv: 16.6.1 exsolve: 1.0.8 giget: 2.0.0 jiti: 2.6.1 ohash: 2.0.11 pathe: 2.0.3 - perfect-debounce: 2.1.0 + perfect-debounce: 1.0.0 pkg-types: 2.3.0 rc9: 2.1.2 - cac@6.7.14: {} - - cacache@19.0.1: + c12@3.3.3: + dependencies: + chokidar: 5.0.0 + confbox: 0.2.4 + defu: 6.1.4 + dotenv: 17.3.1 + exsolve: 1.0.8 + giget: 2.0.0 + jiti: 2.6.1 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 2.1.0 + pkg-types: 2.3.0 + rc9: 2.1.2 + + cac@6.7.14: {} + + cacache@19.0.1: dependencies: '@npmcli/fs': 4.0.0 fs-minipass: 3.0.3 glob: 10.5.0 lru-cache: 10.4.3 - minipass: 7.1.2 + minipass: 7.1.3 minipass-collect: 2.0.1 minipass-flush: 1.0.5 minipass-pipeline: 1.2.4 p-map: 7.0.4 ssri: 12.0.0 - tar: 7.5.2 + tar: 7.5.10 unique-filename: 4.0.0 cacache@20.0.3: dependencies: '@npmcli/fs': 5.0.0 fs-minipass: 3.0.3 - glob: 13.0.0 - lru-cache: 11.2.4 - minipass: 7.1.2 + glob: 13.0.6 + lru-cache: 11.2.6 + minipass: 7.1.3 minipass-collect: 2.0.1 minipass-flush: 1.0.5 minipass-pipeline: 1.2.4 p-map: 7.0.4 - ssri: 13.0.0 + ssri: 13.0.1 unique-filename: 5.0.0 cacheable-lookup@5.0.4: {} @@ -17272,14 +17561,7 @@ snapshots: camelcase@6.3.0: {} - caniuse-api@3.0.0: - dependencies: - browserslist: 4.28.1 - caniuse-lite: 1.0.30001762 - lodash.memoize: 4.1.2 - lodash.uniq: 4.5.0 - - caniuse-lite@1.0.30001762: {} + caniuse-lite@1.0.30001777: {} ccount@2.0.1: {} @@ -17372,6 +17654,8 @@ snapshots: ci-info@4.3.1: {} + ci-info@4.4.0: {} + citty@0.1.6: dependencies: consola: 3.4.2 @@ -17417,7 +17701,7 @@ snapshots: cliui@9.0.1: dependencies: string-width: 7.2.0 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 wrap-ansi: 9.0.2 clone-response@1.0.3: @@ -17433,7 +17717,7 @@ snapshots: '@codemirror/autocomplete': 6.20.0 '@codemirror/commands': 6.10.1 '@codemirror/language': 6.12.1 - '@codemirror/lint': 6.9.2 + '@codemirror/lint': 6.9.5 '@codemirror/search': 6.5.11 '@codemirror/state': 6.5.3 '@codemirror/view': 6.39.9 @@ -17444,8 +17728,6 @@ snapshots: color-name@1.1.4: {} - colord@2.9.3: {} - colorette@2.0.20: {} columnify@1.6.0: @@ -17465,6 +17747,8 @@ snapshots: commander@13.1.0: {} + commander@14.0.3: {} + commander@2.20.3: {} commander@4.1.1: {} @@ -17476,12 +17760,20 @@ snapshots: commander@9.5.0: optional: true - comment-parser@1.4.1: {} + comment-parser@1.4.5: {} commondir@1.0.1: {} compare-version@0.1.2: {} + compress-commons@6.0.2: + dependencies: + crc-32: 1.2.2 + crc32-stream: 6.0.0 + is-stream: 2.0.1 + normalize-path: 3.0.0 + readable-stream: 4.7.0 + concat-map@0.0.1: {} concat-with-sourcemaps@1.1.0: @@ -17515,7 +17807,7 @@ snapshots: depd: 2.0.0 keygrip: 1.1.0 - core-js-compat@3.47.0: + core-js-compat@3.48.0: dependencies: browserslist: 4.28.1 @@ -17543,7 +17835,7 @@ snapshots: optionalDependencies: typescript: 5.9.3 - cosmiconfig@9.0.0(typescript@5.9.3): + cosmiconfig@9.0.1(typescript@5.9.3): dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 @@ -17552,6 +17844,13 @@ snapshots: optionalDependencies: typescript: 5.9.3 + crc-32@1.2.2: {} + + crc32-stream@6.0.0: + dependencies: + crc-32: 1.2.2 + readable-stream: 4.7.0 + crc@3.8.0: dependencies: buffer: 5.7.1 @@ -17574,18 +17873,6 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - css-declaration-sorter@6.4.1(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - - css-select@4.3.0: - dependencies: - boolbase: 1.0.0 - css-what: 6.2.2 - domhandler: 4.3.1 - domutils: 2.8.0 - nth-check: 2.1.1 - css-select@5.2.2: dependencies: boolbase: 1.0.0 @@ -17594,11 +17881,6 @@ snapshots: domutils: 3.2.2 nth-check: 2.1.1 - css-tree@1.1.3: - dependencies: - mdn-data: 2.0.14 - source-map: 0.6.1 - css-tree@2.2.1: dependencies: mdn-data: 2.0.28 @@ -17615,54 +17897,6 @@ snapshots: cssesc@3.0.0: {} - cssnano-preset-default@5.2.14(postcss@8.5.6): - dependencies: - css-declaration-sorter: 6.4.1(postcss@8.5.6) - cssnano-utils: 3.1.0(postcss@8.5.6) - postcss: 8.5.6 - postcss-calc: 8.2.4(postcss@8.5.6) - postcss-colormin: 5.3.1(postcss@8.5.6) - postcss-convert-values: 5.1.3(postcss@8.5.6) - postcss-discard-comments: 5.1.2(postcss@8.5.6) - postcss-discard-duplicates: 5.1.0(postcss@8.5.6) - postcss-discard-empty: 5.1.1(postcss@8.5.6) - postcss-discard-overridden: 5.1.0(postcss@8.5.6) - postcss-merge-longhand: 5.1.7(postcss@8.5.6) - postcss-merge-rules: 5.1.4(postcss@8.5.6) - postcss-minify-font-values: 5.1.0(postcss@8.5.6) - postcss-minify-gradients: 5.1.1(postcss@8.5.6) - postcss-minify-params: 5.1.4(postcss@8.5.6) - postcss-minify-selectors: 5.2.1(postcss@8.5.6) - postcss-normalize-charset: 5.1.0(postcss@8.5.6) - postcss-normalize-display-values: 5.1.0(postcss@8.5.6) - postcss-normalize-positions: 5.1.1(postcss@8.5.6) - postcss-normalize-repeat-style: 5.1.1(postcss@8.5.6) - postcss-normalize-string: 5.1.0(postcss@8.5.6) - postcss-normalize-timing-functions: 5.1.0(postcss@8.5.6) - postcss-normalize-unicode: 5.1.1(postcss@8.5.6) - postcss-normalize-url: 5.1.0(postcss@8.5.6) - postcss-normalize-whitespace: 5.1.1(postcss@8.5.6) - postcss-ordered-values: 5.1.3(postcss@8.5.6) - postcss-reduce-initial: 5.1.2(postcss@8.5.6) - postcss-reduce-transforms: 5.1.0(postcss@8.5.6) - postcss-svgo: 5.1.0(postcss@8.5.6) - postcss-unique-selectors: 5.1.1(postcss@8.5.6) - - cssnano-utils@3.1.0(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - - cssnano@5.1.15(postcss@8.5.6): - dependencies: - cssnano-preset-default: 5.2.14(postcss@8.5.6) - lilconfig: 2.1.0 - postcss: 8.5.6 - yaml: 1.10.2 - - csso@4.2.0: - dependencies: - css-tree: 1.1.3 - csso@5.0.5: dependencies: css-tree: 2.2.1 @@ -17756,11 +17990,13 @@ snapshots: deep-is@0.1.4: {} + deepmerge-ts@7.1.5: {} + deepmerge@4.3.1: {} default-browser-id@5.0.1: {} - default-browser@5.4.0: + default-browser@5.5.0: dependencies: bundle-name: 4.1.0 default-browser-id: 5.0.1 @@ -17793,6 +18029,8 @@ snapshots: delegates@1.0.0: {} + denque@2.1.0: {} + depd@1.1.2: {} depd@2.0.0: {} @@ -17803,8 +18041,6 @@ snapshots: destroy@1.2.0: {} - detect-libc@1.0.3: {} - detect-libc@2.0.2: optional: true @@ -17824,19 +18060,19 @@ snapshots: dependencies: dequal: 2.0.3 - diff@4.0.2: {} + diff@4.0.4: {} - diff@8.0.2: {} + diff@8.0.3: {} dir-compare@4.2.0: dependencies: - minimatch: 3.1.2 + minimatch: 3.1.5 p-limit: 3.1.0 - dmg-builder@26.3.1(electron-builder-squirrel-windows@26.4.0): + dmg-builder@26.8.1(electron-builder-squirrel-windows@26.4.0): dependencies: - app-builder-lib: 26.3.1(dmg-builder@26.3.1)(electron-builder-squirrel-windows@26.4.0) - builder-util: 26.3.1 + app-builder-lib: 26.8.1(dmg-builder@26.8.1)(electron-builder-squirrel-windows@26.4.0) + builder-util: 26.8.1 fs-extra: 10.1.0 iconv-lite: 0.6.3 js-yaml: 4.1.1 @@ -17850,7 +18086,7 @@ snapshots: dependencies: '@types/plist': 3.0.5 '@types/verror': 1.10.11 - ajv: 6.12.6 + ajv: 6.14.0 crc: 3.8.0 iconv-corefoundation: 1.1.7 plist: 3.1.0 @@ -17870,12 +18106,6 @@ snapshots: dom-accessibility-api@0.6.3: {} - dom-serializer@1.4.1: - dependencies: - domelementtype: 2.3.0 - domhandler: 4.3.1 - entities: 2.2.0 - dom-serializer@2.0.0: dependencies: domelementtype: 2.3.0 @@ -17884,20 +18114,10 @@ snapshots: domelementtype@2.3.0: {} - domhandler@4.3.1: - dependencies: - domelementtype: 2.3.0 - domhandler@5.0.3: dependencies: domelementtype: 2.3.0 - domutils@2.8.0: - dependencies: - dom-serializer: 1.4.1 - domelementtype: 2.3.0 - domhandler: 4.3.1 - domutils@3.2.2: dependencies: dom-serializer: 2.0.0 @@ -17919,14 +18139,18 @@ snapshots: dotenv@17.3.1: {} - drizzle-orm@0.41.0(@libsql/client@0.14.0)(@prisma/client@5.22.0)(@types/pg@8.16.0)(better-sqlite3@12.6.2)(kysely@0.28.11)(pg@8.18.0): + drizzle-orm@0.41.0(@electric-sql/pglite@0.3.15)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.18.0)(better-sqlite3@12.6.2)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)): optionalDependencies: + '@electric-sql/pglite': 0.3.15 '@libsql/client': 0.14.0 - '@prisma/client': 5.22.0 - '@types/pg': 8.16.0 + '@prisma/client': 5.22.0(prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) + '@types/pg': 8.18.0 better-sqlite3: 12.6.2 kysely: 0.28.11 - pg: 8.18.0 + mysql2: 3.15.3 + pg: 8.20.0 + postgres: 3.4.7 + prisma: 7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) dunder-proto@1.0.1: dependencies: @@ -17938,7 +18162,12 @@ snapshots: ee-first@1.1.1: {} - effect@3.19.14: + effect@3.18.4: + dependencies: + '@standard-schema/spec': 1.1.0 + fast-check: 3.23.2 + + effect@3.19.19: dependencies: '@standard-schema/spec': 1.1.0 fast-check: 3.23.2 @@ -17947,23 +18176,23 @@ snapshots: dependencies: jake: 10.9.4 - electron-builder-squirrel-windows@26.4.0(dmg-builder@26.3.1): + electron-builder-squirrel-windows@26.4.0(dmg-builder@26.8.1): dependencies: - app-builder-lib: 26.4.0(dmg-builder@26.3.1)(electron-builder-squirrel-windows@26.4.0) + app-builder-lib: 26.4.0(dmg-builder@26.8.1)(electron-builder-squirrel-windows@26.4.0) builder-util: 26.3.4 electron-winstaller: 5.4.0 transitivePeerDependencies: - dmg-builder - supports-color - electron-builder@26.3.1(electron-builder-squirrel-windows@26.4.0): + electron-builder@26.8.1(electron-builder-squirrel-windows@26.4.0): dependencies: - app-builder-lib: 26.3.1(dmg-builder@26.3.1)(electron-builder-squirrel-windows@26.4.0) - builder-util: 26.3.1 + app-builder-lib: 26.8.1(dmg-builder@26.8.1)(electron-builder-squirrel-windows@26.4.0) + builder-util: 26.8.1 builder-util-runtime: 9.5.1 chalk: 4.1.2 - ci-info: 4.3.1 - dmg-builder: 26.3.1(electron-builder-squirrel-windows@26.4.0) + ci-info: 4.4.0 + dmg-builder: 26.8.1(electron-builder-squirrel-windows@26.4.0) fs-extra: 10.1.0 lazy-val: 1.0.5 simple-update-notifier: 2.0.0 @@ -17976,10 +18205,10 @@ snapshots: dependencies: unzip-crx-3: 0.2.0 - electron-publish@26.3.1: + electron-publish@26.3.4: dependencies: '@types/fs-extra': 9.0.13 - builder-util: 26.3.1 + builder-util: 26.3.4 builder-util-runtime: 9.5.1 chalk: 4.1.2 form-data: 4.0.5 @@ -17989,10 +18218,10 @@ snapshots: transitivePeerDependencies: - supports-color - electron-publish@26.3.4: + electron-publish@26.8.1: dependencies: '@types/fs-extra': 9.0.13 - builder-util: 26.3.4 + builder-util: 26.8.1 builder-util-runtime: 9.5.1 chalk: 4.1.2 form-data: 4.0.5 @@ -18002,9 +18231,9 @@ snapshots: transitivePeerDependencies: - supports-color - electron-to-chromium@1.5.267: {} + electron-to-chromium@1.5.307: {} - electron-updater@6.7.3: + electron-updater@6.8.3: dependencies: builder-util-runtime: 9.5.1 fs-extra: 10.1.0 @@ -18012,22 +18241,22 @@ snapshots: lazy-val: 1.0.5 lodash.escaperegexp: 4.1.2 lodash.isequal: 4.5.0 - semver: 7.7.3 + semver: 7.7.4 tiny-typed-emitter: 2.1.0 transitivePeerDependencies: - supports-color - electron-vite@5.0.0(@swc/core@1.15.8(@swc/helpers@0.5.18))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)): + electron-vite@5.0.0(@swc/core@1.15.8(@swc/helpers@0.5.19))(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): dependencies: - '@babel/core': 7.28.5 - '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) cac: 6.7.14 esbuild: 0.25.12 magic-string: 0.30.21 picocolors: 1.1.1 - vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) optionalDependencies: - '@swc/core': 1.15.8(@swc/helpers@0.5.18) + '@swc/core': 1.15.8(@swc/helpers@0.5.19) transitivePeerDependencies: - supports-color @@ -18043,10 +18272,10 @@ snapshots: transitivePeerDependencies: - supports-color - electron@39.2.7: + electron@40.8.0: dependencies: '@electron/get': 2.0.3 - '@types/node': 22.19.3 + '@types/node': 24.12.0 extract-zip: 2.0.1 transitivePeerDependencies: - supports-color @@ -18057,8 +18286,6 @@ snapshots: emoji-regex@9.2.2: {} - emojis-list@3.0.0: {} - empathic@2.0.0: {} encodeurl@2.0.0: {} @@ -18071,7 +18298,7 @@ snapshots: dependencies: once: 1.4.0 - enhanced-resolve@5.18.4: + enhanced-resolve@5.20.0: dependencies: graceful-fs: 4.2.11 tapable: 2.3.0 @@ -18085,8 +18312,6 @@ snapshots: ansi-colors: 4.1.3 strip-ansi: 6.0.1 - entities@2.2.0: {} - entities@4.5.0: {} env-paths@2.2.1: {} @@ -18154,7 +18379,7 @@ snapshots: typed-array-byte-offset: 1.0.4 typed-array-length: 1.0.7 unbox-primitive: 1.1.0 - which-typed-array: 1.1.19 + which-typed-array: 1.1.20 es-define-property@1.0.1: {} @@ -18236,34 +18461,34 @@ snapshots: '@esbuild/win32-ia32': 0.25.12 '@esbuild/win32-x64': 0.25.12 - esbuild@0.27.2: + esbuild@0.27.3: optionalDependencies: - '@esbuild/aix-ppc64': 0.27.2 - '@esbuild/android-arm': 0.27.2 - '@esbuild/android-arm64': 0.27.2 - '@esbuild/android-x64': 0.27.2 - '@esbuild/darwin-arm64': 0.27.2 - '@esbuild/darwin-x64': 0.27.2 - '@esbuild/freebsd-arm64': 0.27.2 - '@esbuild/freebsd-x64': 0.27.2 - '@esbuild/linux-arm': 0.27.2 - '@esbuild/linux-arm64': 0.27.2 - '@esbuild/linux-ia32': 0.27.2 - '@esbuild/linux-loong64': 0.27.2 - '@esbuild/linux-mips64el': 0.27.2 - '@esbuild/linux-ppc64': 0.27.2 - '@esbuild/linux-riscv64': 0.27.2 - '@esbuild/linux-s390x': 0.27.2 - '@esbuild/linux-x64': 0.27.2 - '@esbuild/netbsd-arm64': 0.27.2 - '@esbuild/netbsd-x64': 0.27.2 - '@esbuild/openbsd-arm64': 0.27.2 - '@esbuild/openbsd-x64': 0.27.2 - '@esbuild/openharmony-arm64': 0.27.2 - '@esbuild/sunos-x64': 0.27.2 - '@esbuild/win32-arm64': 0.27.2 - '@esbuild/win32-ia32': 0.27.2 - '@esbuild/win32-x64': 0.27.2 + '@esbuild/aix-ppc64': 0.27.3 + '@esbuild/android-arm': 0.27.3 + '@esbuild/android-arm64': 0.27.3 + '@esbuild/android-x64': 0.27.3 + '@esbuild/darwin-arm64': 0.27.3 + '@esbuild/darwin-x64': 0.27.3 + '@esbuild/freebsd-arm64': 0.27.3 + '@esbuild/freebsd-x64': 0.27.3 + '@esbuild/linux-arm': 0.27.3 + '@esbuild/linux-arm64': 0.27.3 + '@esbuild/linux-ia32': 0.27.3 + '@esbuild/linux-loong64': 0.27.3 + '@esbuild/linux-mips64el': 0.27.3 + '@esbuild/linux-ppc64': 0.27.3 + '@esbuild/linux-riscv64': 0.27.3 + '@esbuild/linux-s390x': 0.27.3 + '@esbuild/linux-x64': 0.27.3 + '@esbuild/netbsd-arm64': 0.27.3 + '@esbuild/netbsd-x64': 0.27.3 + '@esbuild/openbsd-arm64': 0.27.3 + '@esbuild/openbsd-x64': 0.27.3 + '@esbuild/openharmony-arm64': 0.27.3 + '@esbuild/sunos-x64': 0.27.3 + '@esbuild/win32-arm64': 0.27.3 + '@esbuild/win32-ia32': 0.27.3 + '@esbuild/win32-x64': 0.27.3 escalade@3.2.0: {} @@ -18281,53 +18506,56 @@ snapshots: eslint-import-context@0.1.9(unrs-resolver@1.11.1): dependencies: - get-tsconfig: 4.13.0 + get-tsconfig: 4.13.6 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.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)): + eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)): dependencies: debug: 4.4.3 eslint: 9.39.2(jiti@2.6.1) eslint-import-context: 0.1.9(unrs-resolver@1.11.1) - get-tsconfig: 4.13.0 + get-tsconfig: 4.13.6 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.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)) transitivePeerDependencies: - supports-color - eslint-plugin-better-tailwindcss@3.8.0(eslint@9.39.2(jiti@2.6.1))(tailwindcss@4.1.18): + eslint-plugin-better-tailwindcss@4.3.2(eslint@9.39.2(jiti@2.6.1))(tailwindcss@4.2.1)(typescript@5.9.3): dependencies: - '@eslint/css-tree': 3.6.8 - enhanced-resolve: 5.18.4 - eslint: 9.39.2(jiti@2.6.1) + '@eslint/css-tree': 3.6.9 + '@valibot/to-json-schema': 1.5.0(valibot@1.2.0(typescript@5.9.3)) + enhanced-resolve: 5.20.0 jiti: 2.6.1 - postcss: 8.5.6 - postcss-import: 16.1.1(postcss@8.5.6) - synckit: 0.11.11 + synckit: 0.11.12 tailwind-csstree: 0.1.4 - tailwindcss: 4.1.18 + tailwindcss: 4.2.1 tsconfig-paths-webpack-plugin: 4.2.0 + valibot: 1.2.0(typescript@5.9.3) + optionalDependencies: + eslint: 9.39.2(jiti@2.6.1) + transitivePeerDependencies: + - typescript - eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)): + eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)): dependencies: - '@typescript-eslint/types': 8.52.0 - comment-parser: 1.4.1 + '@typescript-eslint/types': 8.56.1 + comment-parser: 1.4.5 debug: 4.4.3 eslint: 9.39.2(jiti@2.6.1) eslint-import-context: 0.1.9(unrs-resolver@1.11.1) is-glob: 4.0.3 - minimatch: 10.1.1 - semver: 7.7.3 + minimatch: 10.2.4 + semver: 7.7.4 stable-hash-x: 0.2.0 unrs-resolver: 1.11.1 optionalDependencies: - '@typescript-eslint/utils': 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) transitivePeerDependencies: - supports-color @@ -18345,14 +18573,14 @@ snapshots: hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 - minimatch: 3.1.2 + minimatch: 3.1.5 object.fromentries: 2.0.8 safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 - eslint-plugin-perfectionist@5.3.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): + eslint-plugin-perfectionist@5.6.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@typescript-eslint/utils': 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) natural-orderby: 5.0.0 transitivePeerDependencies: @@ -18361,12 +18589,12 @@ snapshots: eslint-plugin-react-hooks@7.0.1(eslint@9.39.2(jiti@2.6.1)): dependencies: - '@babel/core': 7.28.5 - '@babel/parser': 7.28.5 + '@babel/core': 7.29.0 + '@babel/parser': 7.29.0 eslint: 9.39.2(jiti@2.6.1) hermes-parser: 0.25.1 - zod: 4.3.5 - zod-validation-error: 4.0.2(zod@4.3.5) + zod: 4.3.6 + zod-validation-error: 4.0.2(zod@4.3.6) transitivePeerDependencies: - supports-color @@ -18382,12 +18610,12 @@ snapshots: estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 - minimatch: 3.1.2 + minimatch: 3.1.5 object.entries: 1.1.9 object.fromentries: 2.0.8 object.values: 1.2.1 prop-types: 15.8.1 - resolve: 2.0.0-next.5 + resolve: 2.0.0-next.6 semver: 6.3.1 string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 @@ -18406,6 +18634,8 @@ snapshots: eslint-visitor-keys@4.2.1: {} + eslint-visitor-keys@5.0.1: {} + eslint@9.39.2(jiti@2.6.1): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) @@ -18413,14 +18643,14 @@ snapshots: '@eslint/config-array': 0.21.1 '@eslint/config-helpers': 0.4.2 '@eslint/core': 0.17.0 - '@eslint/eslintrc': 3.3.3 + '@eslint/eslintrc': 3.3.4 '@eslint/js': 9.39.2 '@eslint/plugin-kit': 0.4.1 '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 '@types/estree': 1.0.8 - ajv: 6.12.6 + ajv: 6.14.0 chalk: 4.1.2 cross-spawn: 7.0.6 debug: 4.4.3 @@ -18439,7 +18669,7 @@ snapshots: is-glob: 4.0.3 json-stable-stringify-without-jsonify: 1.0.1 lodash.merge: 4.6.2 - minimatch: 3.1.2 + minimatch: 3.1.5 natural-compare: 1.4.0 optionator: 0.9.4 optionalDependencies: @@ -18449,8 +18679,8 @@ snapshots: espree@10.4.0: dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) eslint-visitor-keys: 4.2.1 esprima@4.0.1: {} @@ -18469,8 +18699,6 @@ snapshots: estree-util-is-identifier-name@3.0.0: {} - estree-walker@0.6.1: {} - estree-walker@2.0.2: {} estree-walker@3.0.3: @@ -18485,6 +18713,12 @@ snapshots: eventemitter3@4.0.7: {} + events-universal@1.0.1: + dependencies: + bare-events: 2.8.2 + transitivePeerDependencies: + - bare-abort-controller + events@3.3.0: {} expand-template@2.0.3: {} @@ -18520,7 +18754,7 @@ snapshots: parseurl: 1.3.3 path-to-regexp: 0.1.12 proxy-addr: 2.0.7 - qs: 6.14.1 + qs: 6.14.2 range-parser: 1.2.1 safe-buffer: 5.2.1 send: 0.19.2 @@ -18558,6 +18792,8 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-fifo@1.3.2: {} + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -18570,8 +18806,18 @@ snapshots: fast-levenshtein@2.0.6: {} + fast-string-truncated-width@3.0.3: {} + + fast-string-width@3.0.2: + dependencies: + fast-string-truncated-width: 3.0.3 + fast-uri@3.1.0: {} + fast-wrap-ansi@0.2.0: + dependencies: + fast-string-width: 3.0.2 + fastq@1.20.1: dependencies: reusify: 1.1.0 @@ -18598,17 +18844,11 @@ snapshots: dependencies: flat-cache: 4.0.1 - file-loader@6.2.0(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))): - dependencies: - loader-utils: 2.0.4 - schema-utils: 3.3.0 - webpack: 5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18)) - file-uri-to-path@1.0.0: {} - filelist@1.0.4: + filelist@1.0.6: dependencies: - minimatch: 5.1.6 + minimatch: 5.1.9 fill-range@7.1.1: dependencies: @@ -18657,17 +18897,17 @@ snapshots: fix-dts-default-cjs-exports@1.0.1: dependencies: magic-string: 0.30.21 - mlly: 1.8.0 - rollup: 4.55.1 + mlly: 1.8.1 + rollup: 4.59.0 flat-cache@4.0.1: dependencies: - flatted: 3.3.3 + flatted: 3.3.4 keyv: 4.5.4 flat@5.0.2: {} - flatted@3.3.3: {} + flatted@3.3.4: {} follow-redirects@1.15.11(debug@4.4.3): optionalDependencies: @@ -18682,8 +18922,6 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - form-data-encoder@1.7.2: {} - form-data@4.0.5: dependencies: asynckit: 0.4.0 @@ -18692,11 +18930,6 @@ snapshots: hasown: 2.0.2 mime-types: 2.1.35 - formdata-node@4.4.1: - dependencies: - node-domexception: 1.0.0 - web-streams-polyfill: 4.0.0-beta.3 - formdata-polyfill@4.0.10: dependencies: fetch-blob: 3.2.0 @@ -18722,7 +18955,7 @@ snapshots: jsonfile: 6.2.0 universalify: 2.0.1 - fs-extra@11.3.3: + fs-extra@11.3.4: dependencies: graceful-fs: 4.2.11 jsonfile: 6.2.0 @@ -18753,13 +18986,10 @@ snapshots: fs-minipass@3.0.3: dependencies: - minipass: 7.1.2 + minipass: 7.1.3 fs.realpath@1.0.0: {} - fsevents@2.3.2: - optional: true - fsevents@2.3.3: optional: true @@ -18776,6 +19006,10 @@ snapshots: functions-have-names@1.2.3: {} + generate-function@2.3.1: + dependencies: + is-property: 1.0.2 + generator-function@2.0.1: {} generic-names@4.0.0: @@ -18786,7 +19020,7 @@ snapshots: get-caller-file@2.0.5: {} - get-east-asian-width@1.4.0: {} + get-east-asian-width@1.5.0: {} get-intrinsic@1.3.0: dependencies: @@ -18801,6 +19035,8 @@ snapshots: hasown: 2.0.2 math-intrinsics: 1.1.0 + get-port-please@3.2.0: {} + get-proto@1.0.1: dependencies: dunder-proto: 1.0.1 @@ -18808,7 +19044,7 @@ snapshots: get-stream@5.2.0: dependencies: - pump: 3.0.3 + pump: 3.0.4 get-symbol-description@1.1.0: dependencies: @@ -18816,7 +19052,7 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 - get-tsconfig@4.13.0: + get-tsconfig@4.13.6: dependencies: resolve-pkg-maps: 1.0.0 @@ -18845,32 +19081,23 @@ snapshots: dependencies: foreground-child: 3.3.1 jackspeak: 3.4.3 - minimatch: 9.0.5 - minipass: 7.1.2 + minimatch: 9.0.9 + minipass: 7.1.3 package-json-from-dist: 1.0.1 path-scurry: 1.11.1 - glob@11.1.0: - dependencies: - foreground-child: 3.3.1 - jackspeak: 4.1.1 - minimatch: 10.1.1 - minipass: 7.1.2 - package-json-from-dist: 1.0.1 - path-scurry: 2.0.1 - - glob@13.0.0: + glob@13.0.6: dependencies: - minimatch: 10.1.1 - minipass: 7.1.2 - path-scurry: 2.0.1 + minimatch: 10.2.4 + minipass: 7.1.3 + path-scurry: 2.0.2 glob@7.2.3: dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.1.2 + minimatch: 3.1.5 once: 1.4.0 path-is-absolute: 1.0.1 @@ -18879,7 +19106,7 @@ snapshots: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 5.1.6 + minimatch: 5.1.9 once: 1.4.0 global-agent@3.0.0: @@ -18908,7 +19135,7 @@ snapshots: globals@14.0.0: {} - globals@17.0.0: {} + globals@17.4.0: {} globalthis@1.0.4: dependencies: @@ -18924,7 +19151,7 @@ snapshots: slash: 5.1.0 unicorn-magic: 0.3.0 - globby@16.0.0: + globby@16.1.1: dependencies: '@sindresorhus/merge-streams': 4.0.0 fast-glob: 3.3.3 @@ -18957,6 +19184,10 @@ snapshots: graceful-fs@4.2.11: {} + grammex@3.1.12: {} + + graphmatch@1.1.1: {} + has-bigints@1.1.0: {} has-flag@4.0.0: {} @@ -19019,6 +19250,8 @@ snapshots: dependencies: parse-passwd: 1.0.0 + hono@4.11.4: {} + hosted-git-info@4.1.0: dependencies: lru-cache: 6.0.0 @@ -19029,7 +19262,7 @@ snapshots: hosted-git-info@9.0.2: dependencies: - lru-cache: 11.2.4 + lru-cache: 11.2.6 html-encoding-sniffer@3.0.0: dependencies: @@ -19107,6 +19340,8 @@ snapshots: - debug - supports-color + http-status-codes@2.3.0: {} + http2-wrapper@1.0.3: dependencies: quick-lru: 5.1.1 @@ -19119,10 +19354,6 @@ snapshots: transitivePeerDependencies: - supports-color - humanize-ms@1.2.1: - dependencies: - ms: 2.1.3 - iconv-corefoundation@1.1.7: dependencies: cli-truncate: 2.1.0 @@ -19137,15 +19368,13 @@ snapshots: dependencies: safer-buffer: 2.1.2 - iconv-lite@0.7.1: + iconv-lite@0.7.2: dependencies: safer-buffer: 2.1.2 - icss-replace-symbols@1.1.0: {} - - icss-utils@5.1.0(postcss@8.5.6): + icss-utils@5.1.0(postcss@8.5.8): dependencies: - postcss: 8.5.6 + postcss: 8.5.8 id128@1.6.6: {} @@ -19157,19 +19386,11 @@ snapshots: immediate@3.0.6: {} - import-cwd@3.0.0: - dependencies: - import-from: 3.0.0 - import-fresh@3.3.1: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 - import-from@3.0.0: - dependencies: - resolve-from: 5.0.0 - imurmurhash@0.1.4: {} indent-string@4.0.0: {} @@ -19244,7 +19465,7 @@ snapshots: is-bun-module@2.0.0: dependencies: - semver: 7.7.3 + semver: 7.7.4 is-callable@1.2.7: {} @@ -19318,6 +19539,8 @@ snapshots: is-plain-object@5.0.0: {} + is-property@1.0.2: {} + is-reference@1.2.1: dependencies: '@types/estree': 1.0.8 @@ -19335,6 +19558,8 @@ snapshots: dependencies: call-bound: 1.0.4 + is-stream@2.0.1: {} + is-string@1.1.1: dependencies: call-bound: 1.0.4 @@ -19348,7 +19573,7 @@ snapshots: is-typed-array@1.1.15: dependencies: - which-typed-array: 1.1.19 + which-typed-array: 1.1.20 is-unicode-supported@0.1.0: {} @@ -19373,7 +19598,7 @@ snapshots: dependencies: is-docker: 2.2.1 - is-wsl@3.1.0: + is-wsl@3.1.1: dependencies: is-inside-container: 1.0.0 @@ -19385,11 +19610,11 @@ snapshots: isbinaryfile@5.0.7: {} - isbot@5.1.32: {} + isbot@5.1.35: {} isexe@2.0.0: {} - isexe@3.1.1: {} + isexe@3.1.5: {} isomorphic-ws@5.0.0(ws@8.18.0): dependencies: @@ -19410,18 +19635,10 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 - jackspeak@4.1.1: - dependencies: - '@isaacs/cliui': 8.0.2 - - jackspeak@4.2.3: - dependencies: - '@isaacs/cliui': 9.0.0 - jake@10.9.4: dependencies: async: 3.2.6 - filelist: 1.0.4 + filelist: 1.0.6 picocolors: 1.1.1 jest-diff@30.2.0: @@ -19433,7 +19650,7 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 25.0.3 + '@types/node': 25.3.5 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -19441,7 +19658,7 @@ snapshots: jiti@2.6.1: {} - jose@6.1.3: {} + jose@6.2.0: {} joycon@3.1.1: {} @@ -19474,6 +19691,8 @@ snapshots: json-stringify-safe@5.0.1: optional: true + json-with-bigint@3.5.7: {} + json5@2.2.3: {} jsonc-parser@3.2.0: {} @@ -19516,8 +19735,6 @@ snapshots: kleur@3.0.3: {} - kleur@4.1.5: {} - koa-compose@4.1.0: {} koa@3.0.3: @@ -19553,6 +19770,10 @@ snapshots: lazy-val@1.0.5: {} + lazystream@1.0.1: + dependencies: + readable-stream: 2.3.8 + levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -19576,54 +19797,54 @@ snapshots: dependencies: immediate: 3.0.6 - lightningcss-android-arm64@1.30.2: + lightningcss-android-arm64@1.31.1: optional: true - lightningcss-darwin-arm64@1.30.2: + lightningcss-darwin-arm64@1.31.1: optional: true - lightningcss-darwin-x64@1.30.2: + lightningcss-darwin-x64@1.31.1: optional: true - lightningcss-freebsd-x64@1.30.2: + lightningcss-freebsd-x64@1.31.1: optional: true - lightningcss-linux-arm-gnueabihf@1.30.2: + lightningcss-linux-arm-gnueabihf@1.31.1: optional: true - lightningcss-linux-arm64-gnu@1.30.2: + lightningcss-linux-arm64-gnu@1.31.1: optional: true - lightningcss-linux-arm64-musl@1.30.2: + lightningcss-linux-arm64-musl@1.31.1: optional: true - lightningcss-linux-x64-gnu@1.30.2: + lightningcss-linux-x64-gnu@1.31.1: optional: true - lightningcss-linux-x64-musl@1.30.2: + lightningcss-linux-x64-musl@1.31.1: optional: true - lightningcss-win32-arm64-msvc@1.30.2: + lightningcss-win32-arm64-msvc@1.31.1: optional: true - lightningcss-win32-x64-msvc@1.30.2: + lightningcss-win32-x64-msvc@1.31.1: optional: true - lightningcss@1.30.2: + lightningcss@1.31.1: dependencies: detect-libc: 2.1.2 optionalDependencies: - lightningcss-android-arm64: 1.30.2 - lightningcss-darwin-arm64: 1.30.2 - lightningcss-darwin-x64: 1.30.2 - lightningcss-freebsd-x64: 1.30.2 - lightningcss-linux-arm-gnueabihf: 1.30.2 - lightningcss-linux-arm64-gnu: 1.30.2 - lightningcss-linux-arm64-musl: 1.30.2 - lightningcss-linux-x64-gnu: 1.30.2 - lightningcss-linux-x64-musl: 1.30.2 - lightningcss-win32-arm64-msvc: 1.30.2 - lightningcss-win32-x64-msvc: 1.30.2 + lightningcss-android-arm64: 1.31.1 + lightningcss-darwin-arm64: 1.31.1 + lightningcss-darwin-x64: 1.31.1 + lightningcss-freebsd-x64: 1.31.1 + lightningcss-linux-arm-gnueabihf: 1.31.1 + lightningcss-linux-arm64-gnu: 1.31.1 + lightningcss-linux-arm64-musl: 1.31.1 + lightningcss-linux-x64-gnu: 1.31.1 + lightningcss-linux-x64-musl: 1.31.1 + lightningcss-win32-arm64-msvc: 1.31.1 + lightningcss-win32-x64-msvc: 1.31.1 lilconfig@2.1.0: {} @@ -19633,20 +19854,14 @@ snapshots: lines-and-columns@2.0.3: {} - little-state-machine@4.8.1(react@19.2.3): + little-state-machine@4.8.1(react@19.2.4): dependencies: - react: 19.2.3 + react: 19.2.4 load-tsconfig@0.2.5: {} loader-runner@4.3.1: {} - loader-utils@2.0.4: - dependencies: - big.js: 5.2.2 - emojis-list: 3.0.0 - json5: 2.2.3 - loader-utils@3.3.1: {} locate-path@5.0.0: @@ -19667,12 +19882,8 @@ snapshots: lodash.isequal@4.5.0: {} - lodash.memoize@4.1.2: {} - lodash.merge@4.6.2: {} - lodash.uniq@4.5.0: {} - lodash@4.17.21: {} lodash@4.17.23: {} @@ -19691,7 +19902,7 @@ snapshots: dependencies: date-format: 4.0.14 debug: 4.4.3 - flatted: 3.3.3 + flatted: 3.3.4 rfdc: 1.4.1 streamroller: 3.1.5 transitivePeerDependencies: @@ -19699,6 +19910,8 @@ snapshots: long-timeout@0.1.1: {} + long@5.3.2: {} + longest-streak@3.1.0: {} loose-envify@1.4.0: @@ -19715,7 +19928,7 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.2.4: {} + lru-cache@11.2.6: {} lru-cache@5.1.1: dependencies: @@ -19725,6 +19938,8 @@ snapshots: dependencies: yallist: 4.0.0 + lru.min@1.1.4: {} + luxon@3.7.2: {} lz-string@1.5.0: {} @@ -19744,7 +19959,7 @@ snapshots: '@npmcli/agent': 3.0.0 cacache: 19.0.1 http-cache-semantics: 4.2.0 - minipass: 7.1.2 + minipass: 7.1.3 minipass-fetch: 4.0.1 minipass-flush: 1.0.5 minipass-pipeline: 1.2.4 @@ -19760,14 +19975,14 @@ snapshots: '@npmcli/agent': 4.0.0 cacache: 20.0.3 http-cache-semantics: 4.2.0 - minipass: 7.1.2 - minipass-fetch: 5.0.0 + minipass: 7.1.3 + minipass-fetch: 5.0.2 minipass-flush: 1.0.5 minipass-pipeline: 1.2.4 negotiator: 1.0.0 proc-log: 6.1.0 promise-retry: 2.0.1 - ssri: 13.0.0 + ssri: 13.0.1 transitivePeerDependencies: - supports-color @@ -19789,7 +20004,7 @@ snapshots: unist-util-is: 6.0.1 unist-util-visit-parents: 6.0.2 - mdast-util-from-markdown@2.0.2: + mdast-util-from-markdown@2.0.3: dependencies: '@types/mdast': 4.0.4 '@types/unist': 3.0.3 @@ -19818,7 +20033,7 @@ snapshots: dependencies: '@types/mdast': 4.0.4 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 micromark-util-normalize-identifier: 2.0.1 transitivePeerDependencies: @@ -19827,7 +20042,7 @@ snapshots: mdast-util-gfm-strikethrough@2.0.0: dependencies: '@types/mdast': 4.0.4 - mdast-util-from-markdown: 2.0.2 + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color @@ -19837,7 +20052,7 @@ snapshots: '@types/mdast': 4.0.4 devlop: 1.1.0 markdown-table: 3.0.4 - mdast-util-from-markdown: 2.0.2 + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color @@ -19846,14 +20061,14 @@ snapshots: dependencies: '@types/mdast': 4.0.4 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color mdast-util-gfm@3.1.0: dependencies: - mdast-util-from-markdown: 2.0.2 + mdast-util-from-markdown: 2.0.3 mdast-util-gfm-autolink-literal: 2.0.1 mdast-util-gfm-footnote: 2.1.0 mdast-util-gfm-strikethrough: 2.0.0 @@ -19869,7 +20084,7 @@ snapshots: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color @@ -19882,7 +20097,7 @@ snapshots: '@types/unist': 3.0.3 ccount: 2.0.1 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 parse-entities: 4.0.2 stringify-entities: 4.0.4 @@ -19897,7 +20112,7 @@ snapshots: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color @@ -19935,8 +20150,6 @@ snapshots: dependencies: '@types/mdast': 4.0.4 - mdn-data@2.0.14: {} - mdn-data@2.0.28: {} mdn-data@2.0.30: {} @@ -19947,6 +20160,8 @@ snapshots: media-typer@1.1.0: {} + memory-pager@1.5.0: {} + merge-descriptors@1.0.3: {} merge-stream@2.0.0: {} @@ -20181,27 +20396,23 @@ snapshots: mini-svg-data-uri@1.4.4: {} - minimatch@10.1.1: - dependencies: - '@isaacs/brace-expansion': 5.0.0 - - minimatch@10.2.1: + minimatch@10.2.4: dependencies: - brace-expansion: 5.0.2 + brace-expansion: 5.0.4 - minimatch@3.1.2: + minimatch@3.1.5: dependencies: brace-expansion: 1.1.12 - minimatch@5.1.6: + minimatch@5.1.9: dependencies: brace-expansion: 2.0.2 - minimatch@9.0.3: + minimatch@9.0.5: dependencies: brace-expansion: 2.0.2 - minimatch@9.0.5: + minimatch@9.0.9: dependencies: brace-expansion: 2.0.2 @@ -20209,23 +20420,23 @@ snapshots: minipass-collect@2.0.1: dependencies: - minipass: 7.1.2 + minipass: 7.1.3 minipass-fetch@4.0.1: dependencies: - minipass: 7.1.2 + minipass: 7.1.3 minipass-sized: 1.0.3 minizlib: 3.1.0 optionalDependencies: encoding: 0.1.13 - minipass-fetch@5.0.0: + minipass-fetch@5.0.2: dependencies: - minipass: 7.1.2 - minipass-sized: 1.0.3 + minipass: 7.1.3 + minipass-sized: 2.0.0 minizlib: 3.1.0 optionalDependencies: - encoding: 0.1.13 + iconv-lite: 0.7.2 minipass-flush@1.0.5: dependencies: @@ -20239,13 +20450,17 @@ snapshots: dependencies: minipass: 3.3.6 + minipass-sized@2.0.0: + dependencies: + minipass: 7.1.3 + minipass@3.3.6: dependencies: yallist: 4.0.0 minipass@5.0.0: {} - minipass@7.1.2: {} + minipass@7.1.3: {} minizlib@2.1.2: dependencies: @@ -20254,7 +20469,7 @@ snapshots: minizlib@3.1.0: dependencies: - minipass: 7.1.2 + minipass: 7.1.3 mkdirp-classic@0.5.3: {} @@ -20264,14 +20479,25 @@ snapshots: mkdirp@1.0.4: {} - mlly@1.8.0: + mlly@1.8.1: dependencies: - acorn: 8.15.0 + acorn: 8.16.0 pathe: 2.0.3 pkg-types: 1.3.1 - ufo: 1.6.2 + ufo: 1.6.3 - mri@1.2.0: {} + mongodb-connection-string-url@7.0.1: + dependencies: + '@types/whatwg-url': 13.0.0 + whatwg-url: 14.2.0 + + mongodb@7.1.0(socks@2.8.7): + dependencies: + '@mongodb-js/saslprep': 1.4.6 + bson: 7.2.0 + mongodb-connection-string-url: 7.0.1 + optionalDependencies: + socks: 2.8.7 ms@2.0.0: {} @@ -20299,15 +20525,31 @@ snapshots: mute-stream@3.0.0: {} + mysql2@3.15.3: + dependencies: + aws-ssl-profiles: 1.1.2 + denque: 2.1.0 + generate-function: 2.3.1 + iconv-lite: 0.7.2 + long: 5.3.2 + lru.min: 1.1.4 + named-placeholders: 1.1.6 + seq-queue: 0.0.5 + sqlstring: 2.3.3 + mz@2.7.0: dependencies: any-promise: 1.3.0 object-assign: 4.1.1 thenify-all: 1.6.0 + named-placeholders@1.1.6: + dependencies: + lru.min: 1.1.4 + nanoid@3.3.11: {} - nanostores@1.1.0: {} + nanostores@1.1.1: {} napi-build-utils@2.0.0: {} @@ -20332,9 +20574,9 @@ snapshots: dependencies: semver: 7.7.4 - node-abi@4.24.0: + node-abi@4.26.0: dependencies: - semver: 7.7.3 + semver: 7.7.4 node-addon-api@1.7.2: optional: true @@ -20343,9 +20585,17 @@ snapshots: node-api-version@0.2.1: dependencies: - semver: 7.7.3 + semver: 7.7.4 - node-domexception@1.0.0: {} + node-domexception@1.0.0: + optional: true + + node-exports-info@1.6.0: + dependencies: + array.prototype.flatmap: 1.3.3 + es-errors: 1.3.0 + object.entries: 1.1.9 + semver: 6.3.1 node-fetch-native@1.6.7: {} @@ -20377,8 +20627,8 @@ snapshots: make-fetch-happen: 14.0.3 nopt: 8.1.0 proc-log: 5.0.0 - semver: 7.7.3 - tar: 7.5.2 + semver: 7.7.4 + tar: 7.5.10 tinyglobby: 0.2.15 which: 5.0.0 transitivePeerDependencies: @@ -20386,7 +20636,7 @@ snapshots: node-machine-id@1.1.12: {} - node-releases@2.0.27: {} + node-releases@2.0.36: {} node-schedule@2.1.1: dependencies: @@ -20406,7 +20656,7 @@ snapshots: dependencies: hosted-git-info: 8.1.0 proc-log: 5.0.0 - semver: 7.7.3 + semver: 7.7.4 validate-npm-package-name: 6.0.2 npm-package-arg@13.0.2: @@ -20421,8 +20671,8 @@ snapshots: '@npmcli/redact': 4.0.0 jsonparse: 1.3.1 make-fetch-happen: 15.0.3 - minipass: 7.1.2 - minipass-fetch: 5.0.0 + minipass: 7.1.3 + minipass-fetch: 5.0.2 minizlib: 3.1.0 npm-package-arg: 13.0.2 proc-log: 6.1.0 @@ -20437,19 +20687,19 @@ snapshots: dependencies: boolbase: 1.0.0 - nx@22.3.3(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.18)): + nx@22.5.4(@swc-node/register@1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.8(@swc/helpers@0.5.19)): dependencies: '@napi-rs/wasm-runtime': 0.2.4 '@yarnpkg/lockfile': 1.1.0 '@yarnpkg/parsers': 3.0.2 '@zkochan/js-yaml': 0.0.7 - axios: 1.13.2 - chalk: 4.1.2 + axios: 1.13.6 cli-cursor: 3.1.0 cli-spinners: 2.6.1 cliui: 8.0.1 dotenv: 16.4.7 dotenv-expand: 11.0.7 + ejs: 3.1.10 enquirer: 2.3.6 figures: 3.2.0 flat: 5.0.2 @@ -20458,11 +20708,12 @@ snapshots: jest-diff: 30.2.0 jsonc-parser: 3.2.0 lines-and-columns: 2.0.3 - minimatch: 9.0.3 + minimatch: 10.2.4 node-machine-id: 1.1.12 npm-run-path: 4.0.1 open: 8.4.2 ora: 5.3.0 + picocolors: 1.1.1 resolve.exports: 2.0.3 semver: 7.7.4 string-width: 4.2.3 @@ -20475,18 +20726,18 @@ snapshots: yargs: 17.7.2 yargs-parser: 21.1.1 optionalDependencies: - '@nx/nx-darwin-arm64': 22.3.3 - '@nx/nx-darwin-x64': 22.3.3 - '@nx/nx-freebsd-x64': 22.3.3 - '@nx/nx-linux-arm-gnueabihf': 22.3.3 - '@nx/nx-linux-arm64-gnu': 22.3.3 - '@nx/nx-linux-arm64-musl': 22.3.3 - '@nx/nx-linux-x64-gnu': 22.3.3 - '@nx/nx-linux-x64-musl': 22.3.3 - '@nx/nx-win32-arm64-msvc': 22.3.3 - '@nx/nx-win32-x64-msvc': 22.3.3 - '@swc-node/register': 1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3) - '@swc/core': 1.15.8(@swc/helpers@0.5.18) + '@nx/nx-darwin-arm64': 22.5.4 + '@nx/nx-darwin-x64': 22.5.4 + '@nx/nx-freebsd-x64': 22.5.4 + '@nx/nx-linux-arm-gnueabihf': 22.5.4 + '@nx/nx-linux-arm64-gnu': 22.5.4 + '@nx/nx-linux-arm64-musl': 22.5.4 + '@nx/nx-linux-x64-gnu': 22.5.4 + '@nx/nx-linux-x64-musl': 22.5.4 + '@nx/nx-win32-arm64-msvc': 22.5.4 + '@nx/nx-win32-x64-msvc': 22.5.4 + '@swc-node/register': 1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3) + '@swc/core': 1.15.8(@swc/helpers@0.5.19) transitivePeerDependencies: - debug @@ -20554,7 +20805,7 @@ snapshots: open@10.2.0: dependencies: - default-browser: 5.4.0 + default-browser: 5.5.0 define-lazy-prop: 3.0.0 is-inside-container: 1.0.0 wsl-utils: 0.1.0 @@ -20565,19 +20816,10 @@ snapshots: is-docker: 2.2.1 is-wsl: 2.2.0 - openai@4.77.0(encoding@0.1.13)(zod@3.25.76): - dependencies: - '@types/node': 18.19.130 - '@types/node-fetch': 2.6.13 - abort-controller: 3.0.0 - agentkeepalive: 4.6.0 - form-data-encoder: 1.7.2 - formdata-node: 4.4.1 - node-fetch: 2.7.0(encoding@0.1.13) + openai@6.27.0(ws@8.19.0)(zod@4.3.6): optionalDependencies: - zod: 3.25.76 - transitivePeerDependencies: - - encoding + ws: 8.19.0 + zod: 4.3.6 opener@1.5.2: {} @@ -20595,7 +20837,7 @@ snapshots: bl: 4.1.0 chalk: 4.1.2 cli-cursor: 3.1.0 - cli-spinners: 2.9.2 + cli-spinners: 2.6.1 is-interactive: 1.0.0 log-symbols: 4.1.0 strip-ansi: 6.0.1 @@ -20623,7 +20865,7 @@ snapshots: log-symbols: 6.0.0 stdin-discarder: 0.2.2 string-width: 7.2.0 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 own-keys@1.0.1: dependencies: @@ -20631,33 +20873,31 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 - oxc-resolver@11.16.2: + oxc-resolver@11.19.1: optionalDependencies: - '@oxc-resolver/binding-android-arm-eabi': 11.16.2 - '@oxc-resolver/binding-android-arm64': 11.16.2 - '@oxc-resolver/binding-darwin-arm64': 11.16.2 - '@oxc-resolver/binding-darwin-x64': 11.16.2 - '@oxc-resolver/binding-freebsd-x64': 11.16.2 - '@oxc-resolver/binding-linux-arm-gnueabihf': 11.16.2 - '@oxc-resolver/binding-linux-arm-musleabihf': 11.16.2 - '@oxc-resolver/binding-linux-arm64-gnu': 11.16.2 - '@oxc-resolver/binding-linux-arm64-musl': 11.16.2 - '@oxc-resolver/binding-linux-ppc64-gnu': 11.16.2 - '@oxc-resolver/binding-linux-riscv64-gnu': 11.16.2 - '@oxc-resolver/binding-linux-riscv64-musl': 11.16.2 - '@oxc-resolver/binding-linux-s390x-gnu': 11.16.2 - '@oxc-resolver/binding-linux-x64-gnu': 11.16.2 - '@oxc-resolver/binding-linux-x64-musl': 11.16.2 - '@oxc-resolver/binding-openharmony-arm64': 11.16.2 - '@oxc-resolver/binding-wasm32-wasi': 11.16.2 - '@oxc-resolver/binding-win32-arm64-msvc': 11.16.2 - '@oxc-resolver/binding-win32-ia32-msvc': 11.16.2 - '@oxc-resolver/binding-win32-x64-msvc': 11.16.2 + '@oxc-resolver/binding-android-arm-eabi': 11.19.1 + '@oxc-resolver/binding-android-arm64': 11.19.1 + '@oxc-resolver/binding-darwin-arm64': 11.19.1 + '@oxc-resolver/binding-darwin-x64': 11.19.1 + '@oxc-resolver/binding-freebsd-x64': 11.19.1 + '@oxc-resolver/binding-linux-arm-gnueabihf': 11.19.1 + '@oxc-resolver/binding-linux-arm-musleabihf': 11.19.1 + '@oxc-resolver/binding-linux-arm64-gnu': 11.19.1 + '@oxc-resolver/binding-linux-arm64-musl': 11.19.1 + '@oxc-resolver/binding-linux-ppc64-gnu': 11.19.1 + '@oxc-resolver/binding-linux-riscv64-gnu': 11.19.1 + '@oxc-resolver/binding-linux-riscv64-musl': 11.19.1 + '@oxc-resolver/binding-linux-s390x-gnu': 11.19.1 + '@oxc-resolver/binding-linux-x64-gnu': 11.19.1 + '@oxc-resolver/binding-linux-x64-musl': 11.19.1 + '@oxc-resolver/binding-openharmony-arm64': 11.19.1 + '@oxc-resolver/binding-wasm32-wasi': 11.19.1 + '@oxc-resolver/binding-win32-arm64-msvc': 11.19.1 + '@oxc-resolver/binding-win32-ia32-msvc': 11.19.1 + '@oxc-resolver/binding-win32-x64-msvc': 11.19.1 p-cancelable@2.1.1: {} - p-finally@1.0.0: {} - p-limit@2.3.0: dependencies: p-try: 2.2.0 @@ -20676,15 +20916,6 @@ snapshots: p-map@7.0.4: {} - p-queue@6.6.2: - dependencies: - eventemitter3: 4.0.7 - p-timeout: 3.2.0 - - p-timeout@3.2.0: - dependencies: - p-finally: 1.0.0 - p-try@2.2.0: {} package-json-from-dist@1.0.1: {} @@ -20707,7 +20938,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.27.1 + '@babel/code-frame': 7.29.0 error-ex: 1.3.4 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -20727,12 +20958,12 @@ snapshots: path-scurry@1.11.1: dependencies: lru-cache: 10.4.3 - minipass: 7.1.2 + minipass: 7.1.3 - path-scurry@2.0.1: + path-scurry@2.0.2: dependencies: - lru-cache: 11.2.4 - minipass: 7.1.2 + lru-cache: 11.2.6 + minipass: 7.1.3 path-to-regexp@0.1.12: {} @@ -20748,20 +20979,22 @@ snapshots: pend@1.2.0: {} + perfect-debounce@1.0.0: {} + perfect-debounce@2.1.0: {} pg-cloudflare@1.3.0: optional: true - pg-connection-string@2.11.0: {} + pg-connection-string@2.12.0: {} pg-int8@1.0.1: {} - pg-pool@3.11.0(pg@8.18.0): + pg-pool@3.13.0(pg@8.20.0): dependencies: - pg: 8.18.0 + pg: 8.20.0 - pg-protocol@1.11.0: {} + pg-protocol@1.13.0: {} pg-types@2.2.0: dependencies: @@ -20771,11 +21004,11 @@ snapshots: postgres-date: 1.0.7 postgres-interval: 1.2.0 - pg@8.18.0: + pg@8.20.0: dependencies: - pg-connection-string: 2.11.0 - pg-pool: 3.11.0(pg@8.18.0) - pg-protocol: 1.11.0 + pg-connection-string: 2.12.0 + pg-pool: 3.13.0(pg@8.20.0) + pg-protocol: 1.13.0 pg-types: 2.2.0 pgpass: 1.0.5 optionalDependencies: @@ -20793,10 +21026,6 @@ snapshots: picomatch@4.0.3: {} - pify@2.3.0: {} - - pify@5.0.0: {} - pirates@4.0.7: {} pkg-dir@4.2.0: @@ -20806,7 +21035,7 @@ snapshots: pkg-types@1.3.1: dependencies: confbox: 0.1.8 - mlly: 1.8.0 + mlly: 1.8.1 pathe: 2.0.3 pkg-types@2.3.0: @@ -20815,14 +21044,6 @@ snapshots: exsolve: 1.0.8 pathe: 2.0.3 - playwright-core@1.57.0: {} - - playwright@1.57.0: - dependencies: - playwright-core: 1.57.0 - optionalDependencies: - fsevents: 2.3.2 - plist@3.1.0: dependencies: '@xmldom/xmldom': 0.8.11 @@ -20838,200 +21059,48 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss-calc@8.2.4(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - postcss-selector-parser: 6.0.10 - postcss-value-parser: 4.2.0 - - postcss-colormin@5.3.1(postcss@8.5.6): - dependencies: - browserslist: 4.28.1 - caniuse-api: 3.0.0 - colord: 2.9.3 - postcss: 8.5.6 - postcss-value-parser: 4.2.0 - - postcss-convert-values@5.1.3(postcss@8.5.6): - dependencies: - browserslist: 4.28.1 - postcss: 8.5.6 - postcss-value-parser: 4.2.0 - - postcss-discard-comments@5.1.2(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - - postcss-discard-duplicates@5.1.0(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - - postcss-discard-empty@5.1.1(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - - postcss-discard-overridden@5.1.0(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - - postcss-import@16.1.1(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - postcss-value-parser: 4.2.0 - read-cache: 1.0.0 - resolve: 1.22.11 - - postcss-load-config@3.1.4(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.15.8(@swc/helpers@0.5.18))(@types/node@25.0.3)(typescript@5.9.3)): - dependencies: - lilconfig: 2.1.0 - yaml: 1.10.2 - optionalDependencies: - postcss: 8.5.6 - ts-node: 10.9.2(@swc/core@1.15.8(@swc/helpers@0.5.18))(@types/node@25.0.3)(typescript@5.9.3) - - postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.2): + postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2): dependencies: lilconfig: 3.1.3 optionalDependencies: jiti: 2.6.1 - postcss: 8.5.6 + postcss: 8.5.8 tsx: 4.21.0 yaml: 2.8.2 - postcss-merge-longhand@5.1.7(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - postcss-value-parser: 4.2.0 - stylehacks: 5.1.1(postcss@8.5.6) - - postcss-merge-rules@5.1.4(postcss@8.5.6): - dependencies: - browserslist: 4.28.1 - caniuse-api: 3.0.0 - cssnano-utils: 3.1.0(postcss@8.5.6) - postcss: 8.5.6 - postcss-selector-parser: 6.0.10 - - postcss-minify-font-values@5.1.0(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - postcss-value-parser: 4.2.0 - - postcss-minify-gradients@5.1.1(postcss@8.5.6): + postcss-modules-extract-imports@3.1.0(postcss@8.5.8): dependencies: - colord: 2.9.3 - cssnano-utils: 3.1.0(postcss@8.5.6) - postcss: 8.5.6 - postcss-value-parser: 4.2.0 + postcss: 8.5.8 - postcss-minify-params@5.1.4(postcss@8.5.6): + postcss-modules-local-by-default@4.2.0(postcss@8.5.8): dependencies: - browserslist: 4.28.1 - cssnano-utils: 3.1.0(postcss@8.5.6) - postcss: 8.5.6 - postcss-value-parser: 4.2.0 - - postcss-minify-selectors@5.2.1(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - postcss-selector-parser: 6.0.10 - - postcss-modules-extract-imports@3.1.0(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - - postcss-modules-local-by-default@4.2.0(postcss@8.5.6): - dependencies: - icss-utils: 5.1.0(postcss@8.5.6) - postcss: 8.5.6 + icss-utils: 5.1.0(postcss@8.5.8) + postcss: 8.5.8 postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 - postcss-modules-scope@3.2.1(postcss@8.5.6): + postcss-modules-scope@3.2.1(postcss@8.5.8): dependencies: - postcss: 8.5.6 + postcss: 8.5.8 postcss-selector-parser: 7.1.1 - postcss-modules-values@4.0.0(postcss@8.5.6): + postcss-modules-values@4.0.0(postcss@8.5.8): dependencies: - icss-utils: 5.1.0(postcss@8.5.6) - postcss: 8.5.6 + icss-utils: 5.1.0(postcss@8.5.8) + postcss: 8.5.8 - postcss-modules@4.3.1(postcss@8.5.6): + postcss-modules@6.0.1(postcss@8.5.8): dependencies: generic-names: 4.0.0 - icss-replace-symbols: 1.1.0 + icss-utils: 5.1.0(postcss@8.5.8) lodash.camelcase: 4.3.0 - postcss: 8.5.6 - postcss-modules-extract-imports: 3.1.0(postcss@8.5.6) - postcss-modules-local-by-default: 4.2.0(postcss@8.5.6) - postcss-modules-scope: 3.2.1(postcss@8.5.6) - postcss-modules-values: 4.0.0(postcss@8.5.6) + postcss: 8.5.8 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.8) + postcss-modules-local-by-default: 4.2.0(postcss@8.5.8) + postcss-modules-scope: 3.2.1(postcss@8.5.8) + postcss-modules-values: 4.0.0(postcss@8.5.8) string-hash: 1.1.3 - postcss-normalize-charset@5.1.0(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - - postcss-normalize-display-values@5.1.0(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - postcss-value-parser: 4.2.0 - - postcss-normalize-positions@5.1.1(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - postcss-value-parser: 4.2.0 - - postcss-normalize-repeat-style@5.1.1(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - postcss-value-parser: 4.2.0 - - postcss-normalize-string@5.1.0(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - postcss-value-parser: 4.2.0 - - postcss-normalize-timing-functions@5.1.0(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - postcss-value-parser: 4.2.0 - - postcss-normalize-unicode@5.1.1(postcss@8.5.6): - dependencies: - browserslist: 4.28.1 - postcss: 8.5.6 - postcss-value-parser: 4.2.0 - - postcss-normalize-url@5.1.0(postcss@8.5.6): - dependencies: - normalize-url: 6.1.0 - postcss: 8.5.6 - postcss-value-parser: 4.2.0 - - postcss-normalize-whitespace@5.1.1(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - postcss-value-parser: 4.2.0 - - postcss-ordered-values@5.1.3(postcss@8.5.6): - dependencies: - cssnano-utils: 3.1.0(postcss@8.5.6) - postcss: 8.5.6 - postcss-value-parser: 4.2.0 - - postcss-reduce-initial@5.1.2(postcss@8.5.6): - dependencies: - browserslist: 4.28.1 - caniuse-api: 3.0.0 - postcss: 8.5.6 - - postcss-reduce-transforms@5.1.0(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - postcss-value-parser: 4.2.0 - postcss-selector-parser@6.0.10: dependencies: cssesc: 3.0.0 @@ -21042,20 +21111,9 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-svgo@5.1.0(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - postcss-value-parser: 4.2.0 - svgo: 2.8.0 - - postcss-unique-selectors@5.1.1(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - postcss-selector-parser: 6.0.10 - postcss-value-parser@4.2.0: {} - postcss@8.5.6: + postcss@8.5.8: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 @@ -21071,12 +21129,14 @@ snapshots: dependencies: xtend: 4.0.2 + postgres@3.4.7: {} + postject@1.0.0-alpha.6: dependencies: commander: 9.5.0 optional: true - preact@10.28.2: {} + preact@10.28.4: {} prebuild-install@7.1.3: dependencies: @@ -21087,7 +21147,7 @@ snapshots: mkdirp-classic: 0.5.3 napi-build-utils: 2.0.0 node-abi: 3.87.0 - pump: 3.0.3 + pump: 3.0.4 rc: 1.2.8 simple-get: 4.0.1 tar-fs: 2.1.4 @@ -21095,10 +21155,6 @@ snapshots: prelude-ls@1.2.1: {} - prettier@3.6.2: {} - - prettier@3.7.4: {} - prettier@3.8.1: {} pretty-format@27.5.1: @@ -21113,12 +21169,31 @@ snapshots: ansi-styles: 5.2.0 react-is: 18.3.1 + prisma@7.4.2(@types/react@19.2.14)(better-sqlite3@12.6.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3): + dependencies: + '@prisma/config': 7.4.2 + '@prisma/dev': 0.20.0(typescript@5.9.3) + '@prisma/engines': 7.4.2 + '@prisma/studio-core': 0.13.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + mysql2: 3.15.3 + postgres: 3.4.7 + optionalDependencies: + better-sqlite3: 12.6.2 + typescript: 5.9.3 + transitivePeerDependencies: + - '@types/react' + - magicast + - react + - react-dom + proc-log@5.0.0: {} proc-log@6.1.0: {} process-nextick-args@2.0.1: {} + process@0.11.10: {} + progress@2.0.3: {} promise-limit@2.7.0: @@ -21129,8 +21204,6 @@ snapshots: err-code: 2.0.3 retry: 0.12.0 - promise.series@0.2.0: {} - prompts@2.4.2: dependencies: kleur: 3.0.3 @@ -21142,6 +21215,12 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 + proper-lockfile@4.1.2: + dependencies: + graceful-fs: 4.2.11 + retry: 0.12.0 + signal-exit: 3.0.7 + property-information@7.1.0: {} proxy-addr@2.0.7: @@ -21151,7 +21230,7 @@ snapshots: proxy-from-env@1.1.0: {} - pump@3.0.3: + pump@3.0.4: dependencies: end-of-stream: 1.4.5 once: 1.4.0 @@ -21160,7 +21239,11 @@ snapshots: pure-rand@6.1.0: {} - qs@6.14.1: + qs@6.14.2: + dependencies: + side-channel: 1.1.0 + + qs@6.15.0: dependencies: side-channel: 1.1.0 @@ -21170,10 +21253,6 @@ snapshots: rambda@9.4.2: {} - randombytes@2.1.0: - dependencies: - safe-buffer: 5.2.1 - range-parser@1.2.1: {} raw-body@2.5.3: @@ -21195,86 +21274,86 @@ snapshots: minimist: 1.2.8 strip-json-comments: 2.0.1 - react-aria-components@1.14.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + react-aria-components@1.16.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: - '@internationalized/date': 3.10.1 + '@internationalized/date': 3.12.0 '@internationalized/string': 3.2.7 - '@react-aria/autocomplete': 3.0.0-rc.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/collections': 3.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/dnd': 3.11.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/focus': 3.21.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@react-aria/autocomplete': 3.0.0-rc.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/collections': 3.0.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/dnd': 3.11.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/focus': 3.21.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@react-aria/live-announcer': 3.4.4 - '@react-aria/overlays': 3.31.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/ssr': 3.9.10(react@19.2.3) - '@react-aria/textfield': 3.18.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/toolbar': 3.0.0-beta.22(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/virtualizer': 4.1.11(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/autocomplete': 3.0.0-beta.4(react@19.2.3) - '@react-stately/layout': 4.5.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-stately/selection': 3.20.7(react@19.2.3) - '@react-stately/table': 3.15.2(patch_hash=5ac384399a7b8e18c4e19f25e434b2f2f27fbd45e7a91cdeb30408330b7243b4)(react@19.2.3) - '@react-stately/utils': 3.11.0(react@19.2.3) - '@react-stately/virtualizer': 4.4.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-types/form': 3.7.16(react@19.2.3) - '@react-types/grid': 3.3.6(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - '@react-types/table': 3.13.4(react@19.2.3) - '@swc/helpers': 0.5.18 + '@react-aria/overlays': 3.31.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/ssr': 3.9.10(react@19.2.4) + '@react-aria/textfield': 3.18.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/toolbar': 3.0.0-beta.24(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/virtualizer': 4.1.13(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/autocomplete': 3.0.0-beta.4(react@19.2.4) + '@react-stately/layout': 4.6.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/selection': 3.20.9(react@19.2.4) + '@react-stately/table': 3.15.4(patch_hash=5ac384399a7b8e18c4e19f25e434b2f2f27fbd45e7a91cdeb30408330b7243b4)(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-stately/virtualizer': 4.4.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/form': 3.7.18(react@19.2.4) + '@react-types/grid': 3.3.8(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + '@react-types/table': 3.13.6(react@19.2.4) + '@swc/helpers': 0.5.19 client-only: 0.0.1 - react: 19.2.3 - react-aria: 3.45.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react-dom: 19.2.3(react@19.2.3) - react-stately: 3.43.0(react@19.2.3) - use-sync-external-store: 1.6.0(react@19.2.3) + react: 19.2.4 + react-aria: 3.47.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react-dom: 19.2.4(react@19.2.4) + react-stately: 3.45.0(react@19.2.4) + use-sync-external-store: 1.6.0(react@19.2.4) - react-aria@3.45.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + react-aria@3.47.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: '@internationalized/string': 3.2.7 - '@react-aria/breadcrumbs': 3.5.30(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/button': 3.14.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/calendar': 3.9.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/checkbox': 3.16.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/color': 3.1.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/combobox': 3.14.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/datepicker': 3.15.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/dialog': 3.5.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/disclosure': 3.1.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/dnd': 3.11.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/focus': 3.21.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/gridlist': 3.14.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/i18n': 3.12.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/interactions': 3.26.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/label': 3.7.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/landmark': 3.0.8(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/link': 3.8.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/listbox': 3.15.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/menu': 3.19.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/meter': 3.4.28(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/numberfield': 3.12.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/overlays': 3.31.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/progress': 3.4.28(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/radio': 3.12.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/searchfield': 3.8.10(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/select': 3.17.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/selection': 3.27.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/separator': 3.4.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/slider': 3.8.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/ssr': 3.9.10(react@19.2.3) - '@react-aria/switch': 3.7.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/table': 3.17.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/tabs': 3.10.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/tag': 3.7.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/textfield': 3.18.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/toast': 3.0.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/tooltip': 3.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/tree': 3.1.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/utils': 3.32.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-aria/visually-hidden': 3.8.29(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@react-aria/breadcrumbs': 3.5.32(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/button': 3.14.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/calendar': 3.9.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/checkbox': 3.16.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/color': 3.1.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/combobox': 3.15.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/datepicker': 3.16.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/dialog': 3.5.34(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/disclosure': 3.1.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/dnd': 3.11.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/focus': 3.21.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/gridlist': 3.14.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/label': 3.7.25(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/landmark': 3.0.10(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/link': 3.8.9(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/listbox': 3.15.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/menu': 3.21.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/meter': 3.4.30(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/numberfield': 3.12.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/overlays': 3.31.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/progress': 3.4.30(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/radio': 3.12.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/searchfield': 3.8.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/select': 3.17.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/selection': 3.27.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/separator': 3.4.16(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/slider': 3.8.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/ssr': 3.9.10(react@19.2.4) + '@react-aria/switch': 3.7.11(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/table': 3.17.11(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/tabs': 3.11.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/tag': 3.8.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/textfield': 3.18.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/toast': 3.0.11(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/tooltip': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/tree': 3.1.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/visually-hidden': 3.8.31(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) react-docgen-typescript@2.4.0(typescript@5.9.3): dependencies: @@ -21282,9 +21361,9 @@ snapshots: react-docgen@8.0.2: dependencies: - '@babel/core': 7.28.5 - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/core': 7.29.0 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 '@types/babel__core': 7.20.5 '@types/babel__traverse': 7.28.0 '@types/doctrine': 0.0.9 @@ -21295,23 +21374,22 @@ snapshots: transitivePeerDependencies: - supports-color - react-dom@19.2.3(react@19.2.3): + react-dom@19.2.4(react@19.2.4): dependencies: - react: 19.2.3 + react: 19.2.4 scheduler: 0.27.0 - react-error-boundary@6.0.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + react-error-boundary@6.1.1(react@19.2.4): dependencies: - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + react: 19.2.4 - react-hook-form@7.70.0(react@19.2.3): + react-hook-form@7.70.0(react@19.2.4): dependencies: - react: 19.2.3 + react: 19.2.4 - react-icons@5.5.0(react@19.2.3): + react-icons@5.6.0(react@19.2.4): dependencies: - react: 19.2.3 + react: 19.2.4 react-is@16.13.1: {} @@ -21319,16 +21397,16 @@ snapshots: react-is@18.3.1: {} - react-markdown@10.1.0(@types/react@19.2.7)(react@19.2.3): + react-markdown@10.1.0(@types/react@19.2.14)(react@19.2.4): dependencies: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 - '@types/react': 19.2.7 + '@types/react': 19.2.14 devlop: 1.1.0 hast-util-to-jsx-runtime: 2.3.6 html-url-attributes: 3.0.1 mdast-util-to-hast: 13.2.1 - react: 19.2.3 + react: 19.2.4 remark-parse: 11.0.0 remark-rehype: 11.1.2 unified: 11.0.5 @@ -21339,32 +21417,28 @@ snapshots: react-refresh@0.18.0: {} - react-resizable-panels@4.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + react-resizable-panels@4.7.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - react-scan@0.4.3(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.55.1): + react-scan@0.5.3(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.59.0): dependencies: - '@babel/core': 7.28.5 - '@babel/generator': 7.28.5 - '@babel/types': 7.28.5 - '@clack/core': 0.3.5 - '@clack/prompts': 0.8.2 - '@pivanov/utils': 0.0.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@preact/signals': 1.3.2(preact@10.28.2) - '@rollup/pluginutils': 5.3.0(rollup@4.55.1) - '@types/node': 20.19.27 - bippy: 0.3.34(@types/react@19.2.7)(react@19.2.3) + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/types': 7.29.0 + '@preact/signals': 1.3.4(preact@10.28.4) + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) + '@types/node': 20.19.37 + bippy: 0.5.30(@types/react@19.2.14)(react@19.2.4) + commander: 14.0.3 esbuild: 0.25.12 estree-walker: 3.0.3 - kleur: 4.1.5 - mri: 1.2.0 - playwright: 1.57.0 - preact: 10.28.2 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - tsx: 4.21.0 + picocolors: 1.1.1 + preact: 10.28.4 + prompts: 2.4.2 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: unplugin: 2.1.0 transitivePeerDependencies: @@ -21372,45 +21446,45 @@ snapshots: - rollup - supports-color - react-simple-animate@3.5.3(react-dom@19.2.3(react@19.2.3)): - dependencies: - react-dom: 19.2.3(react@19.2.3) - - react-stately@3.43.0(react@19.2.3): - dependencies: - '@react-stately/calendar': 3.9.1(react@19.2.3) - '@react-stately/checkbox': 3.7.3(react@19.2.3) - '@react-stately/collections': 3.12.8(react@19.2.3) - '@react-stately/color': 3.9.3(react@19.2.3) - '@react-stately/combobox': 3.12.1(react@19.2.3) - '@react-stately/data': 3.15.0(react@19.2.3) - '@react-stately/datepicker': 3.15.3(react@19.2.3) - '@react-stately/disclosure': 3.0.9(react@19.2.3) - '@react-stately/dnd': 3.7.2(react@19.2.3) - '@react-stately/form': 3.2.2(react@19.2.3) - '@react-stately/list': 3.13.2(react@19.2.3) - '@react-stately/menu': 3.9.9(react@19.2.3) - '@react-stately/numberfield': 3.10.3(react@19.2.3) - '@react-stately/overlays': 3.6.21(react@19.2.3) - '@react-stately/radio': 3.11.3(react@19.2.3) - '@react-stately/searchfield': 3.5.17(react@19.2.3) - '@react-stately/select': 3.9.0(react@19.2.3) - '@react-stately/selection': 3.20.7(react@19.2.3) - '@react-stately/slider': 3.7.3(react@19.2.3) - '@react-stately/table': 3.15.2(patch_hash=5ac384399a7b8e18c4e19f25e434b2f2f27fbd45e7a91cdeb30408330b7243b4)(react@19.2.3) - '@react-stately/tabs': 3.8.7(react@19.2.3) - '@react-stately/toast': 3.1.2(react@19.2.3) - '@react-stately/toggle': 3.9.3(react@19.2.3) - '@react-stately/tooltip': 3.5.9(react@19.2.3) - '@react-stately/tree': 3.9.4(react@19.2.3) - '@react-types/shared': 3.32.1(react@19.2.3) - react: 19.2.3 - - react-timeago@8.3.0(react@19.2.3): - dependencies: - react: 19.2.3 - - react@19.2.3: {} + react-simple-animate@3.5.3(react-dom@19.2.4(react@19.2.4)): + dependencies: + react-dom: 19.2.4(react@19.2.4) + + react-stately@3.45.0(react@19.2.4): + dependencies: + '@react-stately/calendar': 3.9.3(react@19.2.4) + '@react-stately/checkbox': 3.7.5(react@19.2.4) + '@react-stately/collections': 3.12.10(react@19.2.4) + '@react-stately/color': 3.9.5(react@19.2.4) + '@react-stately/combobox': 3.13.0(react@19.2.4) + '@react-stately/data': 3.15.2(react@19.2.4) + '@react-stately/datepicker': 3.16.1(react@19.2.4) + '@react-stately/disclosure': 3.0.11(react@19.2.4) + '@react-stately/dnd': 3.7.4(react@19.2.4) + '@react-stately/form': 3.2.4(react@19.2.4) + '@react-stately/list': 3.13.4(react@19.2.4) + '@react-stately/menu': 3.9.11(react@19.2.4) + '@react-stately/numberfield': 3.11.0(react@19.2.4) + '@react-stately/overlays': 3.6.23(react@19.2.4) + '@react-stately/radio': 3.11.5(react@19.2.4) + '@react-stately/searchfield': 3.5.19(react@19.2.4) + '@react-stately/select': 3.9.2(react@19.2.4) + '@react-stately/selection': 3.20.9(react@19.2.4) + '@react-stately/slider': 3.7.5(react@19.2.4) + '@react-stately/table': 3.15.4(patch_hash=5ac384399a7b8e18c4e19f25e434b2f2f27fbd45e7a91cdeb30408330b7243b4)(react@19.2.4) + '@react-stately/tabs': 3.8.9(react@19.2.4) + '@react-stately/toast': 3.1.3(react@19.2.4) + '@react-stately/toggle': 3.9.5(react@19.2.4) + '@react-stately/tooltip': 3.5.11(react@19.2.4) + '@react-stately/tree': 3.9.6(react@19.2.4) + '@react-types/shared': 3.33.1(react@19.2.4) + react: 19.2.4 + + react-timeago@8.3.0(react@19.2.4): + dependencies: + react: 19.2.4 + + react@19.2.4: {} read-binary-file-arch@1.0.6: dependencies: @@ -21418,10 +21492,6 @@ snapshots: transitivePeerDependencies: - supports-color - read-cache@1.0.0: - dependencies: - pify: 2.3.0 - read-yaml-file@2.1.0: dependencies: js-yaml: 4.1.1 @@ -21443,6 +21513,18 @@ snapshots: string_decoder: 1.3.0 util-deprecate: 1.0.2 + readable-stream@4.7.0: + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + + readdir-glob@1.1.3: + dependencies: + minimatch: 5.1.9 + readdirp@3.6.0: dependencies: picomatch: 2.3.1 @@ -21521,7 +21603,7 @@ snapshots: remark-parse@11.0.0: dependencies: '@types/mdast': 4.0.4 - mdast-util-from-markdown: 2.0.2 + mdast-util-from-markdown: 2.0.3 micromark-util-types: 2.0.2 unified: 11.0.5 transitivePeerDependencies: @@ -21541,6 +21623,8 @@ snapshots: mdast-util-to-markdown: 2.1.2 unified: 11.0.5 + remeda@2.33.4: {} + require-directory@2.1.1: {} require-from-string@2.0.2: {} @@ -21578,9 +21662,12 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - resolve@2.0.0-next.5: + resolve@2.0.0-next.6: dependencies: + es-errors: 1.3.0 is-core-module: 2.16.1 + node-exports-info: 1.6.0 + object-keys: 1.1.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 @@ -21618,68 +21705,45 @@ snapshots: sprintf-js: 1.1.3 optional: true - rollup-plugin-postcss@4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.15.8(@swc/helpers@0.5.18))(@types/node@25.0.3)(typescript@5.9.3)): - dependencies: - chalk: 4.1.2 - concat-with-sourcemaps: 1.1.0 - cssnano: 5.1.15(postcss@8.5.6) - import-cwd: 3.0.0 - p-queue: 6.6.2 - pify: 5.0.0 - postcss: 8.5.6 - postcss-load-config: 3.1.4(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.15.8(@swc/helpers@0.5.18))(@types/node@25.0.3)(typescript@5.9.3)) - postcss-modules: 4.3.1(postcss@8.5.6) - promise.series: 0.2.0 - resolve: 1.22.11 - rollup-pluginutils: 2.8.2 - safe-identifier: 0.4.2 - style-inject: 0.3.0 - transitivePeerDependencies: - - ts-node - - rollup-plugin-typescript2@0.36.0(rollup@4.55.1)(typescript@5.9.3): + rollup-plugin-typescript2@0.36.0(rollup@4.59.0)(typescript@5.9.3): dependencies: '@rollup/pluginutils': 4.2.1 find-cache-dir: 3.3.2 fs-extra: 10.1.0 - rollup: 4.55.1 + rollup: 4.59.0 semver: 7.7.4 tslib: 2.8.1 typescript: 5.9.3 - rollup-pluginutils@2.8.2: - dependencies: - estree-walker: 0.6.1 - - rollup@4.55.1: + rollup@4.59.0: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.55.1 - '@rollup/rollup-android-arm64': 4.55.1 - '@rollup/rollup-darwin-arm64': 4.55.1 - '@rollup/rollup-darwin-x64': 4.55.1 - '@rollup/rollup-freebsd-arm64': 4.55.1 - '@rollup/rollup-freebsd-x64': 4.55.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.55.1 - '@rollup/rollup-linux-arm-musleabihf': 4.55.1 - '@rollup/rollup-linux-arm64-gnu': 4.55.1 - '@rollup/rollup-linux-arm64-musl': 4.55.1 - '@rollup/rollup-linux-loong64-gnu': 4.55.1 - '@rollup/rollup-linux-loong64-musl': 4.55.1 - '@rollup/rollup-linux-ppc64-gnu': 4.55.1 - '@rollup/rollup-linux-ppc64-musl': 4.55.1 - '@rollup/rollup-linux-riscv64-gnu': 4.55.1 - '@rollup/rollup-linux-riscv64-musl': 4.55.1 - '@rollup/rollup-linux-s390x-gnu': 4.55.1 - '@rollup/rollup-linux-x64-gnu': 4.55.1 - '@rollup/rollup-linux-x64-musl': 4.55.1 - '@rollup/rollup-openbsd-x64': 4.55.1 - '@rollup/rollup-openharmony-arm64': 4.55.1 - '@rollup/rollup-win32-arm64-msvc': 4.55.1 - '@rollup/rollup-win32-ia32-msvc': 4.55.1 - '@rollup/rollup-win32-x64-gnu': 4.55.1 - '@rollup/rollup-win32-x64-msvc': 4.55.1 + '@rollup/rollup-android-arm-eabi': 4.59.0 + '@rollup/rollup-android-arm64': 4.59.0 + '@rollup/rollup-darwin-arm64': 4.59.0 + '@rollup/rollup-darwin-x64': 4.59.0 + '@rollup/rollup-freebsd-arm64': 4.59.0 + '@rollup/rollup-freebsd-x64': 4.59.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 + '@rollup/rollup-linux-arm-musleabihf': 4.59.0 + '@rollup/rollup-linux-arm64-gnu': 4.59.0 + '@rollup/rollup-linux-arm64-musl': 4.59.0 + '@rollup/rollup-linux-loong64-gnu': 4.59.0 + '@rollup/rollup-linux-loong64-musl': 4.59.0 + '@rollup/rollup-linux-ppc64-gnu': 4.59.0 + '@rollup/rollup-linux-ppc64-musl': 4.59.0 + '@rollup/rollup-linux-riscv64-gnu': 4.59.0 + '@rollup/rollup-linux-riscv64-musl': 4.59.0 + '@rollup/rollup-linux-s390x-gnu': 4.59.0 + '@rollup/rollup-linux-x64-gnu': 4.59.0 + '@rollup/rollup-linux-x64-musl': 4.59.0 + '@rollup/rollup-openbsd-x64': 4.59.0 + '@rollup/rollup-openharmony-arm64': 4.59.0 + '@rollup/rollup-win32-arm64-msvc': 4.59.0 + '@rollup/rollup-win32-ia32-msvc': 4.59.0 + '@rollup/rollup-win32-x64-gnu': 4.59.0 + '@rollup/rollup-win32-x64-msvc': 4.59.0 fsevents: 2.3.3 rou3@0.7.12: {} @@ -21702,8 +21766,6 @@ snapshots: safe-buffer@5.2.1: {} - safe-identifier@0.4.2: {} - safe-push-apply@1.0.0: dependencies: es-errors: 1.3.0 @@ -21721,22 +21783,16 @@ snapshots: dependencies: truncate-utf8-bytes: 1.0.2 - sax@1.4.3: {} + sax@1.5.0: {} scheduler@0.27.0: {} - schema-utils@3.3.0: - dependencies: - '@types/json-schema': 7.0.15 - ajv: 6.12.6 - ajv-keywords: 3.5.2(ajv@6.12.6) - schema-utils@4.3.3: dependencies: '@types/json-schema': 7.0.15 - ajv: 8.17.1 - ajv-formats: 2.1.1(ajv@8.17.1) - ajv-keywords: 5.1.0(ajv@8.17.1) + ajv: 8.18.0 + ajv-formats: 2.1.1(ajv@8.18.0) + ajv-keywords: 5.1.0(ajv@8.18.0) secure-compare@3.0.1: {} @@ -21751,8 +21807,6 @@ snapshots: semver@7.7.2: {} - semver@7.7.3: {} - semver@7.7.4: {} send@0.19.2: @@ -21773,26 +21827,26 @@ snapshots: transitivePeerDependencies: - supports-color + seq-queue@0.0.5: {} + serialize-error@7.0.1: dependencies: type-fest: 0.13.1 optional: true - serialize-javascript@6.0.2: - dependencies: - randombytes: 2.1.0 - seroval-plugins@1.3.3(seroval@1.3.2): dependencies: seroval: 1.3.2 + optional: true - seroval-plugins@1.4.2(seroval@1.4.2): + seroval-plugins@1.5.0(seroval@1.5.0): dependencies: - seroval: 1.4.2 + seroval: 1.5.0 - seroval@1.3.2: {} + seroval@1.3.2: + optional: true - seroval@1.4.2: {} + seroval@1.5.0: {} serve-static@1.16.3: dependencies: @@ -21805,6 +21859,8 @@ snapshots: set-cookie-parser@2.7.2: {} + set-cookie-parser@3.0.1: {} + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -21881,7 +21937,7 @@ snapshots: simple-update-notifier@2.0.0: dependencies: - semver: 7.7.3 + semver: 7.7.4 sisteransi@1.0.5: {} @@ -21919,6 +21975,7 @@ snapshots: csstype: 3.2.3 seroval: 1.3.2 seroval-plugins: 1.3.3(seroval@1.3.2) + optional: true sorted-array-functions@1.3.0: {} @@ -21944,6 +22001,10 @@ snapshots: space-separated-tokens@2.0.2: {} + sparse-bitfield@3.0.3: + dependencies: + memory-pager: 1.5.0 + split2@4.2.0: {} sprintf-js@1.0.3: {} @@ -21951,18 +22012,18 @@ snapshots: sprintf-js@1.1.3: optional: true + sqlstring@2.3.3: {} + ssri@12.0.0: dependencies: - minipass: 7.1.2 + minipass: 7.1.3 - ssri@13.0.0: + ssri@13.0.1: dependencies: - minipass: 7.1.2 + minipass: 7.1.3 stable-hash-x@0.2.0: {} - stable@0.1.8: {} - stackback@0.0.2: {} stat-mode@1.0.0: {} @@ -21980,42 +22041,19 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 - storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.7.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: '@storybook/global': 5.0.0 - '@storybook/icons': 2.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@storybook/icons': 2.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@testing-library/jest-dom': 6.9.1 '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.1) '@vitest/expect': 3.2.4 '@vitest/spy': 3.2.4 - esbuild: 0.27.2 + esbuild: 0.27.3 open: 10.2.0 recast: 0.23.11 - semver: 7.7.3 - use-sync-external-store: 1.6.0(react@19.2.3) - ws: 8.19.0 - optionalDependencies: - prettier: 3.7.4 - transitivePeerDependencies: - - '@testing-library/dom' - - bufferutil - - react - - react-dom - - utf-8-validate - - storybook@10.1.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@storybook/global': 5.0.0 - '@storybook/icons': 2.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@testing-library/jest-dom': 6.9.1 - '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.1) - '@vitest/expect': 3.2.4 - '@vitest/spy': 3.2.4 - esbuild: 0.27.2 - open: 10.2.0 - recast: 0.23.11 - semver: 7.7.3 - use-sync-external-store: 1.6.0(react@19.2.3) + semver: 7.7.4 + use-sync-external-store: 1.6.0(react@19.2.4) ws: 8.19.0 optionalDependencies: prettier: 3.8.1 @@ -22034,6 +22072,15 @@ snapshots: transitivePeerDependencies: - supports-color + streamx@2.23.0: + dependencies: + events-universal: 1.0.1 + fast-fifo: 1.3.2 + text-decoder: 1.2.7 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + string-hash@1.1.3: {} string-width@4.2.3: @@ -22046,13 +22093,13 @@ snapshots: dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 string-width@7.2.0: dependencies: emoji-regex: 10.6.0 - get-east-asian-width: 1.4.0 - strip-ansi: 7.1.2 + get-east-asian-width: 1.5.0 + strip-ansi: 7.2.0 string.prototype.includes@2.0.1: dependencies: @@ -22121,7 +22168,7 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.2: + strip-ansi@7.2.0: dependencies: ansi-regex: 6.2.2 @@ -22139,8 +22186,6 @@ snapshots: strip-json-comments@3.1.1: {} - style-inject@0.3.0: {} - style-mod@4.1.3: {} style-to-js@1.1.21: @@ -22151,12 +22196,6 @@ snapshots: dependencies: inline-style-parser: 0.2.7 - stylehacks@5.1.1(postcss@8.5.6): - dependencies: - browserslist: 4.28.1 - postcss: 8.5.6 - postcss-selector-parser: 6.0.10 - stylis@4.2.0: {} sucrase@3.35.1: @@ -22187,36 +22226,26 @@ snapshots: svg-parser@2.0.4: {} - svgo@2.8.0: + svgo@3.3.3: dependencies: - '@trysound/sax': 0.2.0 - commander: 7.2.0 - css-select: 4.3.0 - css-tree: 1.1.3 - csso: 4.2.0 - picocolors: 1.1.1 - stable: 0.1.8 - - svgo@3.3.2: - dependencies: - '@trysound/sax': 0.2.0 commander: 7.2.0 css-select: 5.2.2 css-tree: 2.3.1 css-what: 6.2.2 csso: 5.0.5 picocolors: 1.1.1 + sax: 1.5.0 - swc-node@1.0.0(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3): + swc-node@1.0.0(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3): dependencies: - '@swc-node/register': 1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3) + '@swc-node/register': 1.11.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(@swc/types@0.1.25)(typescript@5.9.3) transitivePeerDependencies: - '@swc/core' - '@swc/types' - supports-color - typescript - synckit@0.11.11: + synckit@0.11.12: dependencies: '@pkgr/core': 0.2.9 @@ -22225,8 +22254,8 @@ snapshots: chalk: 5.6.2 chalk-template: 1.1.2 commander: 13.1.0 - cosmiconfig: 9.0.0(typescript@5.9.3) - effect: 3.19.14 + cosmiconfig: 9.0.1(typescript@5.9.3) + effect: 3.19.19 enquirer: 2.4.1 fast-check: 3.23.2 globby: 14.1.0 @@ -22236,7 +22265,7 @@ snapshots: ora: 8.2.0 prompts: 2.4.2 read-yaml-file: 2.1.0 - semver: 7.7.3 + semver: 7.7.4 tightrope: 0.2.0 ts-toolbelt: 9.6.0 transitivePeerDependencies: @@ -22244,19 +22273,19 @@ snapshots: tailwind-csstree@0.1.4: {} - tailwind-merge@3.4.0: {} + tailwind-merge@3.5.0: {} - tailwind-variants@3.2.2(tailwind-merge@3.4.0)(tailwindcss@4.1.18): + tailwind-variants@3.2.2(tailwind-merge@3.5.0)(tailwindcss@4.2.1): dependencies: - tailwindcss: 4.1.18 + tailwindcss: 4.2.1 optionalDependencies: - tailwind-merge: 3.4.0 + tailwind-merge: 3.5.0 - tailwindcss-react-aria-components@2.0.1(tailwindcss@4.1.18): + tailwindcss-react-aria-components@2.0.1(tailwindcss@4.2.1): dependencies: - tailwindcss: 4.1.18 + tailwindcss: 4.2.1 - tailwindcss@4.1.18: {} + tailwindcss@4.2.1: {} tapable@2.3.0: {} @@ -22264,7 +22293,7 @@ snapshots: dependencies: chownr: 1.1.4 mkdirp-classic: 0.5.3 - pump: 3.0.3 + pump: 3.0.4 tar-stream: 2.2.0 tar-stream@2.2.0: @@ -22275,6 +22304,17 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 + tar-stream@3.1.8: + dependencies: + b4a: 1.8.0 + bare-fs: 4.5.5 + fast-fifo: 1.3.2 + streamx: 2.23.0 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + tar@6.2.1: dependencies: chownr: 2.0.0 @@ -22284,14 +22324,21 @@ snapshots: mkdirp: 1.0.4 yallist: 4.0.0 - tar@7.5.2: + tar@7.5.10: dependencies: '@isaacs/fs-minipass': 4.0.1 chownr: 3.0.0 - minipass: 7.1.2 + minipass: 7.1.3 minizlib: 3.1.0 yallist: 5.0.0 + teex@1.0.1: + dependencies: + streamx: 2.23.0 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + temp-file@3.4.0: dependencies: async-exit-hook: 2.0.1 @@ -22308,37 +22355,41 @@ snapshots: temporal-spec@0.3.0: {} - terser-webpack-plugin@5.3.16(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2)(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2)): + terser-webpack-plugin@5.3.17(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3)(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - serialize-javascript: 6.0.2 - terser: 5.44.1 - webpack: 5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2) + terser: 5.46.0 + webpack: 5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3) optionalDependencies: - '@swc/core': 1.15.8(@swc/helpers@0.5.18) - esbuild: 0.27.2 + '@swc/core': 1.15.8(@swc/helpers@0.5.19) + esbuild: 0.27.3 optional: true - terser-webpack-plugin@5.3.16(@swc/core@1.15.8(@swc/helpers@0.5.18))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))): + terser-webpack-plugin@5.3.17(@swc/core@1.15.8(@swc/helpers@0.5.19))(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - serialize-javascript: 6.0.2 - terser: 5.44.1 - webpack: 5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18)) + terser: 5.46.0 + webpack: 5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19)) optionalDependencies: - '@swc/core': 1.15.8(@swc/helpers@0.5.18) + '@swc/core': 1.15.8(@swc/helpers@0.5.19) - terser@5.44.1: + terser@5.46.0: dependencies: '@jridgewell/source-map': 0.3.11 - acorn: 8.15.0 + acorn: 8.16.0 commander: 2.20.3 source-map-support: 0.5.21 + text-decoder@1.2.7: + dependencies: + b4a: 1.8.0 + transitivePeerDependencies: + - react-native-b4a + thenify-all@1.6.0: dependencies: thenify: 3.3.1 @@ -22392,6 +22443,10 @@ snapshots: tr46@0.0.3: {} + tr46@5.1.1: + dependencies: + punycode: 2.3.1 + tree-kill@1.2.2: {} trim-lines@3.0.1: {} @@ -22410,25 +22465,25 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-node@10.9.2(@swc/core@1.15.8(@swc/helpers@0.5.18))(@types/node@25.0.3)(typescript@5.9.3): + ts-node@10.9.2(@swc/core@1.15.8(@swc/helpers@0.5.19))(@types/node@25.3.5)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.12 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 25.0.3 - acorn: 8.15.0 - acorn-walk: 8.3.4 + '@types/node': 25.3.5 + acorn: 8.16.0 + acorn-walk: 8.3.5 arg: 4.1.3 create-require: 1.1.1 - diff: 4.0.2 + diff: 4.0.4 make-error: 1.3.6 typescript: 5.9.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: - '@swc/core': 1.15.8(@swc/helpers@0.5.18) + '@swc/core': 1.15.8(@swc/helpers@0.5.19) ts-toolbelt@9.6.0: {} @@ -22439,7 +22494,7 @@ snapshots: tsconfig-paths-webpack-plugin@4.2.0: dependencies: chalk: 4.1.2 - enhanced-resolve: 5.18.4 + enhanced-resolve: 5.20.0 tapable: 2.3.0 tsconfig-paths: 4.2.0 @@ -22453,28 +22508,28 @@ snapshots: tsscmp@1.0.6: {} - tsup@8.5.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2): + tsup@8.5.1(@swc/core@1.15.8(@swc/helpers@0.5.19))(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2): dependencies: - bundle-require: 5.1.0(esbuild@0.27.2) + bundle-require: 5.1.0(esbuild@0.27.3) cac: 6.7.14 chokidar: 4.0.3 consola: 3.4.2 debug: 4.4.3 - esbuild: 0.27.2 + esbuild: 0.27.3 fix-dts-default-cjs-exports: 1.0.1 joycon: 3.1.1 picocolors: 1.1.1 - postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.2) + postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2) resolve-from: 5.0.0 - rollup: 4.55.1 + rollup: 4.59.0 source-map: 0.7.6 sucrase: 3.35.1 tinyexec: 0.3.2 tinyglobby: 0.2.15 tree-kill: 1.2.2 optionalDependencies: - '@swc/core': 1.15.8(@swc/helpers@0.5.18) - postcss: 8.5.6 + '@swc/core': 1.15.8(@swc/helpers@0.5.19) + postcss: 8.5.8 typescript: 5.9.3 transitivePeerDependencies: - jiti @@ -22484,8 +22539,8 @@ snapshots: tsx@4.21.0: dependencies: - esbuild: 0.27.2 - get-tsconfig: 4.13.0 + esbuild: 0.27.3 + get-tsconfig: 4.13.6 optionalDependencies: fsevents: 2.3.3 @@ -22546,12 +22601,12 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): + typescript-eslint@8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.52.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/parser': 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.52.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: @@ -22561,7 +22616,7 @@ snapshots: typescript@5.9.3: {} - ufo@1.6.2: {} + ufo@1.6.3: {} unbox-primitive@1.1.0: dependencies: @@ -22570,13 +22625,13 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 - undici-types@5.26.5: {} - undici-types@6.21.0: {} undici-types@7.16.0: {} - undici@7.18.2: {} + undici-types@7.18.2: {} + + undici@7.22.0: {} unicode-canonical-property-names-ecmascript@2.0.1: {} @@ -22605,7 +22660,7 @@ snapshots: union@0.5.0: dependencies: - qs: 6.14.1 + qs: 6.15.0 unique-filename@4.0.0: dependencies: @@ -22656,14 +22711,14 @@ snapshots: unplugin@2.1.0: dependencies: - acorn: 8.15.0 + acorn: 8.16.0 webpack-virtual-modules: 0.6.2 optional: true unplugin@2.3.11: dependencies: '@jridgewell/remapping': 2.3.5 - acorn: 8.15.0 + acorn: 8.16.0 picomatch: 4.0.3 webpack-virtual-modules: 0.6.2 @@ -22711,19 +22766,19 @@ snapshots: url-join@4.0.1: {} - use-debounce@10.0.6(react@19.2.3): + use-debounce@10.1.0(react@19.2.4): dependencies: - react: 19.2.3 + react: 19.2.4 - use-deep-compare-effect@1.8.1(react@19.2.3): + use-deep-compare-effect@1.8.1(react@19.2.4): dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 dequal: 2.0.3 - react: 19.2.3 + react: 19.2.4 - use-sync-external-store@1.6.0(react@19.2.3): + use-sync-external-store@1.6.0(react@19.2.4): dependencies: - react: 19.2.3 + react: 19.2.4 utf8-byte-length@1.0.5: {} @@ -22737,6 +22792,10 @@ snapshots: v8-compile-cache-lib@3.0.1: {} + valibot@1.2.0(typescript@5.9.3): + optionalDependencies: + typescript: 5.9.3 + validate-html-nesting@1.2.4: {} validate-npm-package-name@6.0.2: {} @@ -22762,38 +22821,37 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite-tsconfig-paths@6.0.3(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)): + vite-tsconfig-paths@6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): dependencies: debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.9.3) - optionalDependencies: - vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color - typescript - vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): + vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: - esbuild: 0.27.2 + esbuild: 0.27.3 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 - postcss: 8.5.6 - rollup: 4.55.1 + postcss: 8.5.8 + rollup: 4.59.0 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 25.0.3 + '@types/node': 25.3.5 fsevents: 2.3.3 jiti: 2.6.1 - lightningcss: 1.30.2 - terser: 5.44.1 + lightningcss: 1.31.1 + terser: 5.46.0 tsx: 4.21.0 yaml: 2.8.2 - vitest@4.0.18(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): + vitest@4.0.18(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@vitest/pretty-format': 4.0.18 '@vitest/runner': 4.0.18 '@vitest/snapshot': 4.0.18 @@ -22810,10 +22868,10 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 25.0.3 + '@types/node': 25.3.5 transitivePeerDependencies: - jiti - less @@ -22844,7 +22902,7 @@ snapshots: w3c-keyname@2.2.8: {} - watchpack@2.5.0: + watchpack@2.5.1: dependencies: glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 @@ -22856,15 +22914,15 @@ snapshots: web-streams-polyfill@3.3.3: optional: true - web-streams-polyfill@4.0.0-beta.3: {} - webidl-conversions@3.0.1: {} - webpack-sources@3.3.3: {} + webidl-conversions@7.0.0: {} + + webpack-sources@3.3.4: {} webpack-virtual-modules@0.6.2: {} - webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18)): + webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19)): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -22872,11 +22930,11 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.15.0 - acorn-import-phases: 1.0.4(acorn@8.15.0) + acorn: 8.16.0 + acorn-import-phases: 1.0.4(acorn@8.16.0) browserslist: 4.28.1 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.18.4 + enhanced-resolve: 5.20.0 es-module-lexer: 2.0.0 eslint-scope: 5.1.1 events: 3.3.0 @@ -22888,15 +22946,15 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.0 - terser-webpack-plugin: 5.3.16(@swc/core@1.15.8(@swc/helpers@0.5.18))(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))) - watchpack: 2.5.0 - webpack-sources: 3.3.3 + terser-webpack-plugin: 5.3.17(@swc/core@1.15.8(@swc/helpers@0.5.19))(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))) + watchpack: 2.5.1 + webpack-sources: 3.3.4 transitivePeerDependencies: - '@swc/core' - esbuild - uglify-js - webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2): + webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -22904,11 +22962,11 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.15.0 - acorn-import-phases: 1.0.4(acorn@8.15.0) + acorn: 8.16.0 + acorn-import-phases: 1.0.4(acorn@8.16.0) browserslist: 4.28.1 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.18.4 + enhanced-resolve: 5.20.0 es-module-lexer: 2.0.0 eslint-scope: 5.1.1 events: 3.3.0 @@ -22920,9 +22978,9 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.0 - terser-webpack-plugin: 5.3.16(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2)(webpack@5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.27.2)) - watchpack: 2.5.0 - webpack-sources: 3.3.3 + terser-webpack-plugin: 5.3.17(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3)(webpack@5.105.4(@swc/core@1.15.8(@swc/helpers@0.5.19))(esbuild@0.27.3)) + watchpack: 2.5.1 + webpack-sources: 3.3.4 transitivePeerDependencies: - '@swc/core' - esbuild @@ -22933,6 +22991,11 @@ snapshots: dependencies: iconv-lite: 0.6.3 + whatwg-url@14.2.0: + dependencies: + tr46: 5.1.1 + webidl-conversions: 7.0.0 + whatwg-url@5.0.0: dependencies: tr46: 0.0.3 @@ -22960,7 +23023,7 @@ snapshots: isarray: 2.0.5 which-boxed-primitive: 1.1.1 which-collection: 1.0.2 - which-typed-array: 1.1.19 + which-typed-array: 1.1.20 which-collection@1.0.2: dependencies: @@ -22969,7 +23032,7 @@ snapshots: is-weakmap: 2.0.2 is-weakset: 2.0.4 - which-typed-array@1.1.19: + which-typed-array@1.1.20: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.8 @@ -22989,7 +23052,7 @@ snapshots: which@5.0.0: dependencies: - isexe: 3.1.1 + isexe: 3.1.5 why-is-node-running@2.3.0: dependencies: @@ -23008,13 +23071,13 @@ snapshots: dependencies: ansi-styles: 6.2.3 string-width: 5.1.2 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 wrap-ansi@9.0.2: dependencies: ansi-styles: 6.2.3 string-width: 7.2.0 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 wrappy@1.0.2: {} @@ -23024,7 +23087,7 @@ snapshots: wsl-utils@0.1.0: dependencies: - is-wsl: 3.1.0 + is-wsl: 3.1.1 xmlbuilder@15.1.1: {} @@ -23082,21 +23145,30 @@ snapshots: yoctocolors@2.1.2: {} - zod-validation-error@4.0.2(zod@4.3.5): + zeptomatch@2.1.0: dependencies: - zod: 4.3.5 + grammex: 3.1.12 + graphmatch: 1.1.1 - zod@3.25.76: {} + zip-stream@6.0.1: + dependencies: + archiver-utils: 5.0.2 + compress-commons: 6.0.2 + readable-stream: 4.7.0 + + zod-validation-error@4.0.2(zod@4.3.6): + dependencies: + zod: 4.3.6 - zod@4.3.5: {} + zod@3.25.76: {} zod@4.3.6: {} - zustand@4.5.7(@types/react@19.2.7)(react@19.2.3): + zustand@4.5.7(@types/react@19.2.14)(react@19.2.4): dependencies: - use-sync-external-store: 1.6.0(react@19.2.3) + use-sync-external-store: 1.6.0(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - react: 19.2.3 + '@types/react': 19.2.14 + react: 19.2.4 zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index cb3a6875f..fcaab6fcd 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -4,131 +4,133 @@ packages: - packages/* catalog: - '@aikidosec/safe-chain': 1.4.0 + '@aikidosec/safe-chain': 1.4.4 '@alloy-js/cli': 0.22.0 '@alloy-js/core': 0.22.0 '@alloy-js/typescript': 0.22.0 - '@better-auth/cli': 1.4.18 - '@bufbuild/buf': 1.63.0 - '@bufbuild/protobuf': 2.10.2 - '@bufbuild/protoc-gen-es': 2.10.2 - '@bufbuild/protovalidate': 1.1.0 - '@codemirror/autocomplete': 6.20.0 - '@codemirror/commands': 6.10.1 + '@better-auth/cli': 1.4.21 + '@bufbuild/buf': 1.66.0 + '@bufbuild/protobuf': 2.11.0 + '@bufbuild/protoc-gen-es': 2.11.0 + '@bufbuild/protovalidate': 1.1.1 + '@codemirror/autocomplete': 6.20.1 + '@codemirror/commands': 6.10.2 '@codemirror/lang-html': 6.4.11 - '@codemirror/lang-javascript': 6.2.4 + '@codemirror/lang-javascript': 6.2.5 '@codemirror/lang-json': 6.0.2 '@codemirror/lang-xml': 6.1.0 - '@codemirror/language': 6.12.1 - '@codemirror/state': 6.5.3 - '@codemirror/view': 6.39.9 + '@codemirror/language': 6.12.2 + '@codemirror/state': 6.5.4 + '@codemirror/view': 6.39.16 '@connectrpc/connect': 2.1.1 '@connectrpc/connect-node': 2.1.1 '@connectrpc/connect-query': 2.2.0 '@connectrpc/connect-web': 2.1.1 - '@effect-atom/atom-react': 0.4.4 - '@effect/cli': 0.73.0 - '@effect/platform': 0.94.1 + '@effect-atom/atom-react': 0.5.0 + '@effect/cli': 0.73.2 + '@effect/platform': 0.94.5 '@effect/platform-browser': 0.74.0 - '@effect/platform-node': 0.104.0 - '@eslint/compat': 2.0.0 + '@effect/platform-node': 0.104.1 + '@eslint/compat': 2.0.2 '@eslint/js': 9.39.2 - '@faker-js/faker': 10.2.0 + '@faker-js/faker': 10.3.0 '@fontsource-variable/dm-sans': 5.2.8 '@fontsource/dm-mono': 5.2.7 '@hookform/devtools': 4.4.0 '@hookform/resolvers': 5.2.2 '@lezer/generator': 1.8.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.7 - '@nx/eslint': 22.3.3 - '@nx/js': 22.3.3 - '@nx/react': 22.3.3 - '@nx/storybook': 22.3.3 - '@nx/vite': 22.3.3 - '@nx/web': 22.3.3 + '@lezer/lr': 1.4.8 + '@nx/eslint': 22.5.4 + '@nx/js': 22.5.4 + '@nx/react': 22.5.4 + '@nx/storybook': 22.5.4 + '@nx/vite': 22.5.4 + '@nx/web': 22.5.4 '@octokit/auth-action': 6.0.2 '@octokit/rest': 22.0.1 '@prettier/plugin-xml': 3.4.2 - '@react-aria/collections': 3.0.1 + '@react-aria/collections': 3.0.3 '@standard-schema/spec': 1.1.0 - '@storybook/addon-docs': 10.1.11 - '@storybook/react': 10.1.11 - '@storybook/react-vite': 10.1.11 + '@storybook/addon-docs': 10.2.16 + '@storybook/react': 10.2.16 + '@storybook/react-vite': 10.2.16 '@tailwindcss/typography': 0.5.19 - '@tailwindcss/vite': 4.1.18 - '@tanstack/eslint-plugin-router': 1.141.0 - '@tanstack/react-db': 0.1.60 - '@tanstack/react-query': 5.90.16 - '@tanstack/react-query-devtools': 5.91.2 - '@tanstack/react-router': 1.145.7 - '@tanstack/react-router-devtools': 1.145.7 - '@tanstack/router-plugin': 1.145.10 - '@tanstack/virtual-file-routes': 1.145.4 + '@tailwindcss/vite': 4.2.1 + '@tanstack/eslint-plugin-router': 1.161.4 + '@tanstack/react-db': 0.1.74 + '@tanstack/react-query': 5.90.21 + '@tanstack/react-query-devtools': 5.91.3 + '@tanstack/react-router': 1.166.2 + '@tanstack/react-router-devtools': 1.166.2 + '@tanstack/router-plugin': 1.166.2 + '@tanstack/virtual-file-routes': 1.161.4 '@tsconfig/strictest': 2.0.8 '@types/eslint-plugin-jsx-a11y': 6.10.1 - '@types/node': 25.0.3 - '@types/react': 19.2.7 + '@types/node': 25.3.5 + '@types/react': 19.2.14 '@types/react-dom': 19.2.3 '@types/react-timeago': 8.0.0 - '@typescript-eslint/parser': 8.52.0 - '@typespec/compiler': 1.7.1 - '@typespec/emitter-framework': 0.14.0 - '@typespec/prettier-plugin-typespec': 1.7.0 - '@uiw/react-codemirror': 4.25.4 - '@vitejs/plugin-react': 5.1.2 + '@typescript-eslint/parser': 8.56.1 + '@typespec/compiler': 1.9.0 + '@typespec/emitter-framework': 0.16.0 + '@typespec/prettier-plugin-typespec': 1.9.0 + '@uiw/react-codemirror': 4.25.7 + '@vitejs/plugin-react': 5.1.4 '@xyflow/react': 12.10.1 babel-plugin-react-compiler: 19.1.0-rc.3 - better-auth: 1.4.18 + better-auth: 1.5.4 builder-util-runtime: 9.5.1 - effect: 3.19.14 - electron: 39.2.7 - electron-builder: 26.3.1 + effect: 3.19.19 + electron: 40.8.0 + electron-builder: 26.8.1 electron-devtools-installer: 4.0.0 + electron-updater: 6.8.3 electron-vite: 5.0.0 eslint: 9.39.2 eslint-config-prettier: 10.1.8 eslint-import-resolver-typescript: 4.4.4 - eslint-plugin-better-tailwindcss: 3.8.0 + eslint-plugin-better-tailwindcss: 4.3.2 eslint-plugin-import-x: 4.16.1 eslint-plugin-jsx-a11y: 6.10.2 - eslint-plugin-perfectionist: 5.3.0 + eslint-plugin-perfectionist: 5.6.0 eslint-plugin-react: 7.37.5 eslint-plugin-react-hooks: 7.0.1 - globals: 17.0.0 + globals: 17.4.0 id128: 1.6.6 jiti: 2.6.1 - nx: 22.3.3 - openai: 4.77.0 - prettier: 3.7.4 - react: 19.2.3 - react-aria: 3.45.0 - react-aria-components: 1.14.0 - react-dom: 19.2.3 - react-error-boundary: 6.0.2 - react-icons: 5.5.0 + nx: 22.5.4 + openai: 6.27.0 + prettier: 3.8.1 + react: 19.2.4 + react-aria: 3.47.0 + react-aria-components: 1.16.0 + react-dom: 19.2.4 + react-error-boundary: 6.1.1 + react-icons: 5.6.0 react-markdown: 10.1.0 - react-resizable-panels: 4.3.0 - react-scan: 0.4.3 - react-stately: 3.43.0 + react-resizable-panels: 4.7.1 + react-scan: 0.5.3 + react-stately: 3.45.0 react-timeago: 8.3.0 remark-gfm: 4.0.1 - storybook: 10.1.11 + storybook: 10.2.16 swc-node: 1.0.0 syncpack: 13.0.4 - tailwind-merge: 3.4.0 + tailwind-merge: 3.5.0 tailwind-variants: 3.2.2 - tailwindcss: 4.1.18 + tailwindcss: 4.2.1 tailwindcss-react-aria-components: 2.0.1 ts-node: 10.9.2 tsup: 8.5.1 + tsx: ^4.21.0 tw-animate-css: 1.4.0 typescript: 5.9.3 - typescript-eslint: 8.52.0 - undici: 7.18.2 - use-debounce: 10.0.6 + typescript-eslint: 8.56.1 + undici: 7.22.0 + use-debounce: 10.1.0 vite: 7.3.1 - vite-tsconfig-paths: 6.0.3 + vite-tsconfig-paths: 6.1.1 vitest: 4.0.18 yaml: 2.8.2 @@ -162,6 +164,7 @@ overrides: '@codemirror/language': 6.12.1 '@codemirror/state': 6.5.3 '@codemirror/view': 6.39.9 + '@lezer/common': 1.5.1 '@types/eslint': '-' patchedDependencies: diff --git a/scoop.json b/scoop.json index 10eb1754e..c4bb80e07 100644 --- a/scoop.json +++ b/scoop.json @@ -1,68 +1,68 @@ { + "buckets": [ + { + "Name": "main", + "Source": "https://github.com/ScoopInstaller/Main.git", + "Updated": "2026-03-01T20:30:21+00:00", + "Manifests": 1449 + } + ], "apps": [ { "Info": "", - "Updated": "2025-11-24T00:09:42.6740987+00:00", "Name": "7zip", - "Version": "25.01", - "Source": "main" + "Updated": "2026-03-02T00:11:42.5461877+00:00", + "Source": "main", + "Version": "26.00" }, { "Info": "", - "Updated": "2025-11-24T00:09:52.0812649+00:00", "Name": "gcc", - "Version": "13.2.0", - "Source": "main" + "Updated": "2026-03-02T00:11:55.5410061+00:00", + "Source": "main", + "Version": "15.2.0" }, { "Info": "", - "Updated": "2025-12-29T00:12:40.2282169+00:00", "Name": "go", - "Version": "1.25.5", - "Source": "main" + "Updated": "2026-03-02T00:12:48.7592051+00:00", + "Source": "main", + "Version": "1.26.0" }, { "Info": "", - "Updated": "2025-11-24T00:10:40.0177047+00:00", "Name": "jq", - "Version": "1.8.1", - "Source": "main" + "Updated": "2026-03-02T00:12:49.0700649+00:00", + "Source": "main", + "Version": "1.8.1" }, { "Info": "", - "Updated": "2025-11-24T00:11:28.9374828+00:00", "Name": "mingw", - "Version": "15.2.0-rt_v13-rev0", - "Source": "main" + "Updated": "2026-03-02T00:13:39.1655567+00:00", + "Source": "main", + "Version": "15.2.0-rt_v13-rev1" }, { "Info": "", - "Updated": "2025-11-24T00:11:38.5272031+00:00", "Name": "nodejs", - "Version": "25.2.1", - "Source": "main" + "Updated": "2026-03-02T00:13:47.8899354+00:00", + "Source": "main", + "Version": "25.7.0" }, { "Info": "", - "Updated": "2025-12-29T00:12:41.4945252+00:00", "Name": "pnpm", - "Version": "10.26.2", - "Source": "main" + "Updated": "2026-03-02T00:13:48.5868567+00:00", + "Source": "main", + "Version": "10.30.3" }, { "Info": "", - "Updated": "2025-12-29T00:12:42.3442632+00:00", "Name": "task", - "Version": "3.46.4", - "Source": "main" - } - ], - "buckets": [ - { - "Name": "main", - "Source": "https://github.com/ScoopInstaller/Main.git", - "Updated": "2025-12-28T20:29:45+00:00", - "Manifests": 1412 + "Updated": "2026-03-02T00:13:49.2456734+00:00", + "Source": "main", + "Version": "3.48.0" } ] } diff --git a/tools/eslint/config.ts b/tools/eslint/config.ts index 6b985fae0..7030b7aed 100644 --- a/tools/eslint/config.ts +++ b/tools/eslint/config.ts @@ -137,7 +137,7 @@ const rules = defineConfig({ 'warn', { group: 'emptyLine', preferSingleLine: true, printWidth: 120 }, ], - 'better-tailwindcss/enforce-consistent-variable-syntax': ['warn', { syntax: 'parentheses' }], + 'better-tailwindcss/enforce-consistent-variable-syntax': ['warn', { syntax: 'variable' }], }, }); From 3d58fae34446ae1fe8f102f52c6acf5eb4834e98 Mon Sep 17 00:00:00 2001 From: moosebay Date: Sat, 7 Mar 2026 05:57:00 +0300 Subject: [PATCH 2/2] feat: GraphQL delta UI, tab fixes, header delta service fixes, and flow node docs - Add DeltaResetButton to GraphQL top-bar (name), query editor, and variables editor - Replace inline URL with delta-aware GraphQLUrl component in top-bar - Wire delta-aware delete and send in GraphQL top-bar - Add onStay hooks to all route files (HTTP, GraphQL, WS, Flow, Credential) for tab creation - Fix tab active state: use exact route matching to prevent parent highlighting on delta pages - Add GraphQL delta to file system sidebar (FileKind enum, model, converters, migration, UI) - Fix GraphQL header delta service: Create now passes delta fields, add UpdateDelta method - Fix header delta RPC handler to call UpdateDelta instead of Update - Add UpdateGraphQLHeaderDelta sqlc query - Fix converter.go missing GraphQL/WebSocket/GraphQLDelta cases in ToAPIFileKind - Add NEW_FLOW_NODE.md comprehensive checklist for adding new flow node types --- .../client/src/features/file-system/index.tsx | 218 +++- .../credential/$credentialIdCan/index.tsx | 11 + .../flow/routes/flow/$flowIdCan/route.tsx | 11 + .../pages/graphql/request/query-editor.tsx | 30 +- .../src/pages/graphql/request/top-bar.tsx | 61 +- .../graphql/request/variables-editor.tsx | 32 +- .../delta.$deltaGraphqlIdCan.tsx | 9 + .../routes/graphql/$graphqlIdCan/index.tsx | 9 + .../http/$httpIdCan/delta.$deltaHttpIdCan.tsx | 9 + .../http/routes/http/$httpIdCan/index.tsx | 9 + .../websocket/$websocketIdCan/index.tsx | 9 + packages/client/src/widgets/tabs/index.tsx | 1 + packages/db/pkg/sqlc/gen/db.go | 10 + packages/db/pkg/sqlc/gen/graphql.sql.go | 37 +- packages/db/pkg/sqlc/queries/graphql.sql | 13 +- packages/db/pkg/sqlc/schema/03_files.sql | 4 +- packages/server/cmd/serverrun/serverrun.go | 1 + packages/server/docs/specs/NEW_FLOW_NODE.md | 959 ++++++++++++++++++ packages/server/internal/api/rfile/rfile.go | 4 + .../server/internal/api/rflowv2/rflowv2.go | 3 + .../api/rflowv2/rflowv2_copy_paste.go | 33 +- .../api/rgraphql/rgraphql_crud_assert.go | 10 + .../rgraphql/rgraphql_crud_header_delta.go | 2 +- .../internal/api/rgraphql/rgraphql_exec.go | 21 +- .../api/rgraphql/rgraphql_exec_assert.go | 37 +- .../internal/api/rreference/rreference.go | 219 ++++ .../server/internal/converter/converter.go | 6 + .../01KK31SQ_add_graphql_delta_file_kind.go | 122 +++ packages/server/pkg/ioworkspace/types.go | 1 + packages/server/pkg/model/mfile/mfile.go | 14 +- .../server/pkg/service/sgraphql/header.go | 38 +- packages/spec/api/file-system.tsp | 1 + 32 files changed, 1846 insertions(+), 98 deletions(-) create mode 100644 packages/server/docs/specs/NEW_FLOW_NODE.md create mode 100644 packages/server/internal/migrations/01KK31SQ_add_graphql_delta_file_kind.go diff --git a/packages/client/src/features/file-system/index.tsx b/packages/client/src/features/file-system/index.tsx index 5cb800586..0b900f915 100644 --- a/packages/client/src/features/file-system/index.tsx +++ b/packages/client/src/features/file-system/index.tsx @@ -29,7 +29,10 @@ import { FolderSchema, } from '@the-dev-tools/spec/buf/api/file_system/v1/file_system_pb'; import { FlowSchema, FlowService } from '@the-dev-tools/spec/buf/api/flow/v1/flow_pb'; -import { GraphQLSchema as GraphQLItemSchema } from '@the-dev-tools/spec/buf/api/graph_q_l/v1/graph_q_l_pb'; +import { + GraphQLDeltaSchema, + GraphQLSchema as GraphQLItemSchema, +} from '@the-dev-tools/spec/buf/api/graph_q_l/v1/graph_q_l_pb'; import { HttpDeltaSchema, HttpMethod, HttpSchema, HttpService } from '@the-dev-tools/spec/buf/api/http/v1/http_pb'; import { WebSocketSchema as WebSocketItemSchema } from '@the-dev-tools/spec/buf/api/web_socket/v1/web_socket_pb'; import { @@ -40,7 +43,7 @@ import { } from '@the-dev-tools/spec/tanstack-db/v1/api/credential'; import { FileCollectionSchema, FolderCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/file_system'; import { FlowCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/flow'; -import { GraphQLCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/graph_q_l'; +import { GraphQLCollectionSchema, GraphQLDeltaCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/graph_q_l'; import { HttpCollectionSchema, HttpDeltaCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/http'; import { WebSocketCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/web_socket'; import { Button } from '@the-dev-tools/ui/button'; @@ -290,7 +293,9 @@ export const FileTree = ({ onAction, onSelectionChange, selectedKeys, selectionM if (dropPosition !== 'on') return false; const sourceCanMove = - !sourceKinds.has(`kind_${FileKind.UNSPECIFIED}`) && !sourceKinds.has(`kind_${FileKind.HTTP_DELTA}`); + !sourceKinds.has(`kind_${FileKind.UNSPECIFIED}`) && + !sourceKinds.has(`kind_${FileKind.HTTP_DELTA}`) && + !sourceKinds.has(`kind_${FileKind.GRAPH_Q_L_DELTA}`); const targetCanAccept = fileCollection.get(key.toString())?.kind === FileKind.FOLDER; return sourceCanMove && targetCanAccept; @@ -365,6 +370,7 @@ const FileItem = ({ id }: FileItemProps) => { Match.when(FileKind.HTTP_DELTA, () => ), Match.when(FileKind.FLOW, () => ), Match.when(FileKind.GRAPH_Q_L, () => ), + Match.when(FileKind.GRAPH_Q_L_DELTA, () => ), Match.when(FileKind.CREDENTIAL, () => ), Match.when(FileKind.WEB_SOCKET, () => ), Match.orElse(() => null), @@ -919,8 +925,9 @@ const FlowFile = ({ id }: FileItemProps) => { }; const GraphQLFile = ({ id }: FileItemProps) => { - const router = useRouter(); const matchRoute = useMatchRoute(); + const router = useRouter(); + const navigate = useNavigate(); const { theme } = useTheme(); @@ -942,6 +949,17 @@ const GraphQLFile = ({ id }: FileItemProps) => { [graphqlCollection, graphqlId], ).data ?? create(GraphQLItemSchema); + const deltaCollection = useApiCollection(GraphQLDeltaCollectionSchema); + + const { data: files } = useLiveQuery( + (_) => + _.from({ file: fileCollection }) + .where((_) => eq(_.file.parentId, graphqlId)) + .orderBy((_) => _.file.order) + .select((_) => pick(_.file, 'fileId', 'order')), + [fileCollection, graphqlId], + ); + const modal = useProgrammaticModal(); const exportMutation = useConnectMutation(ExportService.method.export); @@ -991,6 +1009,31 @@ const GraphQLFile = ({ id }: FileItemProps) => { + { + const deltaGraphqlId = Ulid.generate().bytes; + deltaCollection.utils.insert({ deltaGraphqlId, graphqlId }); + fileCollection.utils.insert({ + fileId: deltaGraphqlId, + kind: FileKind.GRAPH_Q_L_DELTA, + order: await getNextOrder(fileCollection), + parentId: graphqlId, + workspaceId, + }); + if (toNavigate) + await navigate({ + from: router.routesById[routes.dashboard.workspace.route.id].fullPath, + params: { + deltaGraphqlIdCan: Ulid.construct(deltaGraphqlId).toCanonical(), + graphqlIdCan: Ulid.construct(graphqlId).toCanonical(), + }, + to: router.routesById[routes.dashboard.workspace.graphql.delta.id].fullPath, + }); + }} + > + New delta + + void edit()}>Rename @@ -1061,8 +1104,175 @@ const GraphQLFile = ({ id }: FileItemProps) => { children: content, className: toNavigate && matchRoute(route) !== false ? tw`bg-neutral` : '', id, + item: (_) => , + items: files, onContextMenu, textValue: name, + } satisfies TreeItemProps<(typeof files)[number]>; + + return toNavigate ? : ; +}; + +const GraphQLDeltaFile = ({ id }: FileItemProps) => { + const router = useRouter(); + const matchRoute = useMatchRoute(); + + const { theme } = useTheme(); + + const { workspaceId } = routes.dashboard.workspace.route.useLoaderData(); + + const fileCollection = useApiCollection(FileCollectionSchema); + + const { fileId: deltaGraphqlId } = useMemo( + () => fileCollection.utils.parseKeyUnsafe(id), + [fileCollection.utils, id], + ); + + const deltaCollection = useApiCollection(GraphQLDeltaCollectionSchema); + + const { graphqlId } = + useLiveQuery( + (_) => + _.from({ item: deltaCollection }) + .where((_) => eq(_.item.deltaGraphqlId, deltaGraphqlId)) + .select((_) => pick(_.item, 'graphqlId')) + .findOne(), + [deltaCollection, deltaGraphqlId], + ).data ?? create(GraphQLDeltaSchema); + + const deltaOptions = { + deltaId: deltaGraphqlId, + deltaSchema: GraphQLDeltaCollectionSchema, + originId: graphqlId, + originSchema: GraphQLCollectionSchema, + } as const; + + const [name, setName] = useDeltaState({ ...deltaOptions, valueKey: 'name' }); + + const modal = useProgrammaticModal(); + + const exportMutation = useConnectMutation(ExportService.method.export); + const exportCurlGraphQLMutation = useConnectMutation(ExportService.method.exportCurlGraphQL); + + const { containerRef, navigate: toNavigate = false, showControls } = useContext(FileTreeContext); + + const { escapeRef, escapeRender } = useEscapePortal(containerRef); + + const { edit, isEditing, textFieldProps } = useEditableTextState({ + onSuccess: (_) => { + if (_ === name) return; + setName(_); + }, + value: name ?? '', + }); + + const { menuProps, menuTriggerProps, onContextMenu } = useContextMenuState(); + + const route = { + from: router.routesById[routes.dashboard.workspace.route.id].fullPath, + params: { + deltaGraphqlIdCan: Ulid.construct(deltaGraphqlId).toCanonical(), + graphqlIdCan: Ulid.construct(graphqlId).toCanonical(), + }, + to: router.routesById[routes.dashboard.workspace.graphql.delta.id].fullPath, + } satisfies ToOptions; + + const content = ( + <> + {modal.children && } + + GQL + + + {name} + + + {isEditing && + escapeRender( + , + )} + + {showControls && ( + + + + + void edit()}>Rename + + + Export + + + { + const { data, name } = await exportMutation.mutateAsync({ + fileIds: [deltaGraphqlId], + workspaceId, + }); + saveFile({ blobParts: [data], name }); + }} + > + YAML (DevTools) + + + { + const { data } = await exportCurlGraphQLMutation.mutateAsync({ + graphqlIds: [deltaGraphqlId], + workspaceId, + }); + modal.onOpenChange( + true, + + {({ close }) => ( + <> +
+ + cURL export + + + +
+ + + + )} +
, + ); + }} + > + cURL +
+
+
+ + void fileCollection.utils.delete({ fileId: deltaGraphqlId })} variant='danger'> + Delete + +
+
+ )} + + ); + + const props = { + children: content, + className: toNavigate && matchRoute(route) !== false ? tw`bg-neutral` : '', + id, + onContextMenu, + textValue: name ?? '', } satisfies TreeItemProps; return toNavigate ? : ; diff --git a/packages/client/src/pages/credential/routes/credential/$credentialIdCan/index.tsx b/packages/client/src/pages/credential/routes/credential/$credentialIdCan/index.tsx index b8d62475e..6c6cb6645 100644 --- a/packages/client/src/pages/credential/routes/credential/$credentialIdCan/index.tsx +++ b/packages/client/src/pages/credential/routes/credential/$credentialIdCan/index.tsx @@ -41,6 +41,17 @@ export const Route = createFileRoute( const { credentialId } = match.loaderData; + await openTab({ + id: credentialTabId(credentialId), + match, + node: , + }); + }, + onStay: async (match) => { + if (!match.loaderData) return; + + const { credentialId } = match.loaderData; + await openTab({ id: credentialTabId(credentialId), match, diff --git a/packages/client/src/pages/flow/routes/flow/$flowIdCan/route.tsx b/packages/client/src/pages/flow/routes/flow/$flowIdCan/route.tsx index 17652e69c..7416145ff 100644 --- a/packages/client/src/pages/flow/routes/flow/$flowIdCan/route.tsx +++ b/packages/client/src/pages/flow/routes/flow/$flowIdCan/route.tsx @@ -17,6 +17,17 @@ export const Route = createFileRoute('/(dashboard)/(workspace)/workspace/$worksp const { flowId } = match.loaderData; + await openTab({ + id: flowTabId(flowId), + match, + node: , + }); + }, + onStay: async (match) => { + if (!match.loaderData) return; + + const { flowId } = match.loaderData; + await openTab({ id: flowTabId(flowId), match, diff --git a/packages/client/src/pages/graphql/request/query-editor.tsx b/packages/client/src/pages/graphql/request/query-editor.tsx index 7ee41cf67..762702c1e 100644 --- a/packages/client/src/pages/graphql/request/query-editor.tsx +++ b/packages/client/src/pages/graphql/request/query-editor.tsx @@ -5,7 +5,7 @@ import { } from '@the-dev-tools/spec/tanstack-db/v1/api/graph_q_l'; import { tw } from '@the-dev-tools/ui/tailwind-literal'; import { useTheme } from '@the-dev-tools/ui/theme'; -import { useDeltaState } from '~/features/delta'; +import { DeltaResetButton, useDeltaState } from '~/features/delta'; export interface GraphQLQueryEditorProps { deltaGraphqlId?: Uint8Array | undefined; @@ -28,15 +28,23 @@ export const GraphQLQueryEditor = ({ deltaGraphqlId, graphqlId, isReadOnly = fal const [value, setValue] = useDeltaState(deltaOptions); return ( - void setValue(_)} - placeholder='Enter your GraphQL query...' - readOnly={isReadOnly} - theme={theme} - value={value ?? ''} - /> +
+ {!isReadOnly && ( +
+ +
+ )} + + void setValue(_)} + placeholder='Enter your GraphQL query...' + readOnly={isReadOnly} + theme={theme} + value={value ?? ''} + /> +
); }; diff --git a/packages/client/src/pages/graphql/request/top-bar.tsx b/packages/client/src/pages/graphql/request/top-bar.tsx index 19229b958..eb1cef64c 100644 --- a/packages/client/src/pages/graphql/request/top-bar.tsx +++ b/packages/client/src/pages/graphql/request/top-bar.tsx @@ -1,17 +1,21 @@ import { Array, pipe } from 'effect'; -import { useState, useTransition } from 'react'; +import { useTransition } from 'react'; import { Button as AriaButton, DialogTrigger, MenuTrigger } from 'react-aria-components'; import { FiClock, FiMoreHorizontal } from 'react-icons/fi'; import { GraphQLService } from '@the-dev-tools/spec/buf/api/graph_q_l/v1/graph_q_l_pb'; -import { GraphQLCollectionSchema } from '@the-dev-tools/spec/tanstack-db/v1/api/graph_q_l'; +import { + GraphQLCollectionSchema, + GraphQLDeltaCollectionSchema, +} from '@the-dev-tools/spec/tanstack-db/v1/api/graph_q_l'; import { Button } from '@the-dev-tools/ui/button'; import { Menu, MenuItem, useContextMenuState } from '@the-dev-tools/ui/menu'; import { tw } from '@the-dev-tools/ui/tailwind-literal'; import { TextInputField, useEditableTextState } from '@the-dev-tools/ui/text-field'; -import { ReferenceField } from '~/features/expression'; +import { DeltaResetButton, useDeltaState } from '~/features/delta'; import { request, useApiCollection } from '~/shared/api'; import { routes } from '~/shared/routes'; import { HistoryModal } from '../history'; +import { GraphQLUrl } from './url'; export interface GraphQLTopBarProps { deltaGraphqlId?: Uint8Array | undefined; @@ -22,23 +26,30 @@ export const GraphQLTopBar = ({ deltaGraphqlId, graphqlId }: GraphQLTopBarProps) const { transport } = routes.root.useRouteContext(); const collection = useApiCollection(GraphQLCollectionSchema); + const deltaCollection = useApiCollection(GraphQLDeltaCollectionSchema); - const item = collection.get(collection.utils.getKey({ graphqlId })); + const deltaOptions = { + deltaId: deltaGraphqlId, + deltaSchema: GraphQLDeltaCollectionSchema, + isDelta: deltaGraphqlId !== undefined, + originId: graphqlId, + originSchema: GraphQLCollectionSchema, + }; + + const [name, setName] = useDeltaState({ ...deltaOptions, valueKey: 'name' }); const { menuProps, menuTriggerProps, onContextMenu } = useContextMenuState(); const { edit, isEditing, textFieldProps } = useEditableTextState({ onSuccess: (_) => { - if (_ === item?.name) return; - collection.utils.update({ graphqlId, name: _ }); + if (_ === name) return; + setName(_); }, - value: item?.name ?? '', + value: name ?? '', }); const [isSending, startTransition] = useTransition(); - const [urlState, setUrlState] = useState(); - return ( <>
@@ -59,9 +70,11 @@ export const GraphQLTopBar = ({ deltaGraphqlId, graphqlId }: GraphQLTopBarProps) onContextMenu={onContextMenu} onPress={() => void edit()} > - {item?.name} + {name} )} + +
@@ -80,7 +93,13 @@ export const GraphQLTopBar = ({ deltaGraphqlId, graphqlId }: GraphQLTopBarProps) void edit()}>Rename - collection.utils.delete({ graphqlId })} variant='danger'> + { + if (deltaGraphqlId) deltaCollection.utils.delete({ deltaGraphqlId }); + else collection.utils.delete({ graphqlId }); + }} + variant='danger' + > Delete @@ -88,34 +107,24 @@ export const GraphQLTopBar = ({ deltaGraphqlId, graphqlId }: GraphQLTopBarProps)
- { - if (urlState !== undefined) { - collection.utils.update({ graphqlId, url: urlState }); - } - }} - onChange={(_) => void setUrlState(_)} - value={urlState ?? item?.url ?? ''} - /> +