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..0b900f915 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'; @@ -29,8 +29,12 @@ 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 { CredentialAnthropicCollectionSchema, CredentialCollectionSchema, @@ -39,8 +43,9 @@ 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'; import { FlowsIcon, FolderOpenedIcon } from '@the-dev-tools/ui/icons'; import { Menu, MenuItem, useContextMenuState } from '@the-dev-tools/ui/menu'; @@ -89,6 +94,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 +158,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 + + ); @@ -277,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; @@ -352,7 +370,9 @@ 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), ); }; @@ -905,8 +925,13 @@ const FlowFile = ({ id }: FileItemProps) => { }; const GraphQLFile = ({ id }: FileItemProps) => { - const router = useRouter(); const matchRoute = useMatchRoute(); + const router = useRouter(); + const navigate = useNavigate(); + + const { theme } = useTheme(); + + const { workspaceId } = routes.dashboard.workspace.route.useLoaderData(); const fileCollection = useApiCollection(FileCollectionSchema); @@ -924,6 +949,22 @@ 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); + const exportCurlGraphQLMutation = useConnectMutation(ExportService.method.exportCurlGraphQL); + const { containerRef, navigate: toNavigate = false, showControls } = useContext(FileTreeContext); const { escapeRef, escapeRender } = useEscapePortal(containerRef); @@ -943,6 +984,8 @@ const GraphQLFile = ({ id }: FileItemProps) => { const content = ( <> + {modal.children && } + GQL @@ -966,8 +1009,361 @@ 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 + + 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, + 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 ? : ; +}; + +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 +1424,8 @@ const CredentialFile = ({ id }: FileItemProps) => { to: router.routesById[routes.dashboard.workspace.credential.id].fullPath, }); + + const content = ( <> {pipe( @@ -1075,7 +1473,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/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/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/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 ?? ''} - /> +
+ } + > + + + + + + + + + + ); +}; + +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..911063faa --- /dev/null +++ b/packages/client/src/pages/websocket/routes/websocket/$websocketIdCan/index.tsx @@ -0,0 +1,28 @@ +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: , + }); + }, + onStay: 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/client/src/widgets/tabs/index.tsx b/packages/client/src/widgets/tabs/index.tsx index 05a720d14..fd17eb80f 100644 --- a/packages/client/src/widgets/tabs/index.tsx +++ b/packages/client/src/widgets/tabs/index.tsx @@ -118,6 +118,7 @@ const TabItem = ({ id }: TabItemProps) => { return ( .tsp` + +Define the full API surface: + +- **Models**: Base item, delta, sync insert/update/delete/upsert messages +- **Service methods**: Collection, Insert, Update, Delete, Sync (server-streaming), plus Delta variants +- **Sub-entities**: Headers, assertions, etc. — each needs its own full CRUD + sync + delta set + +After editing `.tsp` files: +```bash +pnpm nx run spec:build +``` + +This generates: +- `packages/spec/dist/buf/go/` — Go protobuf + Connect RPC +- `packages/spec/dist/buf/typescript/` — TypeScript protobuf types +- `packages/spec/dist/tanstack-db/typescript/` — TanStack DB collection schemas + +**Gotcha:** The tanstack-db schemas are auto-generated. They must be registered in the `schemas_v1_api_` array in the generated file, and that array must be included in `packages/spec/dist/tanstack-db/typescript/v1/api.ts`. + +--- + +## 2. Database Schema + Queries + +### Schema + +**File:** `packages/db/pkg/sqlc/schema/_.sql` + +Typical columns for a request-type node: +```sql +CREATE TABLE ( + id BLOB PRIMARY KEY NOT NULL, + workspace_id BLOB NOT NULL, + folder_id BLOB, + name TEXT NOT NULL DEFAULT '', + url TEXT NOT NULL DEFAULT '', + -- type-specific fields... + description TEXT NOT NULL DEFAULT '', + + -- Delta fields + parent__id BLOB, + is_delta BOOLEAN NOT NULL DEFAULT FALSE, + is_snapshot BOOLEAN NOT NULL DEFAULT FALSE, + delta_name TEXT, + delta_url TEXT, + -- delta_ for each mutable field... + + created_at INTEGER NOT NULL DEFAULT 0, + updated_at INTEGER NOT NULL DEFAULT 0, + + FOREIGN KEY (workspace_id) REFERENCES workspace(id) +); +``` + +Also create sub-entity tables (headers, assertions, etc.) with the same delta pattern. + +### Queries + +**File:** `packages/db/pkg/sqlc/queries/.sql` + +Required queries: +- `Create` — insert +- `Get` — by ID +- `GetsByWorkspaceID` — list for workspace (filter `is_delta = FALSE AND is_snapshot = FALSE`) +- `GetDeltasByWorkspaceID` — list deltas +- `Update` — full update +- `UpdateDelta` — update delta fields only +- `Delete` — by ID +- Same pattern for sub-entities (headers, assertions) + +After editing `.sql` files: +```bash +pnpm nx run db:generate +``` + +**Gotcha:** The workspace listing query MUST filter `is_delta = FALSE AND is_snapshot = FALSE` to exclude deltas and snapshots from the base collection. Forgetting this causes snapshot/delta entries to appear as base items. + +**Gotcha — Sub-entity delta columns:** Sub-entity tables (headers, assertions) need delta columns too (`parent__header_id`, `is_delta`, `delta_header_key`, etc.). These can be added inline in the initial schema or via a separate delta schema file (e.g., `09_graphql_delta.sql` uses `ALTER TABLE`). The migration that creates the tables should include these columns from the start. If the schema and queries reference delta columns but the table doesn't have them, all delta operations will fail at runtime (400 errors on update, SQL errors on select). + +**Gotcha — `UpdateDelta` query required:** Each entity/sub-entity that supports deltas needs TWO update queries: `Update` for base fields and `UpdateDelta` for delta-specific fields (`delta_*` columns). The delta update handler must call `UpdateDelta`, NOT `Update` — the base `Update` only modifies base columns and ignores delta fields entirely. + +**Gotcha — `Create` must pass delta fields:** When sqlc generates a `CreateParams` struct with delta fields, the service's `Create` method must populate them from the model. Otherwise, delta records are inserted with zero-valued delta fields, and `is_delta` stays `false`. Check that all delta-related fields (`ParentID`, `IsDelta`, `DeltaKey`, etc.) are mapped in the `Create` call. + +--- + +## 3. Server Model Layer + +**File:** `packages/server/pkg/model/m/m.go` + +Define pure Go domain structs: +```go +type struct { + ID idwrap.IDWrap + WorkspaceID idwrap.IDWrap + // fields... + + // Delta fields + ParentID *idwrap.IDWrap + IsDelta bool + IsSnapshot bool + DeltaName *string + // delta_ for each mutable field... +} +``` + +These bridge between API types (protobuf) and DB types (sqlc gen). Keep them pure Go — no dependencies on protobuf or sqlc packages. + +--- + +## 4. Server Service Layer + +**Files:** `packages/server/pkg/service/s/` + +Split into reader and writer following the SQLite deadlock prevention pattern: + +- **Reader** (`reader.go`): Read-only operations using `*sql.DB` connection pool + - `Get(ctx, id)`, `GetByWorkspaceID(ctx, wsID)`, `GetDeltasByWorkspaceID(ctx, wsID)` +- **Writer** (inline or `writer.go`): Write operations using `*sql.Tx` + - `Create(ctx, model)`, `Update(ctx, model)`, `Delete(ctx, id)` +- **Service struct**: Wraps queries, provides `TX(tx)` method to create transactional writer + +Pattern: +```go +type Service struct { + queries *gen.Queries +} + +func (s Service) TX(tx *sql.Tx) *Service { + return &Service{queries: gen.New(tx)} +} +``` + +**Gotcha:** Reads MUST happen OUTSIDE transactions. Writers operate INSIDE transactions. This prevents SQLite deadlocks. The `notxread` linter enforces this. + +--- + +## 5. Mutation Package + +**Files:** `packages/server/pkg/mutation/insert_.go`, `update_.go` + +Create insert/update helper functions that both execute the DB operation AND track the event: + +```go +type InsertItem struct { + ID idwrap.IDWrap + WorkspaceID idwrap.IDWrap + IsDelta bool + Params gen.CreateParams +} + +func (c *Context) Insert(ctx context.Context, item InsertItem) error { + if err := c.q.Create(ctx, item.Params); err != nil { + return err + } + c.track(Event{ + Entity: Entity, + Op: OpInsert, + ID: item.ID, + WorkspaceID: item.WorkspaceID, + IsDelta: item.IsDelta, + }) + return nil +} +``` + +Also register the entity constant in `packages/server/pkg/mutation/mutation.go`: +```go +const Entity = "" +``` + +**CRITICAL GOTCHA — Sync Payload:** The mutation helper's `track()` call does NOT include a `Payload`. The CRUD handler MUST add a SEPARATE `mut.Track()` call WITH the model as `Payload` for sync events to work. Without this, the publisher can't create the API model, and the sync event is silently dropped. Example: + +```go +// In the CRUD handler: +if err := mut.Insert(ctx, ...); err != nil { + return nil, err +} +// This second Track is REQUIRED for sync to work: +mut.Track(mutation.Event{ + Entity: mutation.Entity, + Op: mutation.OpInsert, + ID: item.ID, + Payload: model, // <-- Without this, sync breaks silently +}) +``` + +This applies to BOTH insert and update operations. The delete path is different — the publisher constructs a minimal model from the event ID, so no payload is needed. + +--- + +## 6. Node Executor Package + +**File:** `packages/server/pkg/flow/node/n/n.go` + +Each node type needs a dedicated executor package that implements the `FlowNode` interface. This is the runtime logic that executes when the flow runner reaches this node. + +```go +package n + +type Node struct { + FlowNodeID idwrap.IDWrap + Name string + // Type-specific config and dependencies... +} + +func New(id idwrap.IDWrap, name string, /* deps */) *Node { + return &Node{FlowNodeID: id, Name: name} +} + +func (n *Node) GetID() idwrap.IDWrap { return n.FlowNodeID } +func (n *Node) GetName() string { return n.Name } + +func (n *Node) RunSync(ctx context.Context, req *node.FlowNodeRequest) node.FlowNodeResult { + nextID := mflow.GetNextNodeID(req.EdgeSourceMap, n.GetID(), mflow.HandleUnspecified) + result := node.FlowNodeResult{NextNodeID: nextID} + + // 1. Read input variables (deep copy VarMap to prevent concurrent access) + varMapCopy := node.DeepCopyVarMap(req) + + // 2. Execute the node's logic (HTTP request, GraphQL query, etc.) + // 3. Build output map and write to flow variables + err := node.WriteNodeVarBulk(req, n.Name, outputMap) + + // 4. For request-type nodes: set AuxiliaryID to link to response + result.AuxiliaryID = &responseID + + return result +} +``` + +**Existing executor packages** (for reference): +- `nrequest` — HTTP requests +- `ngraphql` — GraphQL queries +- `nwsconnection` — WebSocket connections +- `nwssend` — WebSocket send messages +- `nif` — Condition nodes +- `nfor` — For loops +- `nforeach` — ForEach loops +- `njs` — JavaScript execution +- `nai` — AI nodes +- `naiprovider` — AI provider nodes +- `nmemory` — AI memory nodes +- `nwait` — Wait/delay nodes +- `nstart` — Manual start nodes + +**Side Response Channel (request-type nodes only):** + +HTTP and GraphQL nodes send responses through a side channel for async DB persistence: +```go +// The builder passes these channels into node constructors +respChan chan nrequest.NodeRequestSideResp +gqlRespChan chan ngraphql.NodeGraphQLSideResp +``` + +The executor sends the response + request data through this channel after execution. A separate goroutine persists the response to the DB and publishes sync events. This decouples response storage from the flow execution path. + +--- + +## 7. Server RPC Handlers + +**Files:** `packages/server/internal/api/r/` + +Organize by concern: +- `r.go` — Service struct, constructor, streamers, mutation publisher +- `r_crud.go` — CRUD operations (Collection, Insert, Update, Delete) +- `r_crud_.go` — Sub-entity CRUD (headers, assertions) +- `r_delta.go` — Delta operations +- `r_exec.go` — Execution logic +- `r_converter.go` — Model <-> API type converters, sync response builders + +### Mutation Publisher + +The publisher routes mutation events to the correct sync streamer: + +```go +func (p *publisher) PublishAll(events []mutation.Event) { + for _, evt := range events { + switch evt.Entity { + case mutation.Entity: + p.publish(evt) + case mutation.EntityHeader: + p.publishHeader(evt) + } + } +} +``` + +Each `publish` method must handle insert/update (from Payload) and delete (from event ID): + +```go +func (p *publisher) publish(evt mutation.Event) { + switch evt.Op { + case mutation.OpInsert, mutation.OpUpdate: + // MUST type-assert Payload to get the model + if m, ok := evt.Payload.(m.); ok { + model = ToAPI(m) + } + case mutation.OpDelete: + // Delete can construct from ID alone + model = &pb.{Id: evt.ID.Bytes()} + } + if model != nil { + p.streamers..Publish(topic, event) + } +} +``` + +### All CRUD handlers follow Fetch-Check-Act: +1. **FETCH**: Read data via pool services (outside transaction) +2. **CHECK**: Validate permissions/rules (pure Go) +3. **ACT**: Write via mutation context inside transaction, then commit (auto-publishes) + +### Node Config CRUD Handlers + +In addition to the entity's own CRUD (e.g., `rhttp`, `rgraphql`), each node type needs **node config CRUD** in the flow handler: + +**File:** `packages/server/internal/api/rflowv2/rflowv2_node_.go` + +These manage the type-specific flow node record (e.g., `flow_node_http` table) that links a flow node to its entity: + +- `NodeCollection` — Lists all type-specific nodes across accessible flows +- `NodeInsert` — Creates the type-specific node record (links nodeID to entityID) +- `NodeUpdate` — Updates entity references (e.g., change which HTTP request a node points to) +- `NodeDelete` — Removes the type-specific record +- `NodeSync` — Streams type-specific node mutations in real-time + +**Pattern:** The sync handler filters the generic node event stream for the specific node kind, then looks up the type-specific config: + +```go +func (s *FlowServiceV2RPC) streamNodeSync(ctx context.Context, send func(*resp) error) error { + // Subscribe to generic node stream, filter by NODE_KIND_ + events, _ := s.nodeStream.Subscribe(ctx, filter) + for evt := range events { + if evt.Node.GetKind() != flowv1.NodeKind_NODE_KIND_ { continue } + // Look up type-specific config (e.g., httpId, deltaHttpId) + nodeCfg, _ := s.ns.GetNode(ctx, nodeID) + // Build sync response with config data + } +} +``` + +**Gotcha:** The mutation payload for node config uses a wrapper struct (e.g., `nodeHttpWithFlow`) that includes the config, flowID, and base node. This provides context for the sync publisher. + +--- + +## 8. Event Streaming + +**Defined in:** The RPC handler file (`r.go`) + +Each syncable entity needs: +```go +type Topic struct{ WorkspaceID idwrap.IDWrap } +type Event struct { + Type string + *pb. + IsDelta bool +} +``` + +The streamer is typed: `eventstream.SyncStreamer[Topic, Event]` + +Streamers are aggregated in a struct and wired in `serverrun.go`. + +--- + +## 9. Server Wiring (`serverrun.go`) + +**File:** `packages/server/cmd/serverrun/serverrun.go` + +Wire in this order: +1. Create the service (reader/writer) +2. Create the in-memory sync streamer +3. Pass service + streamer into the RPC handler constructor +4. Register Connect RPC routes + +**Gotcha:** If you add a service to an existing handler's dependency struct (e.g., adding `GraphQLAssert` to the flow handler), you must update BOTH the deps struct AND the constructor wiring. + +--- + +## 10. Flow Integration + +### 10a. Flow Builder + +**File:** `packages/server/pkg/flow/flowbuilder/builder.go` + +The flow builder bridges DB models to runtime executor instances. It needs: + +1. **Builder struct** — Add the new node service field: +```go +type Builder struct { + Node *sflow.NodeService + // For request-type nodes, also add entity services: + *s.Service + Header *s.HeaderService + // ... +} +``` + +2. **Constructor** — Add the service parameter to `New()` and wire it. + +3. **`BuildNodes()`** — Add a case in the node kind switch to create the executor: +```go +case mflow.NODE_KIND_: + cfg, err := b.Node.GetNode(ctx, nodeModel.ID) + if err != nil { return nil, nil, err } + // For request-type nodes: resolve deltas + resolved, err := b.Resolver.Resolve(ctx, *cfg.EntityID, cfg.DeltaEntityID) + // Create executor instance + flowNodeMap[nodeModel.ID] = n.New(nodeModel.ID, nodeModel.Name, resolved, ...) +``` + +**Gotcha:** The builder runs OUTSIDE transactions (read-only). For request-type nodes, the resolver merges base + delta data before creating the executor, so the executor receives fully-resolved data. + +### 10b. Flow Runner / Executor + +**Files:** `packages/server/internal/api/rflowv2/rflowv2_exec*.go` + +The flow runner uses the builder's output (`map[IDWrap]FlowNode`) to execute nodes. No switch statement needed here — the runner calls `node.RunSync()` or `node.RunAsync()` polymorphically. + +For request-type nodes, the executor file (`rflowv2_node__exec.go` or in `pkg/flow/node/n/`) handles: +- Variable resolution and request preparation +- Sending the request and capturing the response +- Writing output variables to the flow's VarMap +- Setting `AuxiliaryID` to the response ID +- Sending response data through the side channel for DB persistence + +### 10c. Flow Duplicate + +**File:** `packages/server/internal/api/rflowv2/rflowv2_flow.go` + +Flow duplication fetches ALL node type-specific data. Add a case to the `nodeDetail` struct and the switch: + +```go +type nodeDetail struct { + node mflow.Node + // ...existing fields... + Node *mflow.Node +} + +// In the switch: +case mflow.NODE_KIND_: + if d, err := s.ns.GetNode(ctx, n.ID); err == nil { + detail.Node = d + } +``` + +**Gotcha:** For request-type nodes (HTTP, GraphQL), the duplicate also fetches the associated entity (e.g., the HTTP request) to display in the duplicated flow's node config panel. + +### 10d. Copy/Paste + +**File:** `packages/server/internal/api/rflowv2/rflowv2_copy_paste.go` + +Two functions need updates: + +**Copy** (`FlowNodesCopy`): Add case in the switch to fetch type-specific data: +```go +case flowv1.NODE_KIND_: + s.populateBundle(ctx, entityID, &bundle) +``` + +**Paste** (`FlowNodesPaste`): Handle: +- ID remapping (old ID -> new ID) +- Reference resolution (USE_EXISTING vs create new) +- Variable reference remapping in string fields +- DB creation inside transaction +- Sync event publishing + +**Gotcha:** Don't forget to remap variable references in ALL string fields that can contain `{{var.name}}` expressions. Missing one causes pasted nodes to reference wrong variables. + +### 10e. YAML Export/Import + +**Files:** `packages/server/pkg/translate/yamlflowsimplev2/` + +- **`types.go`**: Add `YamlStep` struct with `YamlStepCommon` inline. Add field to `YamlStepWrapper`. +- **`exporter.go`**: Add case in step export loop. Add to `isValid` check. +- **`converter_node.go`**: Add case to `getStepCommon()` for position data. Add processing in `processSteps()`. +- **`converter_flow.go`**: Add to `mergeFlowData` if template merging is needed. + +### 10f. Workspace Bundle + +**Files:** `packages/server/pkg/ioworkspace/` + +- **`types.go`**: Add `s []m.` (and sub-entities like headers, assertions) to `WorkspaceBundle`. Update `CountEntities()`. +- **`exporter.go`**: Fetch entities from DB in the export function. +- **`importer.go`**: Add service, counter, and import wiring. +- **`importer_flow.go`**: Add `import` function if flow-specific import logic is needed. + +--- + +## 11. Client Components + +### Flow Node Component + +**File:** `packages/client/src/pages/flow/nodes/.tsx` + +**CRITICAL — Module-level default:** Always create the default node value at module scope: +```typescript +const defaultNode = create(NodeSchema); +``` + +NEVER use `create()` inline as a `useLiveQuery` fallback. This causes an infinite re-render loop because `useLiveQuery` → `useDeltaState` subscription sees a new object reference every render. + +**Pattern:** +```typescript +const data = useLiveQuery( + (_) => _.from({ item: collection }).where(...).findOne(), + [collection, id], +).data ?? defaultNode; // module-level default +``` + +### URL Component + +Extract the URL display into a separate component (e.g., ``), matching the HTTP/GraphQL pattern. This keeps the node component clean and allows reuse. + +### Node Registration + +**File:** `packages/client/src/pages/flow/edit.tsx` + +Register the node component and settings component in the node type maps: + +```typescript +import { Node, Settings } from './nodes/'; + +// In the nodeTypes map: +const nodeTypes = { + [NodeKind.]: Node, + // ... +}; + +// In the settings components map: +const settingsMap = { + [NodeKind.]: Settings, + // ... +}; +``` + +### Add Node Menu + +**File:** `packages/client/src/pages/flow/add-node.tsx` + +Add the new node type to the "Add Node" menu so users can drag it onto the canvas. + +### Route & Tab Registration (Request-Type Nodes) + +For request-type nodes that have their own page (HTTP, GraphQL, WebSocket), you need route files that open tabs: + +**Files:** +- `packages/client/src/pages//routes//$IdCan/index.tsx` — main route +- `packages/client/src/pages//routes//$IdCan/route.tsx` — parent route (context) +- `packages/client/src/pages//tab.tsx` — tab component + tab ID generator + +**CRITICAL — Use both `onEnter` AND `onStay`:** TanStack Router has two lifecycle hooks: +- `onEnter` — fires when a route first matches (navigating FROM a different route template) +- `onStay` — fires when a route stays matched but params change (navigating between items of the same type, e.g., GraphQL A → GraphQL B) + +Both hooks must call `openTab()` with the same logic. Without `onStay`, navigating between items of the same type won't create a tab for the second item — the content renders correctly but the tab bar won't show the new tab. + +```typescript +export const Route = createFileRoute('/(dashboard)/(workspace)/workspace/$workspaceIdCan/()//$IdCan/')({ + component: Page, + onEnter: async (match) => { + const { Id } = match.context; + await openTab({ + id: TabId({ Id }), + match, + node: <Tab Id={Id} />, + }); + }, + onStay: async (match) => { + const { Id } = match.context; + await openTab({ + id: TabId({ Id }), + match, + node: <Tab Id={Id} />, + }); + }, +}); +``` + +### File Tree Drag-to-Canvas + +**File:** `packages/client/src/features/file-system/index.tsx` + +For request-type nodes, add handling so users can drag an entity from the sidebar file tree onto the flow canvas to create a node. + +### Top Bar — Delta-Aware Wiring + +The request page top bar must use `useDeltaState` + `DeltaResetButton` for the name field, and use the delta-aware URL component (e.g., ``) rather than an inline `ReferenceField`. Also wire: +- **Delta collection** for delta-aware delete (`if (deltaId) deltaCollection.delete(...)`) +- **Delta-aware send** — send with `deltaId ?? originId`, not just `originId` +- **Transaction flushing** — wait for BOTH base and delta collection transactions before sending + +Without `useDeltaState`, the top bar reads directly from the base collection and won't show delta overrides. Without `DeltaResetButton`, users can't reset individual fields back to the base value. + +### Delta Reset Buttons in Editors + +For CodeMirror-based editors (query, variables, raw body), add `DeltaResetButton` in a small toolbar row above the editor: +```typescript +
+ {!isReadOnly && ( +
+ +
+ )} + +
+``` + +The editors may already use `useDeltaState` for reading/writing values but still be missing the `DeltaResetButton` — check both. + +### Sub-entity Tables + +For headers, assertions, etc., create table components following the pattern in `packages/client/src/pages/graphql/request/assert.tsx`: +- Use `useApiCollection(Schema)` to get the collection +- Use `useLiveQuery` with `eq`/`or` filters on the parent ID +- Use `DeltaCheckbox`, `DeltaReference`, `ColumnActionDeleteDelta` for delta-aware columns + +These components have per-cell `DeltaResetButton` built-in. No additional reset button is needed at the table level. + +--- + +## 12. Request-Type Node Extras (Deltas, Responses, Versions) + +If the new node is a **request-type** (like HTTP, GraphQL, WebSocket) — not just a logic node (If, For, JS) — it needs several additional layers. Reference: `c0585188` (GraphQL delta/assertion/response commit). + +### 12a. Delta System + +Deltas allow users to create variants of a request without duplicating it. Required pieces: + +- **DB schema**: Separate delta schema file (`schema/09_graphql_delta.sql`) with delta-specific columns on the main table (`delta_name`, `delta_url`, etc.) and `parent__id` FK +- **Delta SQL queries**: `UpdateDelta` — updates only delta fields, not base fields. `GetDeltasByWorkspaceID` — lists deltas for a workspace +- **RPC handlers**: `r_crud_delta.go` — Delta CRUD (Insert, Update, Delete, Collection, Sync) for the main entity and each sub-entity (e.g., `r_crud_header_delta.go`) +- **Delta converter**: `r_delta_converter.go` — Converts between delta API types and model types +- **Resolver**: `packages/server/pkg//resolver/resolver.go` — Merges base + delta fields at read time. Called during execution and anywhere resolved data is needed +- **Patch types**: `packages/server/pkg/patch/patch.go` — Add a `Patch` struct that tracks which fields were actually changed (using `Optional[T]` for set/unset semantics) +- **Delta helpers**: `packages/server/pkg/delta/delta.go` — Generic utilities for delta field merging + +**Gotcha:** The `Writer.Update()` method MUST check `IsDelta` to prevent deltas from overwriting parent base fields. The GraphQL commit fixed this exact bug. + +**File System Delta Integration** — For deltas to appear in the sidebar file tree: + +1. **TypeSpec `FileKind` enum** (`packages/spec/api/file-system.tsp`): Add `Delta` to the enum. Run `pnpm nx run spec:build`. +2. **Go model** (`packages/server/pkg/model/mfile/mfile.go`): Add `ContentTypeDelta` constant + `IsDelta()` helper + update `String()`, `ContentTypeFromString()`, `IsValidContentType()`. +3. **File handler converters** (`packages/server/internal/api/rfile/rfile.go`): Add cases in `toAPIFileKind()` and `fromAPIFileKind()`. +4. **Public converter** (`packages/server/internal/converter/converter.go`): Add case in `ToAPIFileKind()`. +5. **DB schema** (`packages/db/pkg/sqlc/schema/03_files.sql`): Update the `CHECK (content_kind IN (...))` constraint to include the new value. Also update the `content_id IS NOT NULL` check to include the new kind. +6. **Migration** (`packages/server/internal/migrations/`): Create a migration that recreates the `files` table with the expanded CHECK constraint. SQLite doesn't support `ALTER TABLE ... ALTER CONSTRAINT`, so the migration must: create `files_new` with new constraints → copy data → drop old → rename → recreate all indexes. Follow the pattern in `01KKFQT8_add_websocket_tables.go:updateFilesCheckConstraintWebSocket()`. +7. **Client file tree** (`packages/client/src/features/file-system/index.tsx`): + - Import `DeltaCollectionSchema` and `DeltaSchema` + - Add `Match.when(FileKind._DELTA, ...)` in `FileItem` + - Add delta children query + "New delta" menu item to the parent `File` component + - Create `DeltaFile` component using `useDeltaState` for field resolution + - Exclude delta kind from drag-and-drop in `shouldAcceptItemDrop` + +**CRITICAL GOTCHA — SQLite CHECK constraint:** The `files` table has a `CHECK (content_kind IN (...))` constraint that whitelists allowed values. Adding a new `FileKind` enum value in TypeSpec is not enough — if the DB constraint doesn't include the new integer value, `FileInsert` will return a 500 error. Always update the schema AND create a migration. + +### 12b. Response Tracking + +Responses are stored every time a request is executed: + +- **Model**: Response struct (e.g., `mgraphql.GraphQLResponse`) with status, body, duration, size, timestamps +- **Response headers**: Separate model + service for response headers +- **Response assertions**: Results of assertion evaluation stored per response +- **Service**: `pkg/service/s/response.go` — Reader/writer for responses, response headers, response assertions +- **RPC handlers**: `r_crud_response_assert.go` — Response assertion collection + sync +- **Response helper**: `packages/server/pkg//response/response.go` — Response processing logic +- **Client UI**: Response panel, response header viewer, response assertion viewer, response history + +### 12c. Version / History Tracking + +Versions create snapshots of a request at execution time for history: + +- **DB**: Version table linking a version ID to the request ID + user ID +- **RPC handler**: `r_crud_version.go` — Version collection + sync endpoints +- **Snapshot creation**: During execution, clone the request + all sub-entities (headers, assertions) into a snapshot entry +- **Client UI**: History view showing past versions with their responses + +### 12d. Assertion System + +Assertions validate response data after execution: + +- **Model**: Assert struct with value (expression), enabled, display_order, delta fields +- **Service**: `pkg/service/s/assert.go` — Full CRUD reader/writer +- **Execution**: `r_exec_assert.go` — Expression evaluation engine, context building (response fields as variables), result tracking +- **Response assertions**: Store pass/fail results per response for display +- **Client UI**: Assertion editor table (request panel), assertion results viewer (response panel) + +### 12e. Reference Service + +**File:** `packages/server/internal/api/rreference/rreference.go` + +Add the new node type to the reference service so variables like `{{ NodeName.response.body }}` resolve correctly across flow nodes. Only nodes that write output variables (via `WriteNodeVarBulk`) need a reference service entry. Passive nodes (e.g., Memory) that don't produce output should be skipped — the `default` case handles them correctly. + +### 12f. Migration + +**File:** `packages/server/internal/migrations/01XXXXX_add__.go` + +Create a migration that adds the new tables. Follow the existing pattern — register it in `migrations_test.go`. + +--- + +## Common Pitfalls + +### Sync Events Silently Dropped +The most insidious bug. If a CRUD handler calls `mut.Insert()` or `mut.Update()` without a separate `mut.Track(Event{Payload: model})`, the sync event has no payload. The publisher silently drops it (model is nil). The client never receives the update. Data persists in DB but UI doesn't reflect changes until page refresh. Always verify sync works end-to-end. + +### SQLite Deadlocks +All reads MUST happen before opening a transaction. The `notxread` linter catches this, but only for direct reads — be careful with service methods that might read internally. + +### Snapshot/Delta Filtering +Workspace listing queries must filter `is_delta = FALSE AND is_snapshot = FALSE`. Without this, snapshots created during execution appear as base items in the collection. + +### Double Event Tracking +The mutation helpers (`Insert`, `Update`) track events internally without payloads. The CRUD handler then adds a second `mut.Track()` with the payload. This is intentional — the first event is silently ignored by the publisher, the second is published. Don't remove either one. + +### Client Re-render Loops +Using `create(Schema)` as an inline fallback in `useLiveQuery` creates a new object reference every render, triggering infinite re-renders through the delta state subscription system. Always hoist to module scope. + +### Variable Reference Remapping +In copy/paste, any string field that can contain `{{var.name}}` variable references must be remapped when pasting. Missing a field causes pasted nodes to reference variables from the source flow. + +### Missing `onStay` in Route Lifecycle +TanStack Router's `onEnter` only fires when a route first enters the matched set. When navigating between items of the same type (e.g., GraphQL A → GraphQL B), the route stays matched — only `onStay` fires. If a route only uses `onEnter` to call `openTab()`, the second item's tab won't appear in the tab bar (though the content renders correctly). Always use both `onEnter` and `onStay`. + +### SQLite CHECK Constraint on `files` Table +The `files` table has `CHECK (content_kind IN (0, 1, 2, ...))` that whitelists allowed content type integers. Adding a new `FileKind` in TypeSpec and `ContentType` in Go is not enough — the DB will reject inserts with a 500 error if the integer isn't in the CHECK list. You must update `03_files.sql` AND create a migration that recreates the table with the expanded constraint (SQLite doesn't support `ALTER CONSTRAINT`). See `01KKFQT8_add_websocket_tables.go` for the table-recreation pattern. + +### Delta Service Layer — `Create` and `UpdateDelta` Gaps +Three common gaps when adding delta support to sub-entities (headers, assertions): +1. **`Create` ignores delta fields** — The service `Create` method only passes base fields to the sqlc `CreateParams`, even though the struct includes delta fields. Delta records get inserted with `is_delta = false` and nil delta values. Fix: populate `IsDelta`, `ParentID`, and all `Delta*` fields in the `Create` call. +2. **No `UpdateDelta` method** — The service only has a base `Update` that writes base columns. Delta field updates silently do nothing because the `Update` SQL doesn't touch `delta_*` columns. Fix: add an `UpdateDelta` query in sqlc and a corresponding service method. +3. **Handler calls `Update` instead of `UpdateDelta`** — The delta update RPC handler modifies the model's `Delta*` fields in memory, then calls `Update()` which only persists base fields. The delta changes are discarded. Returns 400 if `is_delta` is checked (since the DB row has `is_delta = false` from gap #1). Fix: call `UpdateDelta` in the handler. + +### Tab Active State — Parent Route Highlighting on Delta Pages +TanStack Router's link `activeOptions` defaults to `{ exact: false }`. When viewing a delta page (e.g., `/graphql/$id/delta/$deltaId`), the parent route (`/graphql/$id`) also matches as "active". This causes both the original request tab and the delta tab to highlight simultaneously. Fix: add `activeOptions={{ exact: true }}` to tab link components. + +--- + +## WebSocket Implementation Reference + +The WebSocket node type (commit `ceb3c505`) is the most complete reference. Here are the exact files that were created/modified: + +### New Files Created + +| Layer | File | Purpose | +|-------|------|---------| +| DB Schema | `packages/db/pkg/sqlc/schema/10_websocket.sql` | WebSocket + header tables | +| DB Queries | `packages/db/pkg/sqlc/queries/websocket.sql` | CRUD queries | +| Model | `packages/server/pkg/model/mwebsocket/mwebsocket.go` | Domain structs | +| Service | `packages/server/pkg/service/swebsocket/swebsocket.go` | Service + TX | +| Service | `packages/server/pkg/service/swebsocket/header.go` | Header service | +| Service | `packages/server/pkg/service/swebsocket/mapper.go` | DB row -> model conversion | +| RPC Handler | `packages/server/internal/api/rwebsocket/rwebsocket.go` | Full CRUD + sync + publisher | +| Flow Node Service | `packages/server/pkg/service/sflow/node_ws_connection.go` | Flow node type record | +| Flow Node Service | `packages/server/pkg/service/sflow/node_ws_connection_reader.go` | Reader | +| Flow Node Service | `packages/server/pkg/service/sflow/node_ws_connection_writer.go` | Writer | +| Flow Node Service | `packages/server/pkg/service/sflow/node_ws_connection_mapper.go` | Mapper | +| Flow Node Service | `packages/server/pkg/service/sflow/node_ws_send.go` | WS Send node type | +| Flow Node Service | `packages/server/pkg/service/sflow/node_ws_send_reader.go` | Reader | +| Flow Node Service | `packages/server/pkg/service/sflow/node_ws_send_writer.go` | Writer | +| Flow Node Service | `packages/server/pkg/service/sflow/node_ws_send_mapper.go` | Mapper | +| Node Executor | `packages/server/pkg/flow/node/nwsconnection/nwsconnection.go` | WS Connection runtime executor | +| Node Executor | `packages/server/pkg/flow/node/nwssend/nwssend.go` | WS Send runtime executor | +| Node Config CRUD | `packages/server/internal/api/rflowv2/rflowv2_node_ws_connection.go` | WS Connection node config CRUD + sync | +| Node Config CRUD | `packages/server/internal/api/rflowv2/rflowv2_node_ws_send.go` | WS Send node config CRUD + sync | +| Client Node | `packages/client/src/pages/flow/nodes/ws-connection.tsx` | Flow canvas node UI | +| Client Node | `packages/client/src/pages/flow/nodes/ws-send.tsx` | Flow canvas node UI | +| Client Page | `packages/client/src/pages/websocket/page.tsx` | WS request page | +| Client Page | `packages/client/src/pages/websocket/request/` | Request panel, headers, URL | +| Client Page | `packages/client/src/pages/websocket/response/` | Response panel | +| TypeSpec | `packages/spec/api/websocket.tsp` | API contract | + +### Existing Files Modified + +| Layer | File | What Changed | +|-------|------|-------------| +| DB Flow Schema | `packages/db/pkg/sqlc/schema/05_flow.sql` | Added `flow_node_ws_connection`, `flow_node_ws_send` tables | +| DB Flow Queries | `packages/db/pkg/sqlc/queries/flow.sql` | Added CRUD queries for WS node types | +| Flow Model | `packages/server/pkg/model/mflow/node_types.go` | Added `NodeWsConnection`, `NodeWsSend` structs | +| Flow Model | `packages/server/pkg/model/mflow/node.go` | Added `NODE_KIND_WS_CONNECTION`, `NODE_KIND_WS_SEND` | +| Flow Service | `packages/server/pkg/service/sflow/node_mapper.go` | Added WS node kind mapping | +| Flow Builder | `packages/server/pkg/flow/flowbuilder/builder.go` | Added WS services + `BuildNodes` cases | +| Flow RPC | `packages/server/internal/api/rflowv2/rflowv2.go` | Added WS services, streamers, node sync cases | +| Copy/Paste | `packages/server/internal/api/rflowv2/rflowv2_copy_paste.go` | Copy: `populateWebSocketBundle`. Paste: ID remap, var remap, DB create, event publish | +| YAML Types | `packages/server/pkg/translate/yamlflowsimplev2/types.go` | Added `YamlStepWsConnection`, `YamlStepWsSend`, `YamlStepWrapper` fields | +| YAML Exporter | `packages/server/pkg/translate/yamlflowsimplev2/exporter.go` | Added WS step export cases | +| YAML Converter | `packages/server/pkg/translate/yamlflowsimplev2/converter_node.go` | Added WS step processing | +| YAML Converter | `packages/server/pkg/translate/yamlflowsimplev2/converter_flow.go` | Added WS to `mergeFlowData` | +| Workspace Bundle | `packages/server/pkg/ioworkspace/types.go` | Added `WebSockets`, `WebSocketHeaders` fields | +| Workspace Export | `packages/server/pkg/ioworkspace/exporter.go` | Added WS entity fetching | +| Workspace Import | `packages/server/pkg/ioworkspace/importer.go` | Added WS service + import wiring | +| Workspace Import | `packages/server/pkg/ioworkspace/importer_flow.go` | Added `importWebSockets` | +| Server Wiring | `packages/server/cmd/serverrun/serverrun.go` | Added WS service, streamer, handler registration | +| Client File Tree | `packages/client/src/features/file-system/index.tsx` | Added WS drag-to-flow-canvas | +| Client Flow | `packages/client/src/pages/flow/node.tsx` | Added WS node rendering case | +| Client Flow | `packages/client/src/pages/flow/add-node.tsx` | Added WS to "Add Node" menu | + +### Key Pattern: WS Connection + WS Send (Two Node Types, One Entity) + +WebSocket is unique because it has TWO flow node types that share ONE sidebar entity: +- **WS Connection node** — opens the connection (references a `websocket` entity by ID) +- **WS Send node** — sends a message on an open connection (references a WS Connection node by name) + +This means: +- The `WsSend` node has a `WsConnectionNodeName` field that must be remapped during copy/paste +- The YAML step for `ws_send` has `ws_connection_node_name` linking to a `ws_connection` step +- When copying, the WS entity + headers are fetched via `populateWebSocketBundle` +- When pasting, WS entities always get new IDs (no USE_EXISTING reference mode for WS) + +--- + +## Checklist + +### Spec & DB +- [ ] TypeSpec models + service methods defined +- [ ] `pnpm nx run spec:build` — codegen passes +- [ ] DB schema created (`schema/_.sql`) +- [ ] Flow node table added to `schema/05_flow.sql` (e.g., `flow_node_`) +- [ ] DB queries created (`queries/.sql`) +- [ ] Flow node queries added to `queries/flow.sql` +- [ ] `pnpm nx run db:generate` — sqlc passes + +### Server Model & Service +- [ ] Model structs created (`pkg/model/m/`) +- [ ] Flow node model added to `pkg/model/mflow/node_types.go` +- [ ] Node kind constant added to `pkg/model/mflow/node.go` +- [ ] Service reader/writer created (`pkg/service/s/`) +- [ ] Flow node service created (`pkg/service/sflow/node_*.go` — service, reader, writer, mapper) +- [ ] Node kind mapping added to `pkg/service/sflow/node_mapper.go` + +### Mutation & Events +- [ ] Mutation helpers created (`pkg/mutation/insert_.go`, `update_.go`) +- [ ] Entity constant registered in mutation package +- [ ] Sync streamers defined and wired + +### Node Executor +- [ ] Executor package created (`pkg/flow/node/n/`) +- [ ] Implements `FlowNode` interface (`GetID`, `GetName`, `RunSync`, `RunAsync`) +- [ ] Implements `VariableIntrospector` (optional, for AI integration) + +### RPC & Wiring +- [ ] RPC handlers created (`internal/api/r/`) +- [ ] Node config CRUD handlers created (`rflowv2_node_.go`) +- [ ] Mutation publisher handles the entity type +- [ ] `serverrun.go` — service, streamer, and RPC handler wired + +### Flow Integration +- [ ] Flow builder — node kind case + service field added (`pkg/flow/flowbuilder/builder.go`) +- [ ] Flow duplicate — `nodeDetail` case added (`rflowv2_flow.go`) +- [ ] Copy/paste — copy and paste cases added +- [ ] YAML export/import — types, exporter, converter updated +- [ ] Workspace bundle — types, exporter, importer updated + +### Client +- [ ] Flow node component created (with module-level default) (`pages/flow/nodes/.tsx`) +- [ ] Node registered in `edit.tsx` (nodeTypes + settingsMap) +- [ ] Added to "Add Node" menu (`add-node.tsx`) +- [ ] Client sub-entity components created (headers, assertions) +- [ ] Route files with `onEnter` + `onStay` tab opening (for request-type nodes) +- [ ] File tree delta integration — `FileKind` enum, model, converters, delta file component (for request-type nodes with deltas) +- [ ] File tree drag-to-canvas (for request-type nodes) + +### Delta Service Layer +- [ ] Sub-entity schemas include delta columns (`parent_*_id`, `is_delta`, `delta_*` fields) +- [ ] `Create` method passes delta fields to sqlc params (not just base fields) +- [ ] `UpdateDelta` query + service method exists for each deltable entity/sub-entity +- [ ] Delta RPC handler calls `UpdateDelta`, not `Update` +- [ ] Top bar uses `useDeltaState` + `DeltaResetButton` for name/URL +- [ ] CodeMirror editors (query, variables, raw body) have `DeltaResetButton` +- [ ] Tab links use `activeOptions={{ exact: true }}` to prevent parent route highlighting + +### Verification +- [ ] CRUD handlers have `mut.Track()` with Payload for sync +- [ ] All tests pass (`task test`) +- [ ] Lints pass (`task lint`) 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..f15c6873b 100644 --- a/packages/server/internal/api/rfile/rfile.go +++ b/packages/server/internal/api/rfile/rfile.go @@ -142,6 +142,10 @@ 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.ContentTypeGraphQLDelta: + return apiv1.FileKind_FILE_KIND_GRAPH_Q_L_DELTA + case mfile.ContentTypeWebSocket: + return apiv1.FileKind_FILE_KIND_WEB_SOCKET default: return apiv1.FileKind_FILE_KIND_UNSPECIFIED } @@ -162,6 +166,10 @@ 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_GRAPH_Q_L_DELTA: + return mfile.ContentTypeGraphQLDelta + 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..8c79ce31b 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 @@ -289,6 +309,7 @@ type FlowServiceV2Services struct { GraphQLResponse sgraphql.GraphQLResponseService GraphQL *sgraphql.GraphQLService GraphQLHeader *sgraphql.GraphQLHeaderService + GraphQLAssert *sgraphql.GraphQLAssertService File *sfile.FileService Importer WorkspaceImporter Credential scredential.CredentialService @@ -370,6 +391,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 +460,14 @@ 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 + gqlas *sgraphql.GraphQLAssertService nes *sflow.NodeExecutionService fvs *sflow.FlowVariableService envs *senv.EnvironmentService @@ -466,6 +494,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 +507,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 +530,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,8 +587,14 @@ 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, + gqlas: deps.Services.GraphQLAssert, nes: deps.Services.NodeExecution, fvs: deps.Services.FlowVariable, envs: deps.Services.Env, @@ -554,6 +620,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 +632,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 +710,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 +895,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 +922,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 +1165,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 +1231,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..92d7c2246 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) + } + } } } @@ -216,11 +242,30 @@ func (s *FlowServiceV2RPC) populateHTTPBundle(ctx context.Context, httpID idwrap } } -// populateGraphQLBundle fetches headers for a GraphQL request and adds them to the bundle. +// populateGraphQLBundle fetches headers and assertions for a GraphQL request and adds them to the bundle. func (s *FlowServiceV2RPC) populateGraphQLBundle(ctx context.Context, graphqlID idwrap.IDWrap, bundle *ioworkspace.WorkspaceBundle) { if headers, err := s.gqlhs.GetByGraphQLID(ctx, graphqlID); err == nil { bundle.GraphQLHeaders = append(bundle.GraphQLHeaders, headers...) } + if s.gqlas != nil { + if asserts, err := s.gqlas.GetByGraphQLID(ctx, graphqlID); err == nil { + bundle.GraphQLAsserts = append(bundle.GraphQLAsserts, asserts...) + } + } +} + +// 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. @@ -390,6 +435,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 +500,21 @@ func (s *FlowServiceV2RPC) FlowNodesPaste( for i := range parsed.GraphQLHeaders { parsed.GraphQLHeaders[i].Value = remapVarRefs(parsed.GraphQLHeaders[i].Value, nameMapping) } + for i := range parsed.GraphQLAsserts { + parsed.GraphQLAsserts[i].Value = remapVarRefs(parsed.GraphQLAsserts[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 +692,49 @@ func (s *FlowServiceV2RPC) FlowNodesPaste( } } + // Remap GraphQL assertions and filter to only those needing creation + var gqlAssertsToCreate []mgraphql.GraphQLAssert + for i := range parsed.GraphQLAsserts { + a := &parsed.GraphQLAsserts[i] + if newID, ok := gqlIDMapping[a.GraphQLID]; ok { + a.GraphQLID = newID + a.ID = idwrap.NewNow() + a.IsDelta = false + a.ParentGraphQLAssertID = nil + if gqlIDsToCreate[newID] { + gqlAssertsToCreate = append(gqlAssertsToCreate, *a) + } + } + } + + // 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 { @@ -699,6 +817,14 @@ func (s *FlowServiceV2RPC) FlowNodesPaste( } } } + if s.gqlas != nil && len(gqlAssertsToCreate) > 0 { + gqlAssertWriter := s.gqlas.TX(tx) + for i := range gqlAssertsToCreate { + if err := gqlAssertWriter.Create(ctx, &gqlAssertsToCreate[i]); err != nil { + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to create GraphQL assert: %w", err)) + } + } + } // Create nodes var createdNodeIDs [][]byte @@ -767,6 +893,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 +981,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..7395827ed 100644 --- a/packages/server/internal/api/rgraphql/rgraphql_crud_assert.go +++ b/packages/server/internal/api/rgraphql/rgraphql_crud_assert.go @@ -273,6 +273,16 @@ func (s *GraphQLServiceRPC) GraphQLAssertUpdate(ctx context.Context, req *connec }); err != nil { return nil, connect.NewError(connect.CodeInternal, err) } + + mut.Track(mutation.Event{ + Entity: mutation.EntityGraphQLAssert, + Op: mutation.OpUpdate, + ID: assert.ID, + ParentID: assert.GraphQLID, + WorkspaceID: data.workspaceID, + Payload: assert, + Patch: assertPatch, + }) } if err := mut.Commit(ctx); err != nil { // Auto-publishes events! @@ -830,8 +840,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..648e09e69 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" @@ -262,7 +263,7 @@ func (s *GraphQLServiceRPC) GraphQLHeaderDeltaUpdate(ctx context.Context, req *c return nil, connect.NewError(connect.CodeInternal, err) } - err = s.headerService.TX(mut.TX()).Update(ctx, &existingDelta) + err = s.headerService.TX(mut.TX()).UpdateDelta(ctx, &existingDelta) if err != nil { return nil, connect.NewError(connect.CodeInternal, err) } @@ -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/rgraphql/rgraphql_exec.go b/packages/server/internal/api/rgraphql/rgraphql_exec.go index 4a77a6440..38ee42dfd 100644 --- a/packages/server/internal/api/rgraphql/rgraphql_exec.go +++ b/packages/server/internal/api/rgraphql/rgraphql_exec.go @@ -534,11 +534,15 @@ func (s *GraphQLServiceRPC) GraphQLDuplicate(ctx context.Context, req *connect.R return nil, err } - // Read headers outside TX + // Read sub-entities outside TX (SQLite deadlock prevention) headers, err := s.headerService.GetByGraphQLID(ctx, gqlID) if err != nil { headers = []mgraphql.GraphQLHeader{} } + asserts, err := s.graphqlAssertService.GetByGraphQLID(ctx, gqlID) + if err != nil { + asserts = []mgraphql.GraphQLAssert{} + } newGQLID := idwrap.NewNow() @@ -550,6 +554,7 @@ func (s *GraphQLServiceRPC) GraphQLDuplicate(ctx context.Context, req *connect.R txGraphqlService := s.graphqlService.TX(tx) txHeaderService := s.headerService.TX(tx) + txAssertService := s.graphqlAssertService.TX(tx) newEntry := &mgraphql.GraphQL{ ID: newGQLID, @@ -581,6 +586,20 @@ func (s *GraphQLServiceRPC) GraphQLDuplicate(ctx context.Context, req *connect.R } } + for _, a := range asserts { + newAssert := &mgraphql.GraphQLAssert{ + ID: idwrap.NewNow(), + GraphQLID: newGQLID, + Value: a.Value, + Enabled: a.Enabled, + Description: a.Description, + DisplayOrder: a.DisplayOrder, + } + if err := txAssertService.Create(ctx, newAssert); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + } + if err := tx.Commit(); err != nil { return nil, connect.NewError(connect.CodeInternal, err) } diff --git a/packages/server/internal/api/rgraphql/rgraphql_exec_assert.go b/packages/server/internal/api/rgraphql/rgraphql_exec_assert.go index 11d67f3aa..e4d08a451 100644 --- a/packages/server/internal/api/rgraphql/rgraphql_exec_assert.go +++ b/packages/server/internal/api/rgraphql/rgraphql_exec_assert.go @@ -260,52 +260,27 @@ func (s *GraphQLServiceRPC) createAssertionEvalContext(resp GraphQLResponseData) // Convert headers to map headers := make(map[string]string) - headersLower := make(map[string]string) contentType := "" for key, value := range resp.Headers { - lowerKey := strings.ToLower(key) headers[key] = value - headersLower[lowerKey] = value - if lowerKey == "content-type" { + if strings.EqualFold(key, "content-type") { contentType = value } } - // Extract GraphQL-specific fields from response - var data any - var errors any - if bodyMap != nil { - if d, ok := bodyMap["data"]; ok { - data = d - } - if e, ok := bodyMap["errors"]; ok { - errors = e - } - } - // Extract JSON path helpers (for full body navigation) jsonPathHelpers := s.createJSONPathHelpers(bodyMap) - // Extract JSON path helpers for data field specifically - var dataMap map[string]any - if data != nil { - if dm, ok := data.(map[string]any); ok { - dataMap = dm - } - } - dataPathHelpers := s.createJSONPathHelpers(dataMap) - // Create comprehensive evaluation context + // Users access GraphQL data via response.body.data or body.data (consistent with HTTP) context := map[string]any{ // Main response object "response": map[string]any{ "status": resp.StatusCode, "body": body, "headers": headers, - "data": data, - "errors": errors, }, // Direct access to commonly used fields @@ -315,23 +290,15 @@ func (s *GraphQLServiceRPC) createAssertionEvalContext(resp GraphQLResponseData) "headers": headers, "content_type": contentType, - // GraphQL-specific fields (top-level for convenience) - "data": data, - "errors": errors, - // Convenience variables "success": resp.StatusCode >= 200 && resp.StatusCode < 300, "client_error": resp.StatusCode >= 400 && resp.StatusCode < 500, "server_error": resp.StatusCode >= 500 && resp.StatusCode < 600, "is_json": strings.HasPrefix(contentType, "application/json"), "has_body": len(resp.Body) > 0, - "has_data": data != nil, - "has_errors": errors != nil, // JSON path helpers (for full body) "json": jsonPathHelpers, - // JSON path helpers specifically for data field - "dataJson": dataPathHelpers, } return context 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..350c73969 100644 --- a/packages/server/internal/api/rreference/rreference.go +++ b/packages/server/internal/api/rreference/rreference.go @@ -563,8 +563,52 @@ 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) } + + case mflow.NODE_KIND_GRAPHQL: + // For GRAPHQL nodes, provide the schema structure + nodeVarsMap := map[string]interface{}{ + "request": map[string]interface{}{ + "url": "string", + "query": "string", + "variables": map[string]interface{}{}, + "headers": map[string]string{}, + }, + "response": map[string]interface{}{ + "status": 200, + "body": map[string]interface{}{}, + "headers": map[string]string{}, + "duration": 0, + }, + } + nodeVarRef := reference.NewReferenceFromInterfaceWithKey(nodeVarsMap, node.Name) + if err := appendNodeRef(nodeVarRef, fmt.Sprintf("node %q graphql schema", node.Name)); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + case mflow.NODE_KIND_WS_CONNECTION: + nodeVarsMap := map[string]interface{}{ + "url": "string", + "connected": false, + "lastMessage": "string", + } + nodeVarRef := reference.NewReferenceFromInterfaceWithKey(nodeVarsMap, node.Name) + if err := appendNodeRef(nodeVarRef, fmt.Sprintf("node %q ws connection schema", node.Name)); err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + case mflow.NODE_KIND_WS_SEND: + nodeVarsMap := map[string]interface{}{ + "type": "string", + "message": "string", + "connectionNode": "string", + } + nodeVarRef := reference.NewReferenceFromInterfaceWithKey(nodeVarsMap, node.Name) + if err := appendNodeRef(nodeVarRef, fmt.Sprintf("node %q ws send 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 @@ -829,6 +873,40 @@ func (c *ReferenceServiceRPC) ReferenceCompletion(ctx context.Context, req *conn } creator.AddWithKey(node.Name, nodeVarsMap) + case mflow.NODE_KIND_GRAPHQL: + // For GRAPHQL nodes, provide the schema structure + nodeVarsMap := map[string]interface{}{ + "request": map[string]interface{}{ + "url": "string", + "query": "string", + "variables": map[string]interface{}{}, + "headers": map[string]string{}, + }, + "response": map[string]interface{}{ + "status": 200, + "body": map[string]interface{}{}, + "headers": map[string]string{}, + "duration": 0, + }, + } + creator.AddWithKey(node.Name, nodeVarsMap) + + case mflow.NODE_KIND_WS_CONNECTION: + nodeVarsMap := map[string]interface{}{ + "url": "string", + "connected": false, + "lastMessage": "string", + } + creator.AddWithKey(node.Name, nodeVarsMap) + + case mflow.NODE_KIND_WS_SEND: + nodeVarsMap := map[string]interface{}{ + "type": "string", + "message": "string", + "connectionNode": "string", + } + creator.AddWithKey(node.Name, nodeVarsMap) + case mflow.NODE_KIND_AI: // For AI nodes, provide the output schema nodeVarsMap := map[string]interface{}{ @@ -860,6 +938,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 +1094,63 @@ func (c *ReferenceServiceRPC) ReferenceCompletion(ctx context.Context, req *conn "duration": 0, }) } + + case mflow.NODE_KIND_GRAPHQL: + // GRAPHQL nodes can reference their own response and request directly (without prefix) + var nodeData interface{} + hasExecutionData := false + + executions, err := c.nodeExecutionReader.GetNodeExecutionsByNodeID(ctx, currentNode.ID) + if err == nil && len(executions) > 0 { + latestExecution := &executions[0] + + if true { + data := latestExecution.OutputData + if latestExecution.OutputDataCompressType != compress.CompressTypeNone { + decompressed, err := compress.Decompress(data, latestExecution.OutputDataCompressType) + if err == nil { + data = decompressed + } + } + + var genericOutput interface{} + if err := json.Unmarshal(data, &genericOutput); err == nil { + nodeData = genericOutput + hasExecutionData = true + } + } + } + + dataAdded := false + if hasExecutionData && nodeData != nil { + if nodeMap, ok := nodeData.(map[string]interface{}); ok { + if nodeSpecificData, hasNodeKey := nodeMap[currentNode.Name]; hasNodeKey { + if nodeVars, ok := nodeSpecificData.(map[string]interface{}); ok { + for key, value := range nodeVars { + creator.AddWithKey(key, value) + } + dataAdded = true + } + } + } + } + + if !dataAdded { + creator.AddWithKey("request", map[string]interface{}{ + "url": "string", + "query": "string", + "variables": map[string]interface{}{}, + "headers": map[string]string{}, + }) + creator.AddWithKey("response", map[string]interface{}{ + "status": 200, + "body": map[string]interface{}{}, + "headers": map[string]string{}, + "duration": 0, + }) + } + default: + // Other node types don't have self-reference schemas } } } @@ -1297,8 +1434,43 @@ func (c *ReferenceServiceRPC) ReferenceValue(ctx context.Context, req *connect.R }, } lookup.AddWithKey(node.Name, nodeVarsMap) + + case mflow.NODE_KIND_GRAPHQL: + // For GRAPHQL nodes, provide the schema structure + nodeVarsMap := map[string]interface{}{ + "request": map[string]interface{}{ + "url": "string", + "query": "string", + "variables": map[string]interface{}{}, + "headers": map[string]string{}, + }, + "response": map[string]interface{}{ + "status": 200, + "body": map[string]interface{}{}, + "headers": map[string]string{}, + "duration": 0, + }, + } + lookup.AddWithKey(node.Name, nodeVarsMap) + + case mflow.NODE_KIND_WS_CONNECTION: + nodeVarsMap := map[string]interface{}{ + "url": "string", + "connected": false, + "lastMessage": "string", + } + lookup.AddWithKey(node.Name, nodeVarsMap) + + case mflow.NODE_KIND_WS_SEND: + nodeVarsMap := map[string]interface{}{ + "type": "string", + "message": "string", + "connectionNode": "string", + } + 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 +1584,61 @@ func (c *ReferenceServiceRPC) ReferenceValue(ctx context.Context, req *connect.R "duration": 0, }) } + + case mflow.NODE_KIND_GRAPHQL: + // GRAPHQL nodes can reference their own response and request directly (without prefix) + var nodeData interface{} + hasExecutionData := false + + executions, err := c.nodeExecutionReader.GetNodeExecutionsByNodeID(ctx, currentNode.ID) + if err == nil && len(executions) > 0 { + latestExecution := executions[0] + + data := latestExecution.OutputData + if latestExecution.OutputDataCompressType != compress.CompressTypeNone { + decompressed, err := compress.Decompress(data, latestExecution.OutputDataCompressType) + if err == nil { + data = decompressed + } + } + + var genericOutput interface{} + if err := json.Unmarshal(data, &genericOutput); err == nil { + nodeData = genericOutput + hasExecutionData = true + } + } + + dataAdded := false + if hasExecutionData && nodeData != nil { + if nodeMap, ok := nodeData.(map[string]interface{}); ok { + if nodeSpecificData, hasNodeKey := nodeMap[currentNode.Name]; hasNodeKey { + if nodeVars, ok := nodeSpecificData.(map[string]interface{}); ok { + for key, value := range nodeVars { + lookup.AddWithKey(key, value) + } + dataAdded = true + } + } + } + } + + if !dataAdded { + lookup.AddWithKey("request", map[string]interface{}{ + "url": "string", + "query": "string", + "variables": map[string]interface{}{}, + "headers": map[string]string{}, + }) + lookup.AddWithKey("response", map[string]interface{}{ + "status": 200, + "body": map[string]interface{}{}, + "headers": map[string]string{}, + "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..21290b230 100644 --- a/packages/server/internal/converter/converter.go +++ b/packages/server/internal/converter/converter.go @@ -351,6 +351,12 @@ func ToAPIFileKind(kind mfile.ContentType) filev1.FileKind { return filev1.FileKind_FILE_KIND_FLOW case mfile.ContentTypeCredential: return filev1.FileKind_FILE_KIND_CREDENTIAL + case mfile.ContentTypeGraphQL: + return filev1.FileKind_FILE_KIND_GRAPH_Q_L + case mfile.ContentTypeGraphQLDelta: + return filev1.FileKind_FILE_KIND_GRAPH_Q_L_DELTA + case mfile.ContentTypeWebSocket: + return filev1.FileKind_FILE_KIND_WEB_SOCKET default: return filev1.FileKind_FILE_KIND_UNSPECIFIED } @@ -379,6 +385,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/01KK31SQ_add_graphql_delta_file_kind.go b/packages/server/internal/migrations/01KK31SQ_add_graphql_delta_file_kind.go new file mode 100644 index 000000000..1356299c3 --- /dev/null +++ b/packages/server/internal/migrations/01KK31SQ_add_graphql_delta_file_kind.go @@ -0,0 +1,122 @@ +package migrations + +import ( + "context" + "database/sql" + "fmt" + "strings" + + "github.com/the-dev-tools/dev-tools/packages/server/internal/migrate" +) + +// MigrationAddGraphQLDeltaFileKindID is the ULID for the GraphQL delta file kind migration. +const MigrationAddGraphQLDeltaFileKindID = "01KK31SQD0GFP92RZ3XMN5V6BQ" + +// MigrationAddGraphQLDeltaFileKindChecksum is a stable hash of this migration. +const MigrationAddGraphQLDeltaFileKindChecksum = "sha256:add-graphql-delta-file-kind-v1" + +func init() { + if err := migrate.Register(migrate.Migration{ + ID: MigrationAddGraphQLDeltaFileKindID, + Checksum: MigrationAddGraphQLDeltaFileKindChecksum, + Description: "Add GraphQL delta content_kind (7) to files table CHECK constraint", + Apply: applyGraphQLDeltaFileKind, + Validate: validateGraphQLDeltaFileKind, + RequiresBackup: true, + }); err != nil { + panic("failed to register GraphQL delta file kind migration: " + err.Error()) + } +} + +func applyGraphQLDeltaFileKind(ctx context.Context, tx *sql.Tx) error { + return updateFilesCheckConstraintGraphQLDelta(ctx, tx) +} + +// updateFilesCheckConstraintGraphQLDelta recreates the files table with GraphQL delta content_kind support. +func updateFilesCheckConstraintGraphQLDelta(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, "6, 7)") { + 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, 7)), + 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_kind = 7 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 validateGraphQLDeltaFileKind(ctx context.Context, db *sql.DB) error { + var tableSql string + err := db.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, "6, 7)") { + return fmt.Errorf("files table CHECK constraint does not include content_kind 7 (graphql_delta)") + } + 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..8a8940716 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,9 @@ func (wb *WorkspaceBundle) CountEntities() map[string]int { "http_asserts": len(wb.HTTPAsserts), "graphql_requests": len(wb.GraphQLRequests), "graphql_headers": len(wb.GraphQLHeaders), + "graphql_asserts": len(wb.GraphQLAsserts), + "websockets": len(wb.WebSockets), + "websocket_headers": len(wb.WebSocketHeaders), "files": len(wb.Files), "flows": len(wb.Flows), "flow_variables": len(wb.FlowVariables), @@ -86,8 +97,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..30a7bedea 100644 --- a/packages/server/pkg/model/mfile/mfile.go +++ b/packages/server/pkg/model/mfile/mfile.go @@ -18,7 +18,9 @@ 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 + ContentTypeGraphQLDelta ContentType = 7 // graphql delta (draft/overlay) ) // String returns the string representation of ContentType @@ -36,6 +38,10 @@ func (ct ContentType) String() string { return "credential" case ContentTypeGraphQL: return "graphql" + case ContentTypeWebSocket: + return "websocket" + case ContentTypeGraphQLDelta: + return "graphql_delta" default: return "unknown" } @@ -95,6 +101,16 @@ 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 +} + +// IsGraphQLDelta returns true if the file contains a GraphQL delta request +func (f File) IsGraphQLDelta() bool { + return f.ContentType == ContentTypeGraphQLDelta +} + // IsRoot returns true if the file has no parent folder func (f File) IsRoot() bool { return f.ParentID == nil @@ -140,6 +156,10 @@ func ContentTypeFromString(s string) ContentType { return ContentTypeCredential case "graphql": return ContentTypeGraphQL + case "websocket": + return ContentTypeWebSocket + case "graphql_delta": + return ContentTypeGraphQLDelta default: return ContentTypeUnknown } @@ -147,7 +167,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 == ContentTypeGraphQLDelta || 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..ccb4194d1 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 { @@ -59,7 +70,7 @@ func (s GraphQLHeaderService) Create(ctx context.Context, header *mgraphql.Graph header.CreatedAt = now.Unix() header.UpdatedAt = now.Unix() - return s.queries.CreateGraphQLHeader(ctx, gen.CreateGraphQLHeaderParams{ + params := gen.CreateGraphQLHeaderParams{ ID: header.ID, GraphqlID: header.GraphQLID, HeaderKey: header.Key, @@ -69,7 +80,29 @@ func (s GraphQLHeaderService) Create(ctx context.Context, header *mgraphql.Graph DisplayOrder: float64(header.DisplayOrder), CreatedAt: header.CreatedAt, UpdatedAt: header.UpdatedAt, - }) + IsDelta: header.IsDelta, + } + + if header.ParentGraphQLHeaderID != nil { + params.ParentGraphqlHeaderID = header.ParentGraphQLHeaderID.Bytes() + } + if header.DeltaKey != nil { + params.DeltaHeaderKey = *header.DeltaKey + } + if header.DeltaValue != nil { + params.DeltaHeaderValue = *header.DeltaValue + } + if header.DeltaDescription != nil { + params.DeltaDescription = *header.DeltaDescription + } + if header.DeltaEnabled != nil { + params.DeltaEnabled = *header.DeltaEnabled + } + if header.DeltaDisplayOrder != nil { + params.DeltaDisplayOrder = *header.DeltaDisplayOrder + } + + return s.queries.CreateGraphQLHeader(ctx, params) } func (s GraphQLHeaderService) Update(ctx context.Context, header *mgraphql.GraphQLHeader) error { @@ -83,6 +116,18 @@ func (s GraphQLHeaderService) Update(ctx context.Context, header *mgraphql.Graph }) } +func (s GraphQLHeaderService) UpdateDelta(ctx context.Context, header *mgraphql.GraphQLHeader) error { + return s.queries.UpdateGraphQLHeaderDelta(ctx, gen.UpdateGraphQLHeaderDeltaParams{ + ID: header.ID, + DeltaHeaderKey: header.DeltaKey, + DeltaHeaderValue: header.DeltaValue, + DeltaDescription: header.DeltaDescription, + DeltaEnabled: header.DeltaEnabled, + DeltaDisplayOrder: header.DeltaDisplayOrder, + UpdatedAt: dbtime.DBNow().Unix(), + }) +} + func (s GraphQLHeaderService) Delete(ctx context.Context, id idwrap.IDWrap) error { return s.queries.DeleteGraphQLHeader(ctx, id) } 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..b1a7aafad 100644 --- a/packages/spec/api/file-system.tsp +++ b/packages/spec/api/file-system.tsp @@ -9,6 +9,8 @@ enum FileKind { Flow, Credential, GraphQL, + GraphQLDelta, + 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' }], }, });