From 5edd4f4f14f1c4e07d31afd7fd25f46e4f999417 Mon Sep 17 00:00:00 2001 From: SevicheCC <91365763+Sevichecc@users.noreply.github.com> Date: Wed, 7 Jun 2023 16:02:47 +0800 Subject: [PATCH] refactor: generator token from outside --- app/page.tsx | 3 - components/FormContainer.tsx | 17 +-- components/InputForm.tsx | 35 +++--- components/ResultTable.tsx | 59 ---------- components/TokenTable.tsx | 9 -- components/tables/CopyableRow.tsx | 23 ++++ components/tables/ResultTable.tsx | 80 ++++++++++++++ components/ui/alert.tsx | 59 ++++++++++ hooks/useAuth.ts | 92 ---------------- hooks/useCreateApp.ts | 6 +- lib/scopes.ts | 87 +++++++++++++++ lib/types.ts | 2 +- lib/utils.ts | 100 +++-------------- package.json | 1 + pnpm-lock.yaml | 174 +++++++++++++++++++++++------- 15 files changed, 435 insertions(+), 312 deletions(-) delete mode 100644 components/ResultTable.tsx delete mode 100644 components/TokenTable.tsx create mode 100644 components/tables/CopyableRow.tsx create mode 100644 components/tables/ResultTable.tsx create mode 100644 components/ui/alert.tsx delete mode 100644 hooks/useAuth.ts create mode 100644 lib/scopes.ts diff --git a/app/page.tsx b/app/page.tsx index dbf843d..b61ee47 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -24,9 +24,6 @@ export default function Home() { - {/* -

Card Footer

-
*/} diff --git a/components/FormContainer.tsx b/components/FormContainer.tsx index 3b33c55..465f8a1 100644 --- a/components/FormContainer.tsx +++ b/components/FormContainer.tsx @@ -1,26 +1,27 @@ "use client"; -import { useEffect, useState } from "react"; +import { useState } from "react"; import InputForm from "@/components/InputForm"; -import ResultTable from "@/components/ResultTable"; -import TokenTable from "@/components/TokenTable"; +import ResultTable from "@/components/tables/ResultTable"; import useCreateApp from "@/hooks/useCreateApp"; -import useAuth from "@/hooks/useAuth"; + import { FormSchema } from "@/components/InputForm"; export type AppInfo = Pick; + const FormContainer = () => { - const { appEntry, createApp } = useCreateApp(); + const { credentials, createApp } = useCreateApp() + const [appInfo, setAppInfo] = useState({ instanceUrl: "", scopes: [""], }); - const { token, getAccessToken } = useAuth(appInfo); return ( <> - {appEntry && } - {/* */} + {credentials && ( + + )} ); }; diff --git a/components/InputForm.tsx b/components/InputForm.tsx index 1a1da7b..58fb861 100644 --- a/components/InputForm.tsx +++ b/components/InputForm.tsx @@ -16,13 +16,12 @@ import { } from "@/components/ui/form"; import ScopeSection from "@/components/scopes/ScopeSection"; -import { scopesInfo } from "@/lib/utils"; -import { Dispatch, SetStateAction } from "react"; -import { AppEntry } from "@/lib/types"; +import { scopesInfo } from "@/lib/scopes"; +import { Dispatch, SetStateAction } from "react"; import { AppInfo } from "./FormContainer"; const formSchema = z.object({ - instanceUrl: z.string().trim(), + instanceUrl: z.string().url().trim(), clientName: z.string().trim(), redirectUris: z.string().trim(), scopes: z.string().array().nonempty().optional(), @@ -31,8 +30,8 @@ const formSchema = z.object({ export type FormSchema = z.infer; interface InputFormProps { - createApp: ({ }: FormSchema) => Promise - setAppInfo: Dispatch> + createApp: ({}: FormSchema) => Promise; + setAppInfo: Dispatch>; } const InputForm: React.FC = ({ createApp, setAppInfo }) => { @@ -41,28 +40,30 @@ const InputForm: React.FC = ({ createApp, setAppInfo }) => { defaultValues: { instanceUrl: "https://", clientName: "", - redirectUris: "", + redirectUris: "urn:ietf:wg:oauth:2.0:oob", scopes: ["read"], }, }); const onSubmit = async (values: FormSchema) => { - setAppInfo(values) - await createApp(values) - } + setAppInfo(values); + await createApp(values); + }; return (
( - Instance + + Instance* + @@ -75,7 +76,9 @@ const InputForm: React.FC = ({ createApp, setAppInfo }) => { name="clientName" render={({ field }) => ( - Application name + + Application name* + @@ -101,7 +104,9 @@ const InputForm: React.FC = ({ createApp, setAppInfo }) => { name="redirectUris" render={({ field }) => ( - Redirect URI + + Redirect URI* + @@ -110,7 +115,7 @@ const InputForm: React.FC = ({ createApp, setAppInfo }) => { urn:ietf:wg:oauth:2.0:oob {" "} - for local tests + for local tests or for getting access token diff --git a/components/ResultTable.tsx b/components/ResultTable.tsx deleted file mode 100644 index 4c69804..0000000 --- a/components/ResultTable.tsx +++ /dev/null @@ -1,59 +0,0 @@ -"use client"; - -import { - Table, - TableBody, - TableCaption, - TableCell, - TableHead, - TableHeader, - TableRow, -} from "@/components/ui/table"; -import { AppEntry } from "@/lib/types"; -import { CopyButton } from "@/components/ui/copybutton"; -import { Button } from "@/components/ui/button"; - -interface ResultTableProps { - appEntry: AppEntry; - getAccessToken: (appEntry: AppEntry) => Promise; -} - -const renderTableRow = (label: string, value: string | undefined) => ( - - {label} - - {value} - {value && } - - -); - -const ResultTable: React.FC = ({ - appEntry, - getAccessToken, -}) => { - return ( - <> - - - - Type - Value - - - - {renderTableRow("ID", appEntry?.id)} - {renderTableRow("Name", appEntry?.name)} - {renderTableRow("Website", appEntry?.website || "")} - {renderTableRow("Redirect URI", appEntry?.redirect_uri)} - {renderTableRow("Client ID", appEntry?.client_id)} - {renderTableRow("Client Secret", appEntry?.client_secret)} - {renderTableRow("Vapid Key", appEntry?.vapid_key)} - -
- - - ); -}; - -export default ResultTable; diff --git a/components/TokenTable.tsx b/components/TokenTable.tsx deleted file mode 100644 index cf08c16..0000000 --- a/components/TokenTable.tsx +++ /dev/null @@ -1,9 +0,0 @@ -'use client' - -const TokenTable = () => { - - return ( -
5
- ); -}; -export default TokenTable; diff --git a/components/tables/CopyableRow.tsx b/components/tables/CopyableRow.tsx new file mode 100644 index 0000000..56fe26c --- /dev/null +++ b/components/tables/CopyableRow.tsx @@ -0,0 +1,23 @@ +"use client"; + +import { TableCell, TableRow } from "@/components/ui/table"; +import { CopyButton } from "@/components/ui/copybutton"; + +interface CopyableRowProps { + label: string; + value: string | null; +} + +const CopyableRow: React.FC = ({ label, value }) => { + return ( + + {label} + + {value} + {value && } + + + ); +}; + +export default CopyableRow; diff --git a/components/tables/ResultTable.tsx b/components/tables/ResultTable.tsx new file mode 100644 index 0000000..9450e2a --- /dev/null +++ b/components/tables/ResultTable.tsx @@ -0,0 +1,80 @@ +"use client"; + +import { + Table, + TableBody, + TableCaption, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; +import { Credentials } from "@/lib/types"; +import { CopyButton } from "@/components/ui/copybutton"; +import { Button } from "@/components/ui/button"; +import { ExternalLink } from "lucide-react"; +import { getAuth } from "@/lib/utils"; +import { AppInfo } from "../FormContainer"; + +interface ResultTableProps { + credentials: Credentials; + appInfo: AppInfo; +} + +const renderTableRow = (label: string, value: string | undefined) => ( + + {label} + + {value} + {value && } + + +); + +const ResultTable: React.FC = ({ credentials, appInfo }) => { + const { instanceUrl, scopes } = appInfo; + const { + id, + name, + website, + redirect_uri, + client_id, + client_secret, + vapid_key, + } = credentials; + + return ( +
+ + + + Type + Value + + + {credentials && ( + + {renderTableRow("ID", id)} + {renderTableRow("Name", name)} + {renderTableRow("Website", website || "")} + {renderTableRow("Redirect URI", redirect_uri)} + {renderTableRow("Client ID", client_id)} + {renderTableRow("Client Secret", client_secret)} + {renderTableRow("Vapid Key", vapid_key)} + + )} +
+ {redirect_uri === "urn:ietf:wg:oauth:2.0:oob" && ( + + )} +
+ ); +}; + +export default ResultTable; diff --git a/components/ui/alert.tsx b/components/ui/alert.tsx new file mode 100644 index 0000000..9ddbc46 --- /dev/null +++ b/components/ui/alert.tsx @@ -0,0 +1,59 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const alertVariants = cva( + "relative w-full rounded-lg border p-4 [&>svg]:absolute [&>svg]:text-foreground [&>svg]:left-4 [&>svg]:top-4 [&>svg+div]:translate-y-[-3px] [&:has(svg)]:pl-11", + { + variants: { + variant: { + default: "bg-background text-foreground", + destructive: + "text-destructive border-destructive/50 dark:border-destructive [&>svg]:text-destructive text-destructive", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +const Alert = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes & VariantProps +>(({ className, variant, ...props }, ref) => ( +
+)) +Alert.displayName = "Alert" + +const AlertTitle = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +AlertTitle.displayName = "AlertTitle" + +const AlertDescription = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +AlertDescription.displayName = "AlertDescription" + +export { Alert, AlertTitle, AlertDescription } diff --git a/hooks/useAuth.ts b/hooks/useAuth.ts deleted file mode 100644 index fe9a7f7..0000000 --- a/hooks/useAuth.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { useCallback, useState, useMemo } from "react"; -import { AppEntry, MError } from "@/lib/types"; -import { FormSchema } from "@/components/InputForm"; -import { AppInfo } from "@/components/FormContainer"; - -const useAuth = (appInfo: AppInfo) => { - const { instanceUrl, scopes} = appInfo - const [token, setToken] = useState(""); - - const getCode = useCallback( - (client_id: string, redirect_uri: string) => { - const code = new URLSearchParams(window.location.search).get("code"); - - if (!code) { - const params = { - response_type: "code", - client_id, - redirect_uri, - }; - - if (scopes) { - const scope = 1 - } - - const queryString = new URLSearchParams(params).toString(); - window.location.href = `${instanceUrl}/oauth/authorize?${queryString}`; - } else { - return code; - } - }, - [instanceUrl, scopes] - ); - - const getAuth = useCallback( - async ( - code: string, - client_id: string, - redirect_uri: string, - client_secret: string - ) => { - const body = new URLSearchParams({ - grant_type: "authorization_code", - client_id, - client_secret, - redirect_uri, - code, - }); - - try { - const response = await fetch(`${instanceUrl}/oauth/token`, { - method: "POST", - headers: { - "Content-Type": "application/x-www-form-urlencoded", - }, - body: body.toString(), - }); - - const result = await response.json(); - if (!response.ok) throw new Error((result as MError).error); - - return result.access_token; - } catch (error) { - console.error(error); - } - }, - [instanceUrl] - ); - - const getAccessToken = useCallback( - async (appEntry: AppEntry) => { - const { client_id, redirect_uri, client_secret } = appEntry; - const code = getCode(client_id, redirect_uri); - if (code) { - const accessToken = await getAuth( - code, - client_id, - redirect_uri, - client_secret - ); - setToken(accessToken); - } - }, - [getCode, getAuth] - ); - - return { - token, - getAccessToken, - }; -}; - -export default useAuth; diff --git a/hooks/useCreateApp.ts b/hooks/useCreateApp.ts index 64654d8..203ea39 100644 --- a/hooks/useCreateApp.ts +++ b/hooks/useCreateApp.ts @@ -3,7 +3,7 @@ import { useCallback, useState } from "react"; import { AppEntry, MError } from "@/lib/types"; const useCreateApp = () => { - const [appEntry, setAppEntry] = useState(); + const [credentials, setCredentials] = useState(); const createApp = useCallback( async ({ @@ -32,7 +32,7 @@ const useCreateApp = () => { if (!request.ok || request.status === 424) { throw new Error((await request.json()).error); } - setAppEntry(await request.json()); + setCredentials(await request.json()); } catch (error) { throw new Error((error as MError).error); } @@ -40,7 +40,7 @@ const useCreateApp = () => { ); return { - appEntry, + credentials, createApp, }; }; diff --git a/lib/scopes.ts b/lib/scopes.ts new file mode 100644 index 0000000..d71ea79 --- /dev/null +++ b/lib/scopes.ts @@ -0,0 +1,87 @@ +import { ScopeInfo } from "./types"; + +export const READ_SCOPES = [ + "read:accounts", + "read:blocks", + "read:bookmarks", + "read:favourites", + "read:filters", + "read:follows", + "read:lists", + "read:mutes", + "read:notifications", + "read:search", + "read:statuses", +]; + +export const WRITE_SCOPES = [ + "write:account", + "write:blocks", + "write:bookmarks", + "write:favourites", + "write:filters", + "write:lists", + "write:mutes", + "write:notifications", + "write:statuses", + "write:conversations", + "write:media", + "write:reports", +]; + +export const ADMIN_READ_SCOPES = [ + "admin:read:account", + "admin:read:reports", + "admin:read:domain_allows", + "admin:read:domain_blocks", + "admin:read:ip_blocks", + "admin:read:email_domain_blocks", + "admin:read:canonical_email_blocks", +]; + +export const ADMIN_WRITE_SCOPES = [ + "admin:write:account", + "admin:write:reports", + "admin:write:domain_allows", + "admin:write:domain_blocks", + "admin:write:ip_blocks", + "admin:write:email_domain_blocks", + "admin:write:canonical_email_blocks", +]; + +export const scopesInfo: ScopeInfo[] = [ + { + method: "read", + label: "Read", + scopes: READ_SCOPES, + description: "read account's data", + }, + { + method: "write", + label: "Write", + scopes: WRITE_SCOPES, + description: "modify account's data", + }, + { + method: "admin", + label: "Admin", + scopes: [ADMIN_READ_SCOPES, ADMIN_WRITE_SCOPES], + description: "read all data on the server", + }, + { + method: "follow", + label: "Follow", + description: "modify account relationships,deprecated in 3.5.0 and newer.", + }, + { + method: "push", + label: "Push", + description: "receive push notifications", + }, + + { + method: "crypto", + label: "Crypto", + description: "use end-to-end encryption", + }, +]; diff --git a/lib/types.ts b/lib/types.ts index 8812dbd..13e73d6 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -14,7 +14,7 @@ export interface ScopeInfo { description: string; } -export interface AppEntry { +export interface Credentials { id: string; name: string; website: string | null; diff --git a/lib/utils.ts b/lib/utils.ts index cb8928c..0a0b941 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -1,93 +1,25 @@ import { clsx, type ClassValue } from "clsx"; import { twMerge } from "tailwind-merge"; -import { ScopeInfo } from "./types"; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } -export const READ_SCOPES = [ - "read:accounts", - "read:blocks", - "read:bookmarks", - "read:favourites", - "read:filters", - "read:follows", - "read:lists", - "read:mutes", - "read:notifications", - "read:search", - "read:statuses", -]; +export const getAuth = ( + instanceUrl: string, + client_id: string, + scopes: any, +) => { + const params: any = { + response_type: "code", + client_id, + redirect_uri: "urn:ietf:wg:oauth:2.0:oob", + }; -export const WRITE_SCOPES = [ - "write:account", - "write:blocks", - "write:bookmarks", - "write:favourites", - "write:filters", - "write:lists", - "write:mutes", - "write:notifications", - "write:statuses", - "write:conversations", - "write:media", - "write:reports", -]; + if (scopes) { + params.scopes = scopes.join(" "); + } + const queryString = new URLSearchParams(params).toString(); + window.location.href = `${instanceUrl}/oauth/authorize?${queryString}`; +}; -export const ADMIN_READ_SCOPES = [ - "admin:read:account", - "admin:read:reports", - "admin:read:domain_allows", - "admin:read:domain_blocks", - "admin:read:ip_blocks", - "admin:read:email_domain_blocks", - "admin:read:canonical_email_blocks", -]; - -export const ADMIN_WRITE_SCOPES = [ - "admin:write:account", - "admin:write:reports", - "admin:write:domain_allows", - "admin:write:domain_blocks", - "admin:write:ip_blocks", - "admin:write:email_domain_blocks", - "admin:write:canonical_email_blocks", -]; - -export const scopesInfo: ScopeInfo[] = [ - { - method: "read", - label: "Read", - scopes: READ_SCOPES, - description: "read account's data", - }, - { - method: "write", - label: "Write", - scopes: WRITE_SCOPES, - description: "modify account's data", - }, - { - method: "admin", - label: "Admin", - scopes: [ADMIN_READ_SCOPES, ADMIN_WRITE_SCOPES], - description: "read all data on the server", - }, - { - method: "follow", - label: "Follow", - description: "modify account relationships,deprecated in 3.5.0 and newer.", - }, - { - method: "push", - label: "Push", - description: "receive push notifications", - }, - - { - method: "crypto", - label: "Crypto", - description: "use end-to-end encryption", - }, -]; diff --git a/package.json b/package.json index ad67b25..63fb19b 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-separator": "^1.0.3", "@radix-ui/react-slot": "^1.0.2", + "@radix-ui/react-tabs": "^1.0.4", "@types/node": "20.2.5", "@types/react": "18.2.7", "@types/react-dom": "18.2.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2715cec..7fc1690 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,6 +19,9 @@ dependencies: '@radix-ui/react-slot': specifier: ^1.0.2 version: 1.0.2(@types/react@18.2.7)(react@18.2.0) + '@radix-ui/react-tabs': + specifier: ^1.0.4 + version: 1.0.4(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0) '@types/node': specifier: 20.2.5 version: 20.2.5 @@ -395,6 +398,30 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@radix-ui/react-collection@1.0.3(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.22.3 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.7)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.7)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.7)(react@18.2.0) + '@types/react': 18.2.7 + '@types/react-dom': 18.2.4 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.7)(react@18.2.0): resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==} peerDependencies: @@ -423,6 +450,20 @@ packages: react: 18.2.0 dev: false + /@radix-ui/react-direction@1.0.1(@types/react@18.2.7)(react@18.2.0): + resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.22.3 + '@types/react': 18.2.7 + react: 18.2.0 + dev: false + /@radix-ui/react-id@1.0.1(@types/react@18.2.7)(react@18.2.0): resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==} peerDependencies: @@ -502,6 +543,35 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@radix-ui/react-roving-focus@1.0.4(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.22.3 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.7)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.7)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.7)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.7)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.7)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.7)(react@18.2.0) + '@types/react': 18.2.7 + '@types/react-dom': 18.2.4 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-separator@1.0.3(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-itYmTy/kokS21aiV5+Z56MZB54KrhPgn6eHDKkFeOLR34HMN2s8PaN47qZZAGnvupcjxHaFZnW4pQEh0BvvVuw==} peerDependencies: @@ -538,6 +608,34 @@ packages: react: 18.2.0 dev: false + /@radix-ui/react-tabs@1.0.4(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-egZfYY/+wRNCflXNHx+dePvnz9FbmssDTJBtgRfDY7e8SE5oIo3Py2eCB1ckAbh1Q7cQ/6yJZThJ++sgbxibog==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.22.3 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-context': 1.0.1(@types/react@18.2.7)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.7)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.7)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.7)(react@18.2.0) + '@types/react': 18.2.7 + '@types/react-dom': 18.2.4 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.7)(react@18.2.0): resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==} peerDependencies: @@ -661,8 +759,8 @@ packages: resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==} dev: false - /@typescript-eslint/parser@5.59.8(eslint@8.41.0)(typescript@5.0.4): - resolution: {integrity: sha512-AnR19RjJcpjoeGojmwZtCwBX/RidqDZtzcbG3xHrmz0aHHoOcbWnpDllenRDmDvsV0RQ6+tbb09/kyc+UT9Orw==} + /@typescript-eslint/parser@5.59.9(eslint@8.41.0)(typescript@5.0.4): + resolution: {integrity: sha512-FsPkRvBtcLQ/eVK1ivDiNYBjn3TGJdXy2fhXX+rc7czWl4ARwnpArwbihSOHI2Peg9WbtGHrbThfBUkZZGTtvQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -671,9 +769,9 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.59.8 - '@typescript-eslint/types': 5.59.8 - '@typescript-eslint/typescript-estree': 5.59.8(typescript@5.0.4) + '@typescript-eslint/scope-manager': 5.59.9 + '@typescript-eslint/types': 5.59.9 + '@typescript-eslint/typescript-estree': 5.59.9(typescript@5.0.4) debug: 4.3.4 eslint: 8.41.0 typescript: 5.0.4 @@ -681,21 +779,21 @@ packages: - supports-color dev: false - /@typescript-eslint/scope-manager@5.59.8: - resolution: {integrity: sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==} + /@typescript-eslint/scope-manager@5.59.9: + resolution: {integrity: sha512-8RA+E+w78z1+2dzvK/tGZ2cpGigBZ58VMEHDZtpE1v+LLjzrYGc8mMaTONSxKyEkz3IuXFM0IqYiGHlCsmlZxQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.59.8 - '@typescript-eslint/visitor-keys': 5.59.8 + '@typescript-eslint/types': 5.59.9 + '@typescript-eslint/visitor-keys': 5.59.9 dev: false - /@typescript-eslint/types@5.59.8: - resolution: {integrity: sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==} + /@typescript-eslint/types@5.59.9: + resolution: {integrity: sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: false - /@typescript-eslint/typescript-estree@5.59.8(typescript@5.0.4): - resolution: {integrity: sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==} + /@typescript-eslint/typescript-estree@5.59.9(typescript@5.0.4): + resolution: {integrity: sha512-pmM0/VQ7kUhd1QyIxgS+aRvMgw+ZljB3eDb+jYyp6d2bC0mQWLzUDF+DLwCTkQ3tlNyVsvZRXjFyV0LkU/aXjA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' @@ -703,8 +801,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.59.8 - '@typescript-eslint/visitor-keys': 5.59.8 + '@typescript-eslint/types': 5.59.9 + '@typescript-eslint/visitor-keys': 5.59.9 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -715,11 +813,11 @@ packages: - supports-color dev: false - /@typescript-eslint/visitor-keys@5.59.8: - resolution: {integrity: sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==} + /@typescript-eslint/visitor-keys@5.59.9: + resolution: {integrity: sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.59.8 + '@typescript-eslint/types': 5.59.9 eslint-visitor-keys: 3.4.1 dev: false @@ -881,7 +979,7 @@ packages: postcss: ^8.1.0 dependencies: browserslist: 4.21.7 - caniuse-lite: 1.0.30001492 + caniuse-lite: 1.0.30001495 fraction.js: 4.2.0 normalize-range: 0.1.2 picocolors: 1.0.0 @@ -941,8 +1039,8 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001492 - electron-to-chromium: 1.4.417 + caniuse-lite: 1.0.30001495 + electron-to-chromium: 1.4.423 node-releases: 2.0.12 update-browserslist-db: 1.0.11(browserslist@4.21.7) dev: false @@ -983,8 +1081,8 @@ packages: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} - /caniuse-lite@1.0.30001492: - resolution: {integrity: sha512-2efF8SAZwgAX1FJr87KWhvuJxnGJKOnctQa8xLOskAXNXq8oiuqgl6u1kk3fFpsp3GgvzlRjiK1sl63hNtFADw==} + /caniuse-lite@1.0.30001495: + resolution: {integrity: sha512-F6x5IEuigtUfU5ZMQK2jsy5JqUUlEFRVZq8bO2a+ysq5K7jD6PPc9YXZj78xDNS3uNchesp1Jw47YXEqr+Viyg==} dev: false /capital-case@1.0.4: @@ -1269,8 +1367,8 @@ packages: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} dev: true - /electron-to-chromium@1.4.417: - resolution: {integrity: sha512-8rY8HdCxuSVY8wku3i/eDac4g1b4cSbruzocenrqBlzqruAZYHjQCHIjC66dLR9DXhEHTojsC4EjhZ8KmzwXqA==} + /electron-to-chromium@1.4.423: + resolution: {integrity: sha512-y4A7YfQcDGPAeSWM1IuoWzXpg9RY1nwHzHSwRtCSQFp9FgAVDgdWlFf0RbdWfLWQ2WUI+bddUgk5RgTjqRE6FQ==} dev: false /emoji-regex@8.0.0: @@ -1386,11 +1484,11 @@ packages: dependencies: '@next/eslint-plugin-next': 13.4.4 '@rushstack/eslint-patch': 1.3.0 - '@typescript-eslint/parser': 5.59.8(eslint@8.41.0)(typescript@5.0.4) + '@typescript-eslint/parser': 5.59.9(eslint@8.41.0)(typescript@5.0.4) eslint: 8.41.0 eslint-import-resolver-node: 0.3.7 - eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.59.8)(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.27.5)(eslint@8.41.0) - eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.59.8)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0) + eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.27.5)(eslint@8.41.0) + eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0) eslint-plugin-jsx-a11y: 6.7.1(eslint@8.41.0) eslint-plugin-react: 7.32.2(eslint@8.41.0) eslint-plugin-react-hooks: 4.6.0(eslint@8.41.0) @@ -1419,7 +1517,7 @@ packages: - supports-color dev: false - /eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.59.8)(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.27.5)(eslint@8.41.0): + /eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.27.5)(eslint@8.41.0): resolution: {integrity: sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -1429,8 +1527,8 @@ packages: debug: 4.3.4 enhanced-resolve: 5.14.1 eslint: 8.41.0 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.59.8)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0) - eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.59.8)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0) + eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0) get-tsconfig: 4.6.0 globby: 13.1.4 is-core-module: 2.12.1 @@ -1443,7 +1541,7 @@ packages: - supports-color dev: false - /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.59.8)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0): + /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} peerDependencies: @@ -1464,16 +1562,16 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.59.8(eslint@8.41.0)(typescript@5.0.4) + '@typescript-eslint/parser': 5.59.9(eslint@8.41.0)(typescript@5.0.4) debug: 3.2.7 eslint: 8.41.0 eslint-import-resolver-node: 0.3.7 - eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.59.8)(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.27.5)(eslint@8.41.0) + eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.27.5)(eslint@8.41.0) transitivePeerDependencies: - supports-color dev: false - /eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.59.8)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0): + /eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0): resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} engines: {node: '>=4'} peerDependencies: @@ -1483,7 +1581,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.59.8(eslint@8.41.0)(typescript@5.0.4) + '@typescript-eslint/parser': 5.59.9(eslint@8.41.0)(typescript@5.0.4) array-includes: 3.1.6 array.prototype.flat: 1.3.1 array.prototype.flatmap: 1.3.1 @@ -1491,7 +1589,7 @@ packages: doctrine: 2.1.0 eslint: 8.41.0 eslint-import-resolver-node: 0.3.7 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.59.8)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0) has: 1.0.3 is-core-module: 2.12.1 is-glob: 4.0.3 @@ -2470,7 +2568,7 @@ packages: '@next/env': 13.4.4 '@swc/helpers': 0.5.1 busboy: 1.6.0 - caniuse-lite: 1.0.30001492 + caniuse-lite: 1.0.30001495 postcss: 8.4.14 react: 18.2.0 react-dom: 18.2.0(react@18.2.0)