diff --git a/apps/console/package.json b/apps/console/package.json index ee238a536..091e943db 100644 --- a/apps/console/package.json +++ b/apps/console/package.json @@ -53,6 +53,7 @@ "autoprefixer": "^10.4.20", "babel-plugin-relay": "^18.2.0", "esbuild": "^0.25.0", + "eslint": "^9.21.0", "relay-compiler": "^18.2.0", "tailwindcss": "^3.4.17", "typescript": "^5.7.3" diff --git a/apps/console/src/App.tsx b/apps/console/src/App.tsx index 93ebb751c..87f09dd3b 100644 --- a/apps/console/src/App.tsx +++ b/apps/console/src/App.tsx @@ -4,7 +4,13 @@ import { lazy, StrictMode, Suspense } from "react"; import { createRoot } from "react-dom/client"; import { HelmetProvider } from "react-helmet-async"; import { RelayEnvironmentProvider } from "react-relay"; -import { BrowserRouter, Route, Routes, useLocation } from "react-router"; +import { + BrowserRouter, + Route, + Routes, + useLocation, + Navigate, +} from "react-router"; import "App.css"; import ErrorBoundary from "./components/ErrorBoundary"; import ConsoleLayout from "./layouts/ConsoleLayout"; @@ -12,7 +18,6 @@ import AuthLayout from "./layouts/AuthLayout"; import { RelayEnvironment } from "./RelayEnvironment"; import { AuthProvider } from "./contexts/AuthContext"; import { ProtectedRoute } from "./components/ProtectedRoute"; -import { OrganizationProvider } from "./contexts/OrganizationContext"; posthog.init(process.env.POSTHOG_KEY!, { api_host: process.env.POSTHOG_HOST, @@ -24,6 +29,9 @@ posthog.init(process.env.POSTHOG_KEY!, { }, }); +const OrganizationSelectionPage = lazy( + () => import("./pages/OrganizationSelectionPage") +); const HomePage = lazy(() => import("./pages/HomePage")); const NotFoundPage = lazy(() => import("./pages/NotFoundPage")); const PeopleListPage = lazy(() => import("./pages/PeopleListPage")); @@ -52,181 +60,194 @@ function App() { - - - {/* Authentication Routes - Accessible without login */} + + {/* Authentication Routes - Accessible without login */} + + + + } + > - - - } - > - - - - - - } - /> - - - - - - } - > - - - - - - } - /> - - - {/* Protected Routes - Require authentication */} - }> - - + + + } + /> + + + + + + } + > + + + + + + } + /> + + + {/* Protected Routes - Require authentication */} + }> + {/* Organization Selection Route */} + + + + + + } + /> + + {/* Organization Creation Route */} + + + + + + } + /> + + {/* Organization-specific Routes */} + + + + } + > + + + + + } - > - - - - - - } - /> - - - - - - } - /> - - - - - - } - /> - - - - - - } - /> - - - - - - } - /> - - - - - - } - /> - - - - - - } - /> - - - - - - } - /> - - - - - - } - /> - - - - - - } - /> - - - - - - } - /> - - - - } - /> - + /> + + + + + + } + /> + + + + + + } + /> + + + + + + } + /> + + + + + + } + /> + + + + + + } + /> + + + + + + } + /> + + + + + + } + /> + + + + + + } + /> + + + + + + } + /> + + + + } + /> - - + + diff --git a/apps/console/src/components/AppSidebar.tsx b/apps/console/src/components/AppSidebar.tsx index cdb927ced..379b46cb5 100644 --- a/apps/console/src/components/AppSidebar.tsx +++ b/apps/console/src/components/AppSidebar.tsx @@ -1,5 +1,6 @@ import * as React from "react"; import { Suspense, useEffect } from "react"; +import { useParams } from "react-router"; import { BookOpen, Users, @@ -31,55 +32,52 @@ import { } from "@/components/ui/sidebar"; import type { AppSidebarQuery as AppSidebarQueryType } from "./__generated__/AppSidebarQuery.graphql"; import { TeamSwitcher } from "@/components/TeamSwitcher"; -import { url } from "inspector"; -const staticData = { - user: { - name: "shadcn", - email: "m@example.com", - avatar: "/avatars/shadcn.jpg", - }, - navMain: [ - { - title: "Frameworks", - url: "/frameworks", - icon: BookOpen, - }, - { - title: "Organizations", - icon: Building, - url: "/peoples", - items: [ - { - title: "Peoples", - url: "/peoples", - icon: Users, - }, - { - title: "Vendors", - url: "/vendors", - icon: ToyBrick, - }, - ], - }, - { - title: "Settings", - url: "/settings", - icon: Settings, - }, - ], - navSecondary: [ - { - title: "Support", - url: "#", - icon: LifeBuoy, - }, - { - title: "Feedback", - url: "#", - icon: Send, - }, - ], -}; + +function getNavItems(organizationId: string) { + return { + navMain: [ + { + title: "Frameworks", + url: `/organizations/${organizationId}/frameworks`, + icon: BookOpen, + }, + { + title: "Organizations", + icon: Building, + url: `/organizations/${organizationId}/peoples`, + items: [ + { + title: "Peoples", + url: `/organizations/${organizationId}/peoples`, + icon: Users, + }, + { + title: "Vendors", + url: `/organizations/${organizationId}/vendors`, + icon: ToyBrick, + }, + ], + }, + { + title: "Settings", + url: `/organizations/${organizationId}/settings`, + icon: Settings, + }, + ], + navSecondary: [ + { + title: "Support", + url: "#", + icon: LifeBuoy, + }, + { + title: "Feedback", + url: "#", + icon: Send, + }, + ], + }; +} const AppSidebarQuery = graphql` query AppSidebarQuery { @@ -97,7 +95,9 @@ function AppSidebarContent({ }: React.ComponentProps & { queryRef: PreloadedQuery; }) { + const { organizationId } = useParams(); const data = usePreloadedQuery(AppSidebarQuery, queryRef); + const navItems = getNavItems(organizationId!); return ( @@ -105,8 +105,8 @@ function AppSidebarContent({ - - + + @@ -121,39 +121,37 @@ function AppSidebarFallback(props: React.ComponentProps) { - - -
-
- -
- - Enterprise -
-
+ +
+
+
+
+
- - + + {Array.from({ length: 3 }).map((_, i) => ( + + +
+
+ + + ))} + - - -
-
- -
- - -
- -
-
+ +
+
+
+
+
diff --git a/apps/console/src/components/NavUser.tsx b/apps/console/src/components/NavUser.tsx index ef10f8830..2cd0f25b1 100644 --- a/apps/console/src/components/NavUser.tsx +++ b/apps/console/src/components/NavUser.tsx @@ -9,6 +9,7 @@ import { Sparkles, } from "lucide-react"; import { graphql, useFragment } from "react-relay"; +import { useNavigate } from "react-router"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { @@ -26,6 +27,7 @@ import { SidebarMenuItem, useSidebar, } from "@/components/ui/sidebar"; +import { useAuth } from "@/contexts/AuthContext"; import { NavUser_viewer$key, NavUser_viewer$data, @@ -42,6 +44,13 @@ export const navUserFragment = graphql` export function NavUser({ viewer }: { viewer: NavUser_viewer$key }) { const { isMobile } = useSidebar(); const currentUser = useFragment(navUserFragment, viewer); + const { logout } = useAuth(); + const navigate = useNavigate(); + + const handleLogout = async () => { + await logout(); + navigate("/login"); + }; return ( @@ -116,7 +125,7 @@ export function NavUser({ viewer }: { viewer: NavUser_viewer$key }) { - + Log out diff --git a/apps/console/src/components/TeamSwitcher.tsx b/apps/console/src/components/TeamSwitcher.tsx index 38fd759b4..3e2384a3f 100644 --- a/apps/console/src/components/TeamSwitcher.tsx +++ b/apps/console/src/components/TeamSwitcher.tsx @@ -3,8 +3,7 @@ import { useState, useEffect } from "react"; import { ChevronsUpDown, Plus } from "lucide-react"; import { graphql, useFragment } from "react-relay"; -import { useOrganization } from "@/contexts/OrganizationContext"; -import { Link } from "react-router"; +import { Link, useNavigate, useParams } from "react-router"; import { DropdownMenu, @@ -54,20 +53,22 @@ export function TeamSwitcher({ }) { const { isMobile } = useSidebar(); const data = useFragment(teamSwitcherFragment, organizations); - const { currentOrganization, setCurrentOrganization } = useOrganization(); + const navigate = useNavigate(); + const { organizationId } = useParams(); + const [currentOrganization, setCurrentOrganization] = + useState(null); useEffect(() => { - console.log(data.organizations); - - if ( - data.organizations && - data.organizations.edges.length > 0 && - !currentOrganization - ) { - // Type assertion to include plan field - setCurrentOrganization(data.organizations.edges[0].node); + if (data.organizations && data.organizations.edges.length > 0) { + // Find the current organization based on the URL parameter + const org = data.organizations.edges.find( + (edge) => edge.node.id === organizationId + ); + if (org) { + setCurrentOrganization(org.node); + } } - }, [data.organizations, currentOrganization, setCurrentOrganization]); + }, [data.organizations, organizationId]); // If no organizations or data is still loading if (!currentOrganization) { @@ -88,6 +89,11 @@ export function TeamSwitcher({ return null; }; + const handleOrganizationSwitch = (org: Organization) => { + // Navigate to the selected organization + navigate(`/organizations/${org.id}`); + }; + return ( @@ -121,7 +127,7 @@ export function TeamSwitcher({ {data.organizations.edges.map((edge, index) => ( setCurrentOrganization(edge.node)} + onClick={() => handleOrganizationSwitch(edge.node)} className="gap-2 p-2" >
diff --git a/apps/console/src/contexts/OrganizationContext.tsx b/apps/console/src/contexts/OrganizationContext.tsx deleted file mode 100644 index f98d25bc1..000000000 --- a/apps/console/src/contexts/OrganizationContext.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import React, { createContext, useContext, useState, ReactNode } from "react"; - -interface Organization { - id: string; - name: string; - logoUrl: string; -} - -interface OrganizationContextType { - currentOrganization: Organization | null; - setCurrentOrganization: (organization: Organization) => void; -} - -const OrganizationContext = createContext( - undefined, -); - -export function useOrganization() { - const context = useContext(OrganizationContext); - if (context === undefined) { - throw new Error( - "useOrganization must be used within an OrganizationProvider", - ); - } - return context; -} - -interface OrganizationProviderProps { - children: ReactNode; -} - -export function OrganizationProvider({ children }: OrganizationProviderProps) { - const [currentOrganization, setCurrentOrganization] = - useState(null); - - return ( - - {children} - - ); -} diff --git a/apps/console/src/layouts/ConsoleLayout.tsx b/apps/console/src/layouts/ConsoleLayout.tsx index 2b137894e..be224e2c9 100644 --- a/apps/console/src/layouts/ConsoleLayout.tsx +++ b/apps/console/src/layouts/ConsoleLayout.tsx @@ -29,14 +29,32 @@ import { ConsoleLayoutBreadcrumbFrameworkOverviewQuery } from "./__generated__/C import { ConsoleLayoutBreadcrumbPeopleOverviewQuery } from "./__generated__/ConsoleLayoutBreadcrumbPeopleOverviewQuery.graphql"; import { ConsoleLayoutBreadcrumbVendorOverviewQuery } from "./__generated__/ConsoleLayoutBreadcrumbVendorOverviewQuery.graphql"; import { ConsoleLayoutBreadcrumbControlOverviewQuery } from "./__generated__/ConsoleLayoutBreadcrumbControlOverviewQuery.graphql"; +import { ConsoleLayoutOrganizationQuery } from "./__generated__/ConsoleLayoutOrganizationQuery.graphql"; function BreadcrumbHome({ children }: { children: React.ReactNode }) { + const { organizationId } = useParams(); + const data = useLazyLoadQuery( + graphql` + query ConsoleLayoutOrganizationQuery($organizationId: ID!) { + organization: node(id: $organizationId) { + ... on Organization { + name + } + } + } + `, + { organizationId: organizationId! }, + { fetchPolicy: "store-or-network" } + ); + return ( - Home + + {data.organization?.name || "Home"} + {children} @@ -46,12 +64,15 @@ function BreadcrumbHome({ children }: { children: React.ReactNode }) { } function BreadcrumbFrameworkList() { + const { organizationId } = useParams(); return ( <> - Frameworks + + Frameworks + @@ -60,7 +81,7 @@ function BreadcrumbFrameworkList() { } function BreadcrumbFrameworkOverview() { - const { frameworkId } = useParams(); + const { organizationId, frameworkId } = useParams(); const data = useLazyLoadQuery( graphql` query ConsoleLayoutBreadcrumbFrameworkOverviewQuery($frameworkId: ID!) { @@ -81,7 +102,9 @@ function BreadcrumbFrameworkOverview() { - + {data.framework.name} @@ -91,71 +114,14 @@ function BreadcrumbFrameworkOverview() { ); } -function BreadcrumbPeopleList() { - return ( - <> - - - - People - - - - - ); -} - -function BreadcrumbCreatePeople() { - return ( - <> - - - - Create People - - - - - ); -} - -function BreadcrumbPeopleOverview() { - const { peopleId } = useParams(); - const data = useLazyLoadQuery( - graphql` - query ConsoleLayoutBreadcrumbPeopleOverviewQuery($peopleId: ID!) { - people: node(id: $peopleId) { - id - ... on People { - fullName - } - } - } - `, - { peopleId: peopleId! }, - { fetchPolicy: "store-or-network" } - ); - - return ( - <> - - - - {data.people.fullName} - - - - - ); -} - function BreadcrumbVendorList() { + const { organizationId } = useParams(); return ( <> - Vendors + Vendors @@ -164,7 +130,7 @@ function BreadcrumbVendorList() { } function BreadcrumbVendorOverview() { - const { vendorId } = useParams(); + const { organizationId, vendorId } = useParams(); const data = useLazyLoadQuery( graphql` query ConsoleLayoutBreadcrumbVendorOverviewQuery($vendorId: ID!) { @@ -185,15 +151,91 @@ function BreadcrumbVendorOverview() { - {data.vendor.name} + + {data.vendor.name} + + + + ); +} + +function BreadcrumbPeopleList() { + const { organizationId } = useParams(); + return ( + <> + + + + People + + + + + ); +} + +function BreadcrumbCreatePeople() { + return ( + <> + + + Create + + + ); +} + +function BreadcrumbPeopleOverview() { + const { organizationId, peopleId } = useParams(); + const data = useLazyLoadQuery( + graphql` + query ConsoleLayoutBreadcrumbPeopleOverviewQuery($peopleId: ID!) { + people: node(id: $peopleId) { + id + ... on People { + fullName + } + } + } + `, + { peopleId: peopleId! }, + { fetchPolicy: "store-or-network" } + ); + + return ( + <> + + + + + {data.people.fullName} + + + + + + ); +} + +function BreadcrumbCreateOrganization() { + return ( + <> + + + Create Organization + ); } function BreadcrumbControlOverview() { - const { frameworkId, controlId } = useParams(); + const { organizationId, frameworkId, controlId } = useParams(); const data = useLazyLoadQuery( graphql` query ConsoleLayoutBreadcrumbControlOverviewQuery( @@ -223,7 +265,9 @@ function BreadcrumbControlOverview() { - + {data.framework.name} @@ -232,7 +276,7 @@ function BreadcrumbControlOverview() { {data.control.name} @@ -243,21 +287,9 @@ function BreadcrumbControlOverview() { ); } -function BreadcrumbCreateOrganization() { - return ( - <> - - - - Create Organization - - - - - ); -} - export default function ConsoleLayout() { + const { organizationId } = useParams(); + return ( @@ -268,36 +300,29 @@ export default function ConsoleLayout() { - }> + }> } /> } /> - }> + }> } /> - } - /> + } /> - }> + }> } /> - } - />
diff --git a/apps/console/src/layouts/__generated__/ConsoleLayoutOrganizationQuery.graphql.ts b/apps/console/src/layouts/__generated__/ConsoleLayoutOrganizationQuery.graphql.ts new file mode 100644 index 000000000..433df9c72 --- /dev/null +++ b/apps/console/src/layouts/__generated__/ConsoleLayoutOrganizationQuery.graphql.ts @@ -0,0 +1,124 @@ +/** + * @generated SignedSource<<93800eee21fa3f30cc45da37370359fd>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +export type ConsoleLayoutOrganizationQuery$variables = { + organizationId: string; +}; +export type ConsoleLayoutOrganizationQuery$data = { + readonly organization: { + readonly name?: string; + }; +}; +export type ConsoleLayoutOrganizationQuery = { + response: ConsoleLayoutOrganizationQuery$data; + variables: ConsoleLayoutOrganizationQuery$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "organizationId" + } +], +v1 = [ + { + "kind": "Variable", + "name": "id", + "variableName": "organizationId" + } +], +v2 = { + "kind": "InlineFragment", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + } + ], + "type": "Organization", + "abstractKey": null +}; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "ConsoleLayoutOrganizationQuery", + "selections": [ + { + "alias": "organization", + "args": (v1/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v2/*: any*/) + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "ConsoleLayoutOrganizationQuery", + "selections": [ + { + "alias": "organization", + "args": (v1/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null + }, + (v2/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null + } + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "e275faa366380b1b423251e6a06ab743", + "id": null, + "metadata": {}, + "name": "ConsoleLayoutOrganizationQuery", + "operationKind": "query", + "text": "query ConsoleLayoutOrganizationQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n name\n }\n id\n }\n}\n" + } +}; +})(); + +(node as any).hash = "3310c40eb8f1e3874139c934fb08cbb1"; + +export default node; diff --git a/apps/console/src/pages/CreateOrganizationPage.tsx b/apps/console/src/pages/CreateOrganizationPage.tsx index 1da1d8e92..fe242b65b 100644 --- a/apps/console/src/pages/CreateOrganizationPage.tsx +++ b/apps/console/src/pages/CreateOrganizationPage.tsx @@ -8,7 +8,6 @@ import { } from "react-relay"; import { Helmet } from "react-helmet-async"; import { Button } from "@/components/ui/button"; -import { useOrganization } from "@/contexts/OrganizationContext"; import { Card, CardHeader, @@ -84,7 +83,7 @@ function EditableField({ export default function CreateOrganizationPage() { const navigate = useNavigate(); - const { setCurrentOrganization } = useOrganization(); + const { toast } = useToast(); const data = useLazyLoadQuery( viewerQuery, {} @@ -93,7 +92,6 @@ export default function CreateOrganizationPage() { useMutation( createOrganizationMutation ); - const { toast } = useToast(); const [formData, setFormData] = useState({ name: "", }); @@ -122,13 +120,12 @@ export default function CreateOrganizationPage() { }, onCompleted: (response) => { const newOrg = response.createOrganization.organizationEdge.node; - setCurrentOrganization(newOrg); toast({ title: "Success", description: "Organization created successfully", variant: "default", }); - navigate("/"); + navigate(`/organizations/${newOrg.id}`); }, onError: (error) => { toast({ diff --git a/apps/console/src/pages/CreatePeoplePage.tsx b/apps/console/src/pages/CreatePeoplePage.tsx index bf2097db9..dc5cc085c 100644 --- a/apps/console/src/pages/CreatePeoplePage.tsx +++ b/apps/console/src/pages/CreatePeoplePage.tsx @@ -1,5 +1,5 @@ import { Suspense, useEffect, useState } from "react"; -import { useNavigate } from "react-router"; +import { useNavigate, useParams } from "react-router"; import { graphql, PreloadedQuery, @@ -18,7 +18,6 @@ import { useToast } from "@/hooks/use-toast"; import { HelpCircle } from "lucide-react"; import { cn } from "@/lib/utils"; import { CreatePeoplePageCreatePeopleMutation } from "./__generated__/CreatePeoplePageCreatePeopleMutation.graphql"; -import { useOrganization } from "@/contexts/OrganizationContext"; const createPeopleMutation = graphql` mutation CreatePeoplePageCreatePeopleMutation( @@ -75,7 +74,7 @@ function EditableField({ function CreatePeoplePageContent() { const navigate = useNavigate(); - const { currentOrganization } = useOrganization(); + const { organizationId } = useParams(); const [createPeople] = useMutation(createPeopleMutation); @@ -97,7 +96,7 @@ function CreatePeoplePageContent() { const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); const peopleConnectionId = ConnectionHandler.getConnectionID( - currentOrganization!.id, + organizationId!, "PeopleListPage_peoples" ); @@ -105,7 +104,7 @@ function CreatePeoplePageContent() { variables: { connections: [peopleConnectionId], input: { - organizationId: currentOrganization!.id, + organizationId: organizationId!, fullName: formData.fullName, primaryEmailAddress: formData.primaryEmailAddress, additionalEmailAddresses: formData.additionalEmailAddresses, diff --git a/apps/console/src/pages/FrameworkListPage.tsx b/apps/console/src/pages/FrameworkListPage.tsx index b631d0785..34d260351 100644 --- a/apps/console/src/pages/FrameworkListPage.tsx +++ b/apps/console/src/pages/FrameworkListPage.tsx @@ -6,10 +6,9 @@ import { useQueryLoader, } from "react-relay"; import { Card, CardContent } from "@/components/ui/card"; -import { Link } from "react-router"; +import { Link, useParams } from "react-router"; import type { FrameworkListPageQuery as FrameworkListPageQueryType } from "./__generated__/FrameworkListPageQuery.graphql"; import { Helmet } from "react-helmet-async"; -import { useOrganization } from "@/contexts/OrganizationContext"; const FrameworkListPageQuery = graphql` query FrameworkListPageQuery($organizationId: ID!) { @@ -86,6 +85,7 @@ function FrameworkListPageContent({ queryRef: PreloadedQuery; }) { const data = usePreloadedQuery(FrameworkListPageQuery, queryRef); + const { organizationId } = useParams(); const frameworks = data.organization.frameworks?.edges.map((edge) => edge?.node) ?? []; @@ -101,12 +101,15 @@ function FrameworkListPageContent({
{frameworks.map((framework) => { const validatedControls = framework.controls.edges.filter( - (edge) => edge?.node?.state === "IMPLEMENTED", + (edge) => edge?.node?.state === "IMPLEMENTED" ).length; const totalControls = framework.controls.edges.length; return ( - + ( - FrameworkListPageQuery, + FrameworkListPageQuery ); - const { currentOrganization } = useOrganization(); + const { organizationId } = useParams(); useEffect(() => { - loadQuery({ organizationId: currentOrganization!.id }); - }, [loadQuery, currentOrganization]); + loadQuery({ organizationId: organizationId! }); + }, [loadQuery, organizationId]); return ( <> diff --git a/apps/console/src/pages/FrameworkOverviewPage.tsx b/apps/console/src/pages/FrameworkOverviewPage.tsx index 996aed162..e19140b1a 100644 --- a/apps/console/src/pages/FrameworkOverviewPage.tsx +++ b/apps/console/src/pages/FrameworkOverviewPage.tsx @@ -54,19 +54,17 @@ function FrameworkOverviewPageContent({ } | null>(null); const [isTooltipHovered, setIsTooltipHovered] = useState(false); const navigate = useNavigate(); + const { organizationId } = useParams(); // Group controls by their category - const controlsByCategory = controls.reduce( - (acc, control) => { - if (!control?.category) return acc; - if (!acc[control.category]) { - acc[control.category] = []; - } - acc[control.category].push(control); - return acc; - }, - {} as Record, - ); + const controlsByCategory = controls.reduce((acc, control) => { + if (!control?.category) return acc; + if (!acc[control.category]) { + acc[control.category] = []; + } + acc[control.category].push(control); + return acc; + }, {} as Record); const controlCards = Object.entries(controlsByCategory).map( ([category, controls]) => ({ @@ -74,11 +72,11 @@ function FrameworkOverviewPageContent({ controls, completed: controls.filter((c) => c?.state === "IMPLEMENTED").length, total: controls.length, - }), + }) ); const totalImplemented = controls.filter( - (c) => c?.state === "IMPLEMENTED", + (c) => c?.state === "IMPLEMENTED" ).length; return ( @@ -190,7 +188,7 @@ function FrameworkOverviewPageContent({ onClick={() => { if (control?.id) { navigate( - `/frameworks/${framework.id}/controls/${control.id}`, + `/organizations/${organizationId}/frameworks/${framework.id}/controls/${control.id}` ); } }} @@ -274,7 +272,7 @@ function FrameworkOverviewPageContent({
, - document.body, + document.body )}
); @@ -308,7 +306,7 @@ function FrameworkOverviewPageFallback() { export default function FrameworkOverviewPage() { const { frameworkId } = useParams(); const [queryRef, loadQuery] = useQueryLoader( - FrameworkOverviewPageQuery, + FrameworkOverviewPageQuery ); useEffect(() => { diff --git a/apps/console/src/pages/HomePage.tsx b/apps/console/src/pages/HomePage.tsx index 9e0854493..d6bfecf0c 100644 --- a/apps/console/src/pages/HomePage.tsx +++ b/apps/console/src/pages/HomePage.tsx @@ -5,116 +5,112 @@ import { usePreloadedQuery, useQueryLoader, } from "react-relay"; -import { Link } from "react-router"; +import { Link, useParams } from "react-router"; import type { HomePageQuery as HomePageQueryType } from "./__generated__/HomePageQuery.graphql"; export const HomePageQuery = graphql` - query HomePageQuery { - viewer { - id - organizations { - edges { - node { - name - createdAt - updatedAt - vendors { - edges { - node { - id - name - createdAt - updatedAt - } - } + query HomePageQuery($organizationId: ID!) { + organization: node(id: $organizationId) { + ... on Organization { + id + name + createdAt + updatedAt + vendors { + edges { + node { + id + name + createdAt + updatedAt } - peoples { - edges { - node { - id - fullName - primaryEmailAddress - additionalEmailAddresses - createdAt - updatedAt - } - } + } + } + peoples { + edges { + node { + id + fullName + primaryEmailAddress + additionalEmailAddresses + createdAt + updatedAt } - frameworks { - pageInfo { - hasNextPage - hasPreviousPage - startCursor - endCursor - } - edges { - cursor - node { - id - name - description - controls { - edges { - node { - id - name - state - stateTransisions { - edges { - node { - id - toState - fromState - createdAt - updatedAt - } - } + } + } + frameworks { + pageInfo { + hasNextPage + hasPreviousPage + startCursor + endCursor + } + edges { + cursor + node { + id + name + description + controls { + edges { + node { + id + name + state + stateTransisions { + edges { + node { + id + toState + fromState + createdAt + updatedAt } - tasks { - edges { - node { - id - name - state - evidences { - edges { - node { - id - state - fileUrl - stateTransisions { - edges { - node { - id - fromState - toState - reason - createdAt - updatedAt - } - } + } + } + tasks { + edges { + node { + id + name + state + evidences { + edges { + node { + id + state + fileUrl + stateTransisions { + edges { + node { + id + fromState + toState + reason + createdAt + updatedAt } - createdAt - updatedAt } } + createdAt + updatedAt } - stateTransisions { - edges { - node { - id - toState - fromState - reason - createdAt - updatedAt - } - } - } - createdAt - updatedAt } } + stateTransisions { + edges { + node { + id + toState + fromState + reason + createdAt + updatedAt + } + } + } + createdAt + updatedAt } } } @@ -130,10 +126,15 @@ export const HomePageQuery = graphql` `; export default function HomePage() { + const { organizationId } = useParams(); const [queryRef, loadQuery] = useQueryLoader(HomePageQuery); - useEffect(() => loadQuery({}), [loadQuery]); + useEffect(() => { + if (organizationId) { + loadQuery({ organizationId }); + } + }, [organizationId, loadQuery]); if (!queryRef) { return ; @@ -155,6 +156,7 @@ function HomePageContent({ }: { queryRef: PreloadedQuery; }) { + const { organizationId } = useParams(); const data = usePreloadedQuery(HomePageQuery, queryRef); return ( @@ -166,7 +168,9 @@ function HomePageContent({
{JSON.stringify(data, null, 2)}
- Go to FooPage + + Go to Frameworks +
); diff --git a/apps/console/src/pages/LoginPage.tsx b/apps/console/src/pages/LoginPage.tsx index e23ff9fcb..323ea9965 100644 --- a/apps/console/src/pages/LoginPage.tsx +++ b/apps/console/src/pages/LoginPage.tsx @@ -22,16 +22,6 @@ export default function LoginPage() { const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); - - if (!email || !password) { - toast({ - title: "Error", - description: "Email and password are required", - variant: "destructive", - }); - return; - } - setIsLoading(true); try { @@ -40,24 +30,30 @@ export default function LoginPage() { headers: { "Content-Type": "application/json", }, - credentials: "include", body: JSON.stringify({ email, password }), + credentials: "include", }); if (!response.ok) { - const errorData = await response.json().catch(() => ({})); - throw new Error(errorData.message || "Login failed"); + const error = await response.json(); + throw new Error(error.message || "Failed to login"); } - // Check authentication status after login - await checkAuth(); - - // Redirect to the original page or home after successful login - navigate(from, { replace: true }); - } catch (error) { + const authenticated = await checkAuth(); + if (authenticated) { + toast({ + title: "Success", + description: "Logged in successfully", + variant: "default", + }); + navigate("/"); + } else { + throw new Error("Authentication failed"); + } + } catch (error: any) { toast({ title: "Error", - description: error instanceof Error ? error.message : "Login failed", + description: error.message || "Failed to login", variant: "destructive", }); } finally { @@ -66,58 +62,86 @@ export default function LoginPage() { }; return ( - <> - - Log in - Probo - - -
-
-

Log in

-

- Enter your credentials to access your account -

-
- -
-
- - setEmail(e.target.value)} - required - /> +
+
+

+ Login to your account +

+

+ Enter your email below to login to your account +

+
+
+ +
+
+ + setEmail(e.target.value)} + /> +
+
+
+ + + Forgot password? + +
+ setPassword(e.target.value)} + /> +
+
- -
- - setPassword(e.target.value)} - required - /> -
- - - -
-

- Don't have an account?{" "} - - Sign up here - -

+
+
+ +
+
+ + Or continue with + +
+
+
+ +
- +
+ Don't have an account?{" "} + + Register + +
+
); } diff --git a/apps/console/src/pages/OrganizationSelectionPage.tsx b/apps/console/src/pages/OrganizationSelectionPage.tsx new file mode 100644 index 000000000..e2702fcf6 --- /dev/null +++ b/apps/console/src/pages/OrganizationSelectionPage.tsx @@ -0,0 +1,136 @@ +import { useEffect, useState } from "react"; +import { useNavigate } from "react-router"; +import { graphql, useLazyLoadQuery } from "react-relay"; +import { Helmet } from "react-helmet-async"; +import { Button } from "@/components/ui/button"; +import { + Card, + CardHeader, + CardTitle, + CardDescription, + CardContent, + CardFooter, +} from "@/components/ui/card"; +import { useToast } from "@/hooks/use-toast"; +import { Plus } from "lucide-react"; +import { OrganizationSelectionPageQuery } from "./__generated__/OrganizationSelectionPageQuery.graphql"; + +const organizationSelectionQuery = graphql` + query OrganizationSelectionPageQuery { + viewer { + id + organizations(first: 25) { + edges { + node { + id + name + logoUrl + } + } + } + } + } +`; + +export default function OrganizationSelectionPage() { + const navigate = useNavigate(); + const { toast } = useToast(); + const data = useLazyLoadQuery( + organizationSelectionQuery, + {} + ); + + const organizations = data.viewer.organizations.edges.map( + (edge) => edge.node + ); + + useEffect(() => { + // If there's only one organization, redirect to it automatically + if (organizations.length === 1) { + navigate(`/organizations/${organizations[0].id}`); + } + }, [organizations, navigate]); + + // If no organizations, show a message to create one + if (organizations.length === 0) { + return ( +
+ + Select Organization - Probo + +
+ + + Welcome to Probo + + You don't have any organizations yet. Create your first one to + get started. + + + + + + +
+
+ ); + } + + // If multiple organizations, show a selection screen + return ( +
+ + Select Organization - Probo + +
+

Select an Organization

+
+ {organizations.map((org) => ( + + + {org.logoUrl && ( +
+ {org.name} +
+ )} +
+ {org.name} +
+
+ + + +
+ ))} + + + Create a New Organization + + Add a new organization to your account + + + + + + +
+
+
+ ); +} diff --git a/apps/console/src/pages/PeopleListPage.tsx b/apps/console/src/pages/PeopleListPage.tsx index 6881dae94..275a3d775 100644 --- a/apps/console/src/pages/PeopleListPage.tsx +++ b/apps/console/src/pages/PeopleListPage.tsx @@ -7,7 +7,7 @@ import { useMutation, usePaginationFragment, } from "react-relay"; -import { useSearchParams } from "react-router"; +import { useSearchParams, useParams } from "react-router"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Badge } from "@/components/ui/badge"; import { UserPlus, Trash2, ChevronRight } from "lucide-react"; @@ -18,7 +18,6 @@ import type { PeopleListPageQuery as PeopleListPageQueryType } from "./__generat import type { PeopleListPageDeletePeopleMutation } from "./__generated__/PeopleListPageDeletePeopleMutation.graphql"; import { PeopleListPagePaginationQuery } from "./__generated__/PeopleListPagePaginationQuery.graphql"; import { PeopleListPage_peoples$key } from "./__generated__/PeopleListPage_peoples.graphql"; -import { useOrganization } from "@/contexts/OrganizationContext"; const ITEMS_PER_PAGE = 25; @@ -141,6 +140,7 @@ function PeopleListContent({ const [isPending, startTransition] = useTransition(); const [deletePeople] = useMutation(deletePeopleMutation); + const { organizationId } = useParams(); const { data: peoplesConnection, @@ -177,7 +177,7 @@ function PeopleListContent({ style={{ borderRadius: "0.5rem" }} className="gap-2" > - + Add a people @@ -188,7 +188,7 @@ function PeopleListContent({ {peoples.map((person) => (
@@ -307,20 +307,20 @@ export default function PeopleListPage() { const [queryRef, loadQuery] = useQueryLoader(peopleListPageQuery); - const { currentOrganization } = useOrganization(); + const { organizationId } = useParams(); useEffect(() => { const after = searchParams.get("after"); const before = searchParams.get("before"); loadQuery({ - organizationId: currentOrganization!.id, + organizationId: organizationId!, first: before ? undefined : ITEMS_PER_PAGE, after: after || undefined, last: before ? ITEMS_PER_PAGE : undefined, before: before || undefined, }); - }, [loadQuery, currentOrganization]); + }, [loadQuery, organizationId, searchParams]); if (!queryRef) { return ; diff --git a/apps/console/src/pages/SettingsPage.tsx b/apps/console/src/pages/SettingsPage.tsx index 76311869f..cb64060bb 100644 --- a/apps/console/src/pages/SettingsPage.tsx +++ b/apps/console/src/pages/SettingsPage.tsx @@ -22,8 +22,8 @@ import { usePreloadedQuery, useQueryLoader, } from "react-relay"; +import { useParams } from "react-router"; import type { SettingsPageQuery as SettingsPageQueryType } from "./__generated__/SettingsPageQuery.graphql"; -import { useOrganization } from "@/contexts/OrganizationContext"; const settingsPageQuery = graphql` query SettingsPageQuery($organizationID: ID!) { @@ -217,11 +217,11 @@ export default function SettingsPage() { const [queryRef, loadQuery] = useQueryLoader(settingsPageQuery); - const { currentOrganization } = useOrganization(); + const { organizationId } = useParams(); useEffect(() => { - loadQuery({ organizationID: currentOrganization!.id }); - }, [loadQuery, currentOrganization]); + loadQuery({ organizationID: organizationId! }); + }, [loadQuery, organizationId]); if (!queryRef) { return ; diff --git a/apps/console/src/pages/VendorListPage.tsx b/apps/console/src/pages/VendorListPage.tsx index a5b97322e..b2d8e7a1d 100644 --- a/apps/console/src/pages/VendorListPage.tsx +++ b/apps/console/src/pages/VendorListPage.tsx @@ -7,7 +7,7 @@ import { useMutation, usePaginationFragment, } from "react-relay"; -import { useSearchParams } from "react-router"; +import { useSearchParams, useParams } from "react-router"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Badge } from "@/components/ui/badge"; import { Store, ChevronRight, Trash2 } from "lucide-react"; @@ -22,7 +22,6 @@ import { VendorListPageDeleteVendorMutation } from "./__generated__/VendorListPa import { VendorListPagePaginationQuery } from "./__generated__/VendorListPagePaginationQuery.graphql"; import { VendorListPage_vendors$key } from "./__generated__/VendorListPage_vendors.graphql"; import { useToast } from "@/hooks/use-toast"; -import { useOrganization } from "@/contexts/OrganizationContext"; const ITEMS_PER_PAGE = 25; @@ -199,6 +198,7 @@ function VendorListContent({ useMutation(createVendorMutation); const [deleteVendor] = useMutation(deleteVendorMutation); + const { organizationId } = useParams(); const { data: vendorsConnection, @@ -300,7 +300,7 @@ function VendorListContent({ {vendors.map((vendor) => (
@@ -425,20 +425,20 @@ export default function VendorListPage() { const [queryRef, loadQuery] = useQueryLoader(vendorListPageQuery); - const { currentOrganization } = useOrganization(); + const { organizationId } = useParams(); useEffect(() => { const after = searchParams.get("after"); const before = searchParams.get("before"); loadQuery({ - organizationId: currentOrganization!.id, + organizationId: organizationId!, first: before ? undefined : ITEMS_PER_PAGE, after: after || undefined, last: before ? ITEMS_PER_PAGE : undefined, before: before || undefined, }); - }, [loadQuery, currentOrganization]); + }, [loadQuery, organizationId, searchParams]); if (!queryRef) { return ; diff --git a/apps/console/src/pages/__generated__/HomePageQuery.graphql.ts b/apps/console/src/pages/__generated__/HomePageQuery.graphql.ts index 059ee67ae..fe22bf786 100644 --- a/apps/console/src/pages/__generated__/HomePageQuery.graphql.ts +++ b/apps/console/src/pages/__generated__/HomePageQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<<72fcf5e9542bdba3b547fa523e55378d>> * @lightSyntaxTransform * @nogrep */ @@ -12,73 +12,52 @@ import { ConcreteRequest } from 'relay-runtime'; export type ControlState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED"; export type EvidenceState = "EXPIRED" | "INVALID" | "VALID"; export type TaskState = "DONE" | "TODO"; -export type HomePageQuery$variables = Record; +export type HomePageQuery$variables = { + organizationId: string; +}; export type HomePageQuery$data = { - readonly viewer: { - readonly id: string; - readonly organizations: { + readonly organization: { + readonly createdAt?: any; + readonly frameworks?: { readonly edges: ReadonlyArray<{ + readonly cursor: any; readonly node: { - readonly createdAt: any; - readonly frameworks: { + readonly controls: { readonly edges: ReadonlyArray<{ - readonly cursor: any; readonly node: { - readonly controls: { + readonly id: string; + readonly name: string; + readonly state: ControlState; + readonly stateTransisions: { readonly edges: ReadonlyArray<{ readonly node: { + readonly createdAt: any; + readonly fromState: ControlState | null | undefined; readonly id: string; - readonly name: string; - readonly state: ControlState; - readonly stateTransisions: { + readonly toState: ControlState; + readonly updatedAt: any; + }; + }>; + }; + readonly tasks: { + readonly edges: ReadonlyArray<{ + readonly node: { + readonly createdAt: any; + readonly evidences: { readonly edges: ReadonlyArray<{ readonly node: { readonly createdAt: any; - readonly fromState: ControlState | null | undefined; + readonly fileUrl: string; readonly id: string; - readonly toState: ControlState; - readonly updatedAt: any; - }; - }>; - }; - readonly tasks: { - readonly edges: ReadonlyArray<{ - readonly node: { - readonly createdAt: any; - readonly evidences: { - readonly edges: ReadonlyArray<{ - readonly node: { - readonly createdAt: any; - readonly fileUrl: string; - readonly id: string; - readonly state: EvidenceState; - readonly stateTransisions: { - readonly edges: ReadonlyArray<{ - readonly node: { - readonly createdAt: any; - readonly fromState: EvidenceState | null | undefined; - readonly id: string; - readonly reason: string | null | undefined; - readonly toState: EvidenceState; - readonly updatedAt: any; - }; - }>; - }; - readonly updatedAt: any; - }; - }>; - }; - readonly id: string; - readonly name: string; - readonly state: TaskState; + readonly state: EvidenceState; readonly stateTransisions: { readonly edges: ReadonlyArray<{ readonly node: { readonly createdAt: any; - readonly fromState: TaskState | null | undefined; + readonly fromState: EvidenceState | null | undefined; readonly id: string; readonly reason: string | null | undefined; - readonly toState: TaskState; + readonly toState: EvidenceState; readonly updatedAt: any; }; }>; @@ -87,45 +66,62 @@ export type HomePageQuery$data = { }; }>; }; + readonly id: string; + readonly name: string; + readonly state: TaskState; + readonly stateTransisions: { + readonly edges: ReadonlyArray<{ + readonly node: { + readonly createdAt: any; + readonly fromState: TaskState | null | undefined; + readonly id: string; + readonly reason: string | null | undefined; + readonly toState: TaskState; + readonly updatedAt: any; + }; + }>; + }; + readonly updatedAt: any; }; }>; }; - readonly description: string; - readonly id: string; - readonly name: string; }; }>; - readonly pageInfo: { - readonly endCursor: any | null | undefined; - readonly hasNextPage: boolean; - readonly hasPreviousPage: boolean; - readonly startCursor: any | null | undefined; - }; }; + readonly description: string; + readonly id: string; + readonly name: string; + }; + }>; + readonly pageInfo: { + readonly endCursor: any | null | undefined; + readonly hasNextPage: boolean; + readonly hasPreviousPage: boolean; + readonly startCursor: any | null | undefined; + }; + }; + readonly id?: string; + readonly name?: string; + readonly peoples?: { + readonly edges: ReadonlyArray<{ + readonly node: { + readonly additionalEmailAddresses: ReadonlyArray; + readonly createdAt: any; + readonly fullName: string; + readonly id: string; + readonly primaryEmailAddress: string; + readonly updatedAt: any; + }; + }>; + }; + readonly updatedAt?: any; + readonly vendors?: { + readonly edges: ReadonlyArray<{ + readonly node: { + readonly createdAt: any; + readonly id: string; readonly name: string; - readonly peoples: { - readonly edges: ReadonlyArray<{ - readonly node: { - readonly additionalEmailAddresses: ReadonlyArray; - readonly createdAt: any; - readonly fullName: string; - readonly id: string; - readonly primaryEmailAddress: string; - readonly updatedAt: any; - }; - }>; - }; readonly updatedAt: any; - readonly vendors: { - readonly edges: ReadonlyArray<{ - readonly node: { - readonly createdAt: any; - readonly id: string; - readonly name: string; - readonly updatedAt: any; - }; - }>; - }; }; }>; }; @@ -137,35 +133,49 @@ export type HomePageQuery = { }; const node: ConcreteRequest = (function(){ -var v0 = { +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "organizationId" + } +], +v1 = [ + { + "kind": "Variable", + "name": "id", + "variableName": "organizationId" + } +], +v2 = { "alias": null, "args": null, "kind": "ScalarField", "name": "id", "storageKey": null }, -v1 = { +v3 = { "alias": null, "args": null, "kind": "ScalarField", "name": "name", "storageKey": null }, -v2 = { +v4 = { "alias": null, "args": null, "kind": "ScalarField", "name": "createdAt", "storageKey": null }, -v3 = { +v5 = { "alias": null, "args": null, "kind": "ScalarField", "name": "updatedAt", "storageKey": null }, -v4 = { +v6 = { "alias": null, "args": null, "concreteType": "VendorConnection", @@ -189,10 +199,10 @@ v4 = { "name": "node", "plural": false, "selections": [ - (v0/*: any*/), - (v1/*: any*/), (v2/*: any*/), - (v3/*: any*/) + (v3/*: any*/), + (v4/*: any*/), + (v5/*: any*/) ], "storageKey": null } @@ -202,7 +212,7 @@ v4 = { ], "storageKey": null }, -v5 = { +v7 = { "alias": null, "args": null, "concreteType": "PeopleConnection", @@ -226,7 +236,7 @@ v5 = { "name": "node", "plural": false, "selections": [ - (v0/*: any*/), + (v2/*: any*/), { "alias": null, "args": null, @@ -248,8 +258,8 @@ v5 = { "name": "additionalEmailAddresses", "storageKey": null }, - (v2/*: any*/), - (v3/*: any*/) + (v4/*: any*/), + (v5/*: any*/) ], "storageKey": null } @@ -259,35 +269,35 @@ v5 = { ], "storageKey": null }, -v6 = { +v8 = { "alias": null, "args": null, "kind": "ScalarField", "name": "state", "storageKey": null }, -v7 = { +v9 = { "alias": null, "args": null, "kind": "ScalarField", "name": "toState", "storageKey": null }, -v8 = { +v10 = { "alias": null, "args": null, "kind": "ScalarField", "name": "fromState", "storageKey": null }, -v9 = { +v11 = { "alias": null, "args": null, "kind": "ScalarField", "name": "reason", "storageKey": null }, -v10 = { +v12 = { "alias": null, "args": null, "concreteType": "FrameworkConnection", @@ -357,8 +367,8 @@ v10 = { "name": "node", "plural": false, "selections": [ - (v0/*: any*/), - (v1/*: any*/), + (v2/*: any*/), + (v3/*: any*/), { "alias": null, "args": null, @@ -390,9 +400,9 @@ v10 = { "name": "node", "plural": false, "selections": [ - (v0/*: any*/), - (v1/*: any*/), - (v6/*: any*/), + (v2/*: any*/), + (v3/*: any*/), + (v8/*: any*/), { "alias": null, "args": null, @@ -417,11 +427,11 @@ v10 = { "name": "node", "plural": false, "selections": [ - (v0/*: any*/), - (v7/*: any*/), - (v8/*: any*/), (v2/*: any*/), - (v3/*: any*/) + (v9/*: any*/), + (v10/*: any*/), + (v4/*: any*/), + (v5/*: any*/) ], "storageKey": null } @@ -455,9 +465,9 @@ v10 = { "name": "node", "plural": false, "selections": [ - (v0/*: any*/), - (v1/*: any*/), - (v6/*: any*/), + (v2/*: any*/), + (v3/*: any*/), + (v8/*: any*/), { "alias": null, "args": null, @@ -482,8 +492,8 @@ v10 = { "name": "node", "plural": false, "selections": [ - (v0/*: any*/), - (v6/*: any*/), + (v2/*: any*/), + (v8/*: any*/), { "alias": null, "args": null, @@ -515,12 +525,12 @@ v10 = { "name": "node", "plural": false, "selections": [ - (v0/*: any*/), - (v8/*: any*/), - (v7/*: any*/), - (v9/*: any*/), (v2/*: any*/), - (v3/*: any*/) + (v10/*: any*/), + (v9/*: any*/), + (v11/*: any*/), + (v4/*: any*/), + (v5/*: any*/) ], "storageKey": null } @@ -530,8 +540,8 @@ v10 = { ], "storageKey": null }, - (v2/*: any*/), - (v3/*: any*/) + (v4/*: any*/), + (v5/*: any*/) ], "storageKey": null } @@ -565,12 +575,12 @@ v10 = { "name": "node", "plural": false, "selections": [ - (v0/*: any*/), - (v7/*: any*/), - (v8/*: any*/), - (v9/*: any*/), (v2/*: any*/), - (v3/*: any*/) + (v9/*: any*/), + (v10/*: any*/), + (v11/*: any*/), + (v4/*: any*/), + (v5/*: any*/) ], "storageKey": null } @@ -580,8 +590,8 @@ v10 = { ], "storageKey": null }, - (v2/*: any*/), - (v3/*: any*/) + (v4/*: any*/), + (v5/*: any*/) ], "storageKey": null } @@ -611,58 +621,32 @@ v10 = { }; return { "fragment": { - "argumentDefinitions": [], + "argumentDefinitions": (v0/*: any*/), "kind": "Fragment", "metadata": null, "name": "HomePageQuery", "selections": [ { - "alias": null, - "args": null, - "concreteType": "User", + "alias": "organization", + "args": (v1/*: any*/), + "concreteType": null, "kind": "LinkedField", - "name": "viewer", + "name": "node", "plural": false, "selections": [ - (v0/*: any*/), { - "alias": null, - "args": null, - "concreteType": "OrganizationConnection", - "kind": "LinkedField", - "name": "organizations", - "plural": false, + "kind": "InlineFragment", "selections": [ - { - "alias": null, - "args": null, - "concreteType": "OrganizationEdge", - "kind": "LinkedField", - "name": "edges", - "plural": true, - "selections": [ - { - "alias": null, - "args": null, - "concreteType": "Organization", - "kind": "LinkedField", - "name": "node", - "plural": false, - "selections": [ - (v1/*: any*/), - (v2/*: any*/), - (v3/*: any*/), - (v4/*: any*/), - (v5/*: any*/), - (v10/*: any*/) - ], - "storageKey": null - } - ], - "storageKey": null - } + (v2/*: any*/), + (v3/*: any*/), + (v4/*: any*/), + (v5/*: any*/), + (v6/*: any*/), + (v7/*: any*/), + (v12/*: any*/) ], - "storageKey": null + "type": "Organization", + "abstractKey": null } ], "storageKey": null @@ -673,58 +657,38 @@ return { }, "kind": "Request", "operation": { - "argumentDefinitions": [], + "argumentDefinitions": (v0/*: any*/), "kind": "Operation", "name": "HomePageQuery", "selections": [ { - "alias": null, - "args": null, - "concreteType": "User", + "alias": "organization", + "args": (v1/*: any*/), + "concreteType": null, "kind": "LinkedField", - "name": "viewer", + "name": "node", "plural": false, "selections": [ - (v0/*: any*/), { "alias": null, "args": null, - "concreteType": "OrganizationConnection", - "kind": "LinkedField", - "name": "organizations", - "plural": false, - "selections": [ - { - "alias": null, - "args": null, - "concreteType": "OrganizationEdge", - "kind": "LinkedField", - "name": "edges", - "plural": true, - "selections": [ - { - "alias": null, - "args": null, - "concreteType": "Organization", - "kind": "LinkedField", - "name": "node", - "plural": false, - "selections": [ - (v1/*: any*/), - (v2/*: any*/), - (v3/*: any*/), - (v4/*: any*/), - (v5/*: any*/), - (v10/*: any*/), - (v0/*: any*/) - ], - "storageKey": null - } - ], - "storageKey": null - } - ], + "kind": "ScalarField", + "name": "__typename", "storageKey": null + }, + (v2/*: any*/), + { + "kind": "InlineFragment", + "selections": [ + (v3/*: any*/), + (v4/*: any*/), + (v5/*: any*/), + (v6/*: any*/), + (v7/*: any*/), + (v12/*: any*/) + ], + "type": "Organization", + "abstractKey": null } ], "storageKey": null @@ -732,16 +696,16 @@ return { ] }, "params": { - "cacheID": "5a56fefd066703ca0ebac1ef3e9a7e1f", + "cacheID": "29440183dcc30ec5e0bcce9c1910b92f", "id": null, "metadata": {}, "name": "HomePageQuery", "operationKind": "query", - "text": "query HomePageQuery {\n viewer {\n id\n organizations {\n edges {\n node {\n name\n createdAt\n updatedAt\n vendors {\n edges {\n node {\n id\n name\n createdAt\n updatedAt\n }\n }\n }\n peoples {\n edges {\n node {\n id\n fullName\n primaryEmailAddress\n additionalEmailAddresses\n createdAt\n updatedAt\n }\n }\n }\n frameworks {\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n edges {\n cursor\n node {\n id\n name\n description\n controls {\n edges {\n node {\n id\n name\n state\n stateTransisions {\n edges {\n node {\n id\n toState\n fromState\n createdAt\n updatedAt\n }\n }\n }\n tasks {\n edges {\n node {\n id\n name\n state\n evidences {\n edges {\n node {\n id\n state\n fileUrl\n stateTransisions {\n edges {\n node {\n id\n fromState\n toState\n reason\n createdAt\n updatedAt\n }\n }\n }\n createdAt\n updatedAt\n }\n }\n }\n stateTransisions {\n edges {\n node {\n id\n toState\n fromState\n reason\n createdAt\n updatedAt\n }\n }\n }\n createdAt\n updatedAt\n }\n }\n }\n }\n }\n }\n }\n }\n }\n id\n }\n }\n }\n }\n}\n" + "text": "query HomePageQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n id\n name\n createdAt\n updatedAt\n vendors {\n edges {\n node {\n id\n name\n createdAt\n updatedAt\n }\n }\n }\n peoples {\n edges {\n node {\n id\n fullName\n primaryEmailAddress\n additionalEmailAddresses\n createdAt\n updatedAt\n }\n }\n }\n frameworks {\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n edges {\n cursor\n node {\n id\n name\n description\n controls {\n edges {\n node {\n id\n name\n state\n stateTransisions {\n edges {\n node {\n id\n toState\n fromState\n createdAt\n updatedAt\n }\n }\n }\n tasks {\n edges {\n node {\n id\n name\n state\n evidences {\n edges {\n node {\n id\n state\n fileUrl\n stateTransisions {\n edges {\n node {\n id\n fromState\n toState\n reason\n createdAt\n updatedAt\n }\n }\n }\n createdAt\n updatedAt\n }\n }\n }\n stateTransisions {\n edges {\n node {\n id\n toState\n fromState\n reason\n createdAt\n updatedAt\n }\n }\n }\n createdAt\n updatedAt\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n id\n }\n}\n" } }; })(); -(node as any).hash = "7a1699535af738f939d954a88c6daa9e"; +(node as any).hash = "d4f516b436d096fe9c91ce532a75b022"; export default node; diff --git a/apps/console/src/pages/__generated__/OrganizationSelectionPageQuery.graphql.ts b/apps/console/src/pages/__generated__/OrganizationSelectionPageQuery.graphql.ts new file mode 100644 index 000000000..0ac0afdab --- /dev/null +++ b/apps/console/src/pages/__generated__/OrganizationSelectionPageQuery.graphql.ts @@ -0,0 +1,138 @@ +/** + * @generated SignedSource<<59c4e8be77fdb5ebcc76c2a611f38052>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +export type OrganizationSelectionPageQuery$variables = Record; +export type OrganizationSelectionPageQuery$data = { + readonly viewer: { + readonly id: string; + readonly organizations: { + readonly edges: ReadonlyArray<{ + readonly node: { + readonly id: string; + readonly logoUrl: string; + readonly name: string; + }; + }>; + }; + }; +}; +export type OrganizationSelectionPageQuery = { + response: OrganizationSelectionPageQuery$data; + variables: OrganizationSelectionPageQuery$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}, +v1 = [ + { + "alias": null, + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "viewer", + "plural": false, + "selections": [ + (v0/*: any*/), + { + "alias": null, + "args": [ + { + "kind": "Literal", + "name": "first", + "value": 25 + } + ], + "concreteType": "OrganizationConnection", + "kind": "LinkedField", + "name": "organizations", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "OrganizationEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Organization", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v0/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "logoUrl", + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": "organizations(first:25)" + } + ], + "storageKey": null + } +]; +return { + "fragment": { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": null, + "name": "OrganizationSelectionPageQuery", + "selections": (v1/*: any*/), + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [], + "kind": "Operation", + "name": "OrganizationSelectionPageQuery", + "selections": (v1/*: any*/) + }, + "params": { + "cacheID": "634e8f413a8b1f2685cfc1f4fd3c13cc", + "id": null, + "metadata": {}, + "name": "OrganizationSelectionPageQuery", + "operationKind": "query", + "text": "query OrganizationSelectionPageQuery {\n viewer {\n id\n organizations(first: 25) {\n edges {\n node {\n id\n name\n logoUrl\n }\n }\n }\n }\n}\n" + } +}; +})(); + +(node as any).hash = "786037ac4c8d61f3b7cf6b4536aadbbb"; + +export default node; diff --git a/package-lock.json b/package-lock.json index a37900670..f5e4a7b21 100644 --- a/package-lock.json +++ b/package-lock.json @@ -60,6 +60,7 @@ "autoprefixer": "^10.4.20", "babel-plugin-relay": "^18.2.0", "esbuild": "^0.25.0", + "eslint": "^9.21.0", "relay-compiler": "^18.2.0", "tailwindcss": "^3.4.17", "typescript": "^5.7.3" @@ -2101,6 +2102,242 @@ "node": ">=18" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", + "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/core": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", + "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz", + "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/eslintrc/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@eslint/js": { + "version": "9.21.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.21.0.tgz", + "integrity": "sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz", + "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.12.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@floating-ui/core": { "version": "1.6.9", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz", @@ -2139,6 +2376,72 @@ "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==", "license": "MIT" }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", + "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -3218,6 +3521,20 @@ "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", "license": "MIT" }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { "version": "22.13.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.0.tgz", @@ -3281,6 +3598,46 @@ "dev": true, "license": "MIT" }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/ansi-regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", @@ -3673,6 +4030,39 @@ ], "license": "CC-BY-4.0" }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -3757,6 +4147,13 @@ "node": ">= 6" } }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -3888,6 +4285,13 @@ } } }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, "node_modules/detect-node-es": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", @@ -3986,6 +4390,151 @@ "node": ">=6" } }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.21.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.21.0.tgz", + "integrity": "sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.2", + "@eslint/core": "^0.12.0", + "@eslint/eslintrc": "^3.3.0", + "@eslint/js": "9.21.0", + "@eslint/plugin-kit": "^0.2.7", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -4000,6 +4549,42 @@ "node": ">=4" } }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -4010,6 +4595,13 @@ "node": ">=0.10.0" } }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-glob": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", @@ -4038,6 +4630,20 @@ "node": ">= 6" } }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, "node_modules/fastq": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz", @@ -4074,6 +4680,19 @@ "integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==", "license": "MIT" }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -4086,6 +4705,44 @@ "node": ">=8" } }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, "node_modules/foreground-child": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", @@ -4242,6 +4899,16 @@ "node": ">= 10.x" } }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -4254,6 +4921,16 @@ "node": ">= 0.4" } }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/import-fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", @@ -4268,6 +4945,16 @@ "node": ">=4" } }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -4414,6 +5101,13 @@ "node": ">=6" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, "node_modules/json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -4428,6 +5122,20 @@ "dev": true, "license": "MIT" }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -4454,6 +5162,30 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/lilconfig": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", @@ -4472,6 +5204,22 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "license": "MIT" }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -4479,6 +5227,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -4599,6 +5354,13 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -4669,6 +5431,56 @@ "node": ">= 6" } }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -4712,6 +5524,16 @@ "node": ">=4" } }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -4972,6 +5794,16 @@ "url": "https://opencollective.com/preact" } }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", @@ -4981,6 +5813,16 @@ "asap": "~2.0.3" } }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -5539,6 +6381,19 @@ "node": ">=8" } }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/sucrase": { "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", @@ -5561,6 +6416,19 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -5705,6 +6573,19 @@ "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==", "license": "ISC" }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/typescript": { "version": "5.7.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", @@ -5837,6 +6718,16 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/use-callback-ref": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", @@ -5923,6 +6814,16 @@ "node": ">= 8" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", @@ -6031,6 +6932,19 @@ "node": ">= 6" } }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "packages/tsconfig": { "name": "@probo/tsconfig", "version": "0.0.1",