diff --git a/.github/workflows/deploy-server.yml b/.github/workflows/deploy-server.yml
new file mode 100644
index 0000000..05f6b25
--- /dev/null
+++ b/.github/workflows/deploy-server.yml
@@ -0,0 +1,29 @@
+name: "Deploy Server"
+
+on:
+ push:
+ branches:
+ - main
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-node@v3 # needed until 18 becomes the default
+ with:
+ node-version: 18
+ cache: yarn
+ - name: Install dependencies
+ run: yarn install --frozen-lockfile
+ working-directory: ./apps/server
+ - name: Generate Prisma Client
+ working-directory: ./apps/server
+ run: yarn prisma generate
+ - name: Build
+ working-directory: ./apps/server
+ run: yarn build
+ - uses: superfly/flyctl-actions/setup-flyctl@master
+ - run: flyctl deploy --remote-only ./apps/server/build
+ env:
+ FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
diff --git a/.github/workflows/deploy-web-client.yml b/.github/workflows/deploy-web-client.yml
new file mode 100644
index 0000000..4d3922f
--- /dev/null
+++ b/.github/workflows/deploy-web-client.yml
@@ -0,0 +1,32 @@
+name: Deploy Web
+env:
+ VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
+ VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
+on:
+ push:
+ branches:
+ - main
+jobs:
+ Deploy:
+ defaults:
+ run:
+ working-directory: ./apps/app
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-node@v3 # needed until 18 becomes the default
+ with:
+ node-version: 18
+ cache: yarn
+ - name: Install dependencies
+ run: yarn install --frozen-lockfile
+ - name: Generate Prisma Client
+ run: cd ../server && yarn prisma generate
+ - name: Install Vercel CLI
+ run: npm install --global vercel@canary
+ - name: Pull Vercel Environment Information
+ run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
+ - name: Build Project Artifacts
+ run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
+ - name: Deploy Project Artifacts to Vercel
+ run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
diff --git a/.github/workflows/tests-and-check.yml b/.github/workflows/tests-and-check.yml
new file mode 100644
index 0000000..a97cad5
--- /dev/null
+++ b/.github/workflows/tests-and-check.yml
@@ -0,0 +1,44 @@
+name: Tests and Checks
+
+on: [push]
+
+jobs:
+ typecheck:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-node@v3 # needed until 18 becomes the default
+ with:
+ node-version: 18
+ cache: yarn
+
+ - name: Install dependencies
+ run: yarn install --frozen-lockfile
+ - name: Generate Prisma Client
+ run: cd apps/server && yarn prisma generate
+ - name: Typecheck
+ run: yarn ts:check
+ lint:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-node@v3 # needed until 18 becomes the default
+ with:
+ node-version: 18
+ cache: yarn
+ - name: Install dependencies
+ run: yarn install --frozen-lockfile
+ - name: Linting
+ run: yarn lint
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-node@v3 # needed until 18 becomes the default
+ with:
+ node-version: 18
+ cache: yarn
+ - name: Install dependencies
+ run: yarn install --frozen-lockfile
+ - name: Test
+ run: yarn test
diff --git a/README.md b/README.md
index 70d1695..c999d72 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ docker-compose up
```sh
# in another tab
-cd apps/backend
+cd apps/server
cp .env.example .env
npx @serenity-kit/opaque@latest create-server-setup
# copy the string value as OPAQUE_SERVER_SETUP .env
@@ -87,8 +87,10 @@ Users use OPAQUE to authenticate with the server. After Login the server creates
## Todos
-- fix all ts issues
- setup CI (ts:check)
-- implement frontend from jumpstart
-- implement auth (from jumpstart)
+- generate keys and store them locally
+- store keys on lockbox
- add invitation scheme
+
+- store data locally (api in secsync)
+- fix websocket session auth in secsync
diff --git a/apps/app/.gitignore b/apps/app/.gitignore
new file mode 100644
index 0000000..7312a5e
--- /dev/null
+++ b/apps/app/.gitignore
@@ -0,0 +1,15 @@
+node_modules/
+.expo/
+dist/
+npm-debug.*
+*.jks
+*.p8
+*.p12
+*.key
+*.mobileprovision
+*.orig.*
+web-build/
+
+# macOS
+.DS_Store
+
diff --git a/apps/app/app.json b/apps/app/app.json
index 0cb1ba1..f8ef4e3 100644
--- a/apps/app/app.json
+++ b/apps/app/app.json
@@ -6,10 +6,10 @@
"scheme": "acme",
"version": "1.0.0",
"orientation": "portrait",
- "icon": "./assets/icon.png",
+ "icon": "./assets/images/icon.png",
"userInterfaceStyle": "light",
"splash": {
- "image": "./assets/splash.png",
+ "image": "./assets/images/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
@@ -20,14 +20,14 @@
},
"android": {
"adaptiveIcon": {
- "foregroundImage": "./assets/adaptive-icon.png",
+ "foregroundImage": "./assets/images/adaptive-icon.png",
"backgroundColor": "#ffffff"
}
},
"web": {
- "favicon": "./assets/favicon.png"
+ "favicon": "./assets/images/favicon.png"
},
- "plugins": ["expo-router", "expo-asset"],
+ "plugins": ["expo-router"],
"extra": {
"router": {
"origin": false
diff --git a/apps/app/assets/fonts/SpaceMono-Regular.ttf b/apps/app/assets/fonts/SpaceMono-Regular.ttf
new file mode 100755
index 0000000..28d7ff7
Binary files /dev/null and b/apps/app/assets/fonts/SpaceMono-Regular.ttf differ
diff --git a/apps/app/assets/icon.png b/apps/app/assets/icon.png
deleted file mode 100644
index 31fdbf0..0000000
Binary files a/apps/app/assets/icon.png and /dev/null differ
diff --git a/apps/app/assets/adaptive-icon.png b/apps/app/assets/images/adaptive-icon.png
similarity index 100%
rename from apps/app/assets/adaptive-icon.png
rename to apps/app/assets/images/adaptive-icon.png
diff --git a/apps/app/assets/favicon.png b/apps/app/assets/images/favicon.png
similarity index 100%
rename from apps/app/assets/favicon.png
rename to apps/app/assets/images/favicon.png
diff --git a/apps/app/assets/images/icon.png b/apps/app/assets/images/icon.png
new file mode 100644
index 0000000..a0b1526
Binary files /dev/null and b/apps/app/assets/images/icon.png differ
diff --git a/apps/app/assets/images/partial-react-logo.png b/apps/app/assets/images/partial-react-logo.png
new file mode 100644
index 0000000..66fd957
Binary files /dev/null and b/apps/app/assets/images/partial-react-logo.png differ
diff --git a/apps/app/assets/images/react-logo.png b/apps/app/assets/images/react-logo.png
new file mode 100644
index 0000000..9d72a9f
Binary files /dev/null and b/apps/app/assets/images/react-logo.png differ
diff --git a/apps/app/assets/images/react-logo@2x.png b/apps/app/assets/images/react-logo@2x.png
new file mode 100644
index 0000000..2229b13
Binary files /dev/null and b/apps/app/assets/images/react-logo@2x.png differ
diff --git a/apps/app/assets/images/react-logo@3x.png b/apps/app/assets/images/react-logo@3x.png
new file mode 100644
index 0000000..a99b203
Binary files /dev/null and b/apps/app/assets/images/react-logo@3x.png differ
diff --git a/apps/app/assets/images/splash.png b/apps/app/assets/images/splash.png
new file mode 100644
index 0000000..0e89705
Binary files /dev/null and b/apps/app/assets/images/splash.png differ
diff --git a/apps/app/assets/splash.png b/apps/app/assets/splash.png
deleted file mode 100644
index 4130bbd..0000000
Binary files a/apps/app/assets/splash.png and /dev/null differ
diff --git a/apps/app/babel.config.js b/apps/app/babel.config.js
index 9d74a33..02f1d10 100644
--- a/apps/app/babel.config.js
+++ b/apps/app/babel.config.js
@@ -6,5 +6,6 @@ module.exports = (api) => {
["babel-preset-expo", { jsxImportSource: "nativewind" }],
"nativewind/babel",
],
+ plugins: ["react-native-reanimated/plugin"],
};
};
diff --git a/apps/app/metro.config.js b/apps/app/metro.config.js
index e2423a3..3c80801 100644
--- a/apps/app/metro.config.js
+++ b/apps/app/metro.config.js
@@ -6,8 +6,9 @@ const { withNativeWind } = require("nativewind/metro");
const path = require("node:path");
+// from https://github.com/nativewind/nativewind/blob/main/examples/expo-router/metro.config.js
/** @type {import('expo/metro-config').MetroConfig} */
-const config = getDefaultConfig(__dirname);
+const config = getDefaultConfig(__dirname, { isCSSEnabled: true });
config.resolver.unstable_enableSymlinks = true;
config.resolver.unstable_enablePackageExports = true;
@@ -23,4 +24,8 @@ config.resolver.nodeModulesPaths = [
path.resolve(monorepoRoot, "node_modules"),
];
-module.exports = withNativeWind(config, { input: "./src/global.css" });
+module.exports = withNativeWind(config, {
+ input: "./src/global.css",
+ // from https://github.com/nativewind/nativewind/blob/main/examples/expo-router/metro.config.js
+ inlineRem: false,
+});
diff --git a/apps/app/package.json b/apps/app/package.json
index cb31748..ce7b18b 100644
--- a/apps/app/package.json
+++ b/apps/app/package.json
@@ -1,45 +1,52 @@
{
"name": "koriko",
+ "main": "src/AppEntry.ts",
"version": "1.0.0",
- "main": "./src/AppEntry.ts",
"scripts": {
"dev": "EXPO_USE_METRO_WORKSPACE_ROOT=1 expo start --dev-client",
- "ts:check": "tsc --noEmit"
+ "ts:check": "tsc --noEmit",
+ "test": "jest",
+ "lint": "echo \"Lint not setup\" # expo lint"
+ },
+ "jest": {
+ "preset": "jest-expo"
},
"dependencies": {
- "@effect/schema": "^0.67.15",
- "@expo/metro-runtime": "~3.2.1",
"@expo/vector-icons": "^14.0.0",
- "@react-native/assets-registry": "0.75.0-main",
+ "@react-navigation/native": "^6.0.2",
+ "@tanstack/react-query": "^5.40.0",
+ "@trpc/client": "^11.0.0-rc.382",
+ "@trpc/react-query": "^11.0.0-rc.382",
"babel-preset-expo": "~11.0.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
- "expo": "51.0.9",
- "expo-asset": "~10.0.6",
- "expo-clipboard": "~6.0.3",
+ "expo": "~51.0.9",
"expo-constants": "~16.0.2",
"expo-crypto": "~13.0.2",
"expo-dev-client": "~4.0.15",
+ "expo-font": "~12.0.6",
"expo-linking": "~6.3.1",
"expo-router": "~3.5.14",
- "expo-sqlite": "~14.0.3",
+ "expo-splash-screen": "~0.27.4",
"expo-standard-web-crypto": "^1.8.1",
"expo-status-bar": "~1.12.1",
- "fast-text-encoding": "^1.0.6",
+ "expo-system-ui": "~3.0.4",
"lucide-react-native": "^0.381.0",
"nativewind": "^4.0.1",
"position-strings": "^2.0.1",
- "react": "18.3.1",
- "react-dom": "^18.2.0",
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
"react-native": "0.74.1",
+ "react-native-gesture-handler": "~2.16.1",
"react-native-libsodium": "^1.3.1",
- "react-native-reanimated": "~3.11.0",
- "react-native-safe-area-context": "4.10.3",
+ "react-native-opaque": "^0.3.1",
+ "react-native-reanimated": "~3.10.1",
+ "react-native-safe-area-context": "4.10.1",
"react-native-screens": "3.31.1",
- "react-native-svg": "15.3.0",
- "react-native-web": "~0.19.6",
- "secsync-react-yjs": "^0.4.0",
+ "react-native-svg": "15.2.0",
+ "react-native-web": "~0.19.10",
"secsync": "^0.4.0",
+ "secsync-react-yjs": "^0.4.0",
"tailwind-merge": "^2.3.0",
"tailwindcss": "^3.4.0",
"tailwindcss-animate": "^1.0.7",
@@ -47,19 +54,12 @@
"zustand": "^4.5.2"
},
"devDependencies": {
- "@babel/core": "^7.24.3",
- "@babel/runtime": "^7.24.1",
- "@types/react": "~18.3.3",
- "babel-plugin-transform-vite-meta-env": "^1.0.3",
- "eslint": "^9.3.0",
- "husky": "^9.0.11",
- "lint-staged": "^15.2.5",
- "prettier": "3.2.5",
- "prettier-plugin-tailwindcss": "^0.6.0",
- "typescript": "~5.4.5"
- },
- "resolutions": {
- "@effect/schema": "=0.64.16"
+ "@babel/core": "^7.20.0",
+ "@types/jest": "^29.5.12",
+ "@types/react": "~18.2.45",
+ "jest": "^29.2.1",
+ "jest-expo": "~51.0.1",
+ "typescript": "~5.3.3"
},
"private": true
}
diff --git a/apps/app/src/AppEntry.ts b/apps/app/src/AppEntry.ts
index e0ee9bb..460fdbd 100644
--- a/apps/app/src/AppEntry.ts
+++ b/apps/app/src/AppEntry.ts
@@ -1,2 +1,3 @@
-import "expo-router/entry";
import "./polyfill.ts";
+// must to be after the polyfill
+import "expo-router/entry";
diff --git a/apps/app/src/app/+html.tsx b/apps/app/src/app/+html.tsx
new file mode 100644
index 0000000..2d6b247
--- /dev/null
+++ b/apps/app/src/app/+html.tsx
@@ -0,0 +1,42 @@
+import { ScrollViewStyleReset } from "expo-router/html";
+import { type PropsWithChildren } from "react";
+
+/**
+ * This file is web-only and used to configure the root HTML for every web page during static rendering.
+ * The contents of this function only run in Node.js environments and do not have access to the DOM or browser APIs.
+ */
+export default function Root({ children }: PropsWithChildren) {
+ return (
+
+
+
+
+
+
+ {/*
+ Disable body scrolling on web. This makes ScrollView components work closer to how they do on native.
+ However, body scrolling is often nice to have for mobile web. If you want to enable it, remove this line.
+ */}
+
+
+ {/* Using raw CSS styles as an escape-hatch to ensure the background color never flickers in dark-mode. */}
+
+ {/* Add any additional elements that you want globally available on web... */}
+
+ {children}
+
+ );
+}
+
+const responsiveBackground = `
+body {
+ background-color: #fff;
+}
+@media (prefers-color-scheme: dark) {
+ body {
+ background-color: #000;
+ }
+}`;
diff --git a/apps/app/src/app/+not-found.tsx b/apps/app/src/app/+not-found.tsx
new file mode 100644
index 0000000..539860a
--- /dev/null
+++ b/apps/app/src/app/+not-found.tsx
@@ -0,0 +1,5 @@
+import { Text } from "react-native";
+
+export default () => {
+ return NOT FOUND;
+};
diff --git a/apps/app/src/app/_layout.tsx b/apps/app/src/app/_layout.tsx
index 6b7e0e3..b1636ed 100644
--- a/apps/app/src/app/_layout.tsx
+++ b/apps/app/src/app/_layout.tsx
@@ -1,12 +1,20 @@
import { Theme, ThemeProvider } from "@react-navigation/native";
-import { Stack } from "expo-router";
+import {
+ MutationCache,
+ QueryCache,
+ QueryClient,
+ QueryClientProvider,
+} from "@tanstack/react-query";
+import { httpBatchLink } from "@trpc/client";
+import { SplashScreen, Stack } from "expo-router";
import { StatusBar } from "expo-status-bar";
-import * as React from "react";
+import { useEffect, useState } from "react";
import { SafeAreaProvider } from "react-native-safe-area-context";
import { NAV_THEME } from "~/lib/constants";
import { useColorScheme } from "~/lib/useColorScheme";
import "../global.css";
import useLoadingLibsodium from "../hooks/useLoadingLibsodium";
+import { trpc } from "../utils/trpc";
const LIGHT_THEME: Theme = {
dark: false,
@@ -17,29 +25,103 @@ const DARK_THEME: Theme = {
colors: NAV_THEME.dark,
};
+// TODO PROD API URL
+const apiUrl = "http://localhost:3030/api";
+
+// Catch any errors thrown by the Layout component.
+export { ErrorBoundary } from "expo-router";
+
+SplashScreen.preventAutoHideAsync();
+
export default function Layout() {
const { isDarkColorScheme } = useColorScheme();
const isLoadingComplete = useLoadingLibsodium();
+ useEffect(() => {
+ if (isLoadingComplete) {
+ SplashScreen.hideAsync();
+ }
+ }, [isLoadingComplete]);
+
+ const [queryClient] = useState(
+ () =>
+ new QueryClient({
+ queryCache: new QueryCache({
+ // TODO
+ // onError: (error) => {
+ // if (
+ // error instanceof TRPCClientError &&
+ // error.data?.code === "UNAUTHORIZED" &&
+ // window.location.pathname !== "/login"
+ // ) {
+ // removeLocalDb();
+ // queryClient.clear();
+ // router.navigate({
+ // to: "/login",
+ // search: { redirect: window.location.pathname },
+ // });
+ // }
+ // },
+ }),
+ mutationCache: new MutationCache({
+ // TODO
+ // onError: (error) => {
+ // if (
+ // error instanceof TRPCClientError &&
+ // error.data?.code === "UNAUTHORIZED" &&
+ // window.location.pathname !== "/login"
+ // ) {
+ // removeLocalDb();
+ // queryClient.clear();
+ // router.navigate({
+ // to: "/login",
+ // search: { redirect: window.location.pathname },
+ // });
+ // }
+ // },
+ }),
+ })
+ );
+ const [trpcClient] = useState(() =>
+ trpc.createClient({
+ links: [
+ httpBatchLink({
+ url: apiUrl,
+ fetch(url, options) {
+ return fetch(url, {
+ ...options,
+ credentials: "include",
+ });
+ },
+ }),
+ ],
+ })
+ );
+
if (!isLoadingComplete) {
return null;
}
return (
-
-
-
-
-
-
- {/* Default Portal Host (one per app) */}
-
-
+
+
+
+
+
+
+
+
+ {/* Default Portal Host (one per app) */}
+ {/* */}
+
+
+
+
);
}
diff --git a/apps/app/src/app/index.tsx b/apps/app/src/app/index.tsx
index d80cde9..e686f8b 100644
--- a/apps/app/src/app/index.tsx
+++ b/apps/app/src/app/index.tsx
@@ -1,14 +1,53 @@
import { Link } from "expo-router";
import * as React from "react";
-import { Text } from "react-native";
+import { View } from "react-native";
+import { Card } from "~/components/ui/card";
+import { Text } from "~/components/ui/text";
+import { CreateListForm } from "../components/createListForm";
+import { Logout } from "../components/logout";
+import { trpc } from "../utils/trpc";
const Lists: React.FC = () => {
- const workouts: { id: string; startedAt: string }[] = [];
+ const meQuery = trpc.me.useQuery(undefined, {
+ // avoid lot's of retries in case of unauthorized blocking a page load
+ retry: (failureCount, error) => {
+ if (error.data?.code === "UNAUTHORIZED") {
+ return false;
+ }
+ if (failureCount > 3) return false;
+ return true;
+ },
+ });
+
+ const documentsQuery = trpc.documents.useQuery(undefined, {
+ refetchInterval: 5000,
+ });
return (
-
- Hello WOrld LIST A
-
+
+
+ Login
+
+ Register
+
+
+ {meQuery.data?.username}
+
+
+
+
+
+
+
+ {documentsQuery.data?.map((doc) => (
+
+
+ {doc.name}
+
+
+ ))}
+
+
);
};
diff --git a/apps/app/src/app/login.tsx b/apps/app/src/app/login.tsx
new file mode 100644
index 0000000..cfdee80
--- /dev/null
+++ b/apps/app/src/app/login.tsx
@@ -0,0 +1,48 @@
+import { router, useLocalSearchParams } from "expo-router";
+import { useState } from "react";
+import { View } from "react-native";
+import { Text } from "~/components/ui/text";
+import { AlertCircle } from "~/lib/icons/AlertCircle";
+import { AuthForm } from "../components/authForm";
+import { useLogin } from "../hooks/useLogin";
+
+const Login = () => {
+ const { login, isPending } = useLogin();
+ const [error, setError] = useState(null);
+ const { redirect } = useLocalSearchParams<{ redirect?: string }>();
+
+ return (
+
+ {
+ const sessionKey = await login({
+ userIdentifier: username,
+ password,
+ });
+ if (!sessionKey) {
+ setError("Failed to login");
+ return;
+ }
+ if (redirect) {
+ router.navigate(redirect);
+ return;
+ }
+ router.navigate("/");
+ }}
+ children={Login}
+ isPending={isPending}
+ />
+
+ {error && (
+
+
+ {/* TODO proper styling */}
+ Error
+ Failed to log in
+
+ )}
+
+ );
+};
+
+export default Login;
diff --git a/apps/app/src/app/register.tsx b/apps/app/src/app/register.tsx
new file mode 100644
index 0000000..eb46c39
--- /dev/null
+++ b/apps/app/src/app/register.tsx
@@ -0,0 +1,47 @@
+import { router, useLocalSearchParams } from "expo-router";
+import { useState } from "react";
+import { View } from "react-native";
+import { Text } from "~/components/ui/text";
+import { AlertCircle } from "~/lib/icons/AlertCircle";
+import { AuthForm } from "../components/authForm";
+import { useRegisterAndLogin } from "../hooks/useRegisterAndLogin";
+
+const Register = () => {
+ const { registerAndLogin, isPending } = useRegisterAndLogin();
+ const { redirect } = useLocalSearchParams<{ redirect?: string }>();
+ const [error, setError] = useState(null);
+
+ return (
+
+ {
+ const sessionKey = await registerAndLogin({
+ userIdentifier: username,
+ password,
+ });
+ if (!sessionKey) {
+ setError("Failed to register");
+ return;
+ }
+ if (redirect) {
+ router.navigate(redirect);
+ return;
+ }
+ router.navigate("/");
+ }}
+ children={Register}
+ isPending={isPending}
+ />
+ {error && (
+
+
+ {/* TODO proper styling */}
+ Error
+ Failed to register
+
+ )}
+
+ );
+};
+
+export default Register;
diff --git a/apps/app/src/components/authForm.tsx b/apps/app/src/components/authForm.tsx
new file mode 100644
index 0000000..b515af3
--- /dev/null
+++ b/apps/app/src/components/authForm.tsx
@@ -0,0 +1,57 @@
+import { useState } from "react";
+import { View } from "react-native";
+import { Button } from "~/components/ui/button";
+import { Input } from "~/components/ui/input";
+import { Text } from "~/components/ui/text";
+
+type Props = {
+ onSubmit: (params: { username: string; password: string }) => void;
+ isPending: boolean;
+ children: React.ReactNode;
+};
+
+export const AuthForm = ({ onSubmit, isPending, children }: Props) => {
+ const [username, setUsername] = useState("");
+ const [password, setPassword] = useState("");
+
+ return (
+
+
+ {children}
+
+
+
+ {
+ setUsername(value);
+ }}
+ />
+
+ {
+ setPassword(value);
+ }}
+ />
+
+
+
+
+ );
+};
diff --git a/apps/app/src/components/createListForm.tsx b/apps/app/src/components/createListForm.tsx
new file mode 100644
index 0000000..e5017a7
--- /dev/null
+++ b/apps/app/src/components/createListForm.tsx
@@ -0,0 +1,47 @@
+import { router } from "expo-router";
+import { useState } from "react";
+import { Alert, View } from "react-native";
+import { Button } from "~/components/ui/button";
+import { Input } from "~/components/ui/input";
+import { Text } from "~/components/ui/text";
+import { trpc } from "../utils/trpc";
+
+export const CreateListForm: React.FC = () => {
+ const [name, setName] = useState("");
+ const createDocumentMutation = trpc.createDocument.useMutation();
+
+ return (
+
+ {
+ setName(value);
+ }}
+ />
+
+
+ );
+};
diff --git a/apps/app/src/components/logout.tsx b/apps/app/src/components/logout.tsx
new file mode 100644
index 0000000..b27ae32
--- /dev/null
+++ b/apps/app/src/components/logout.tsx
@@ -0,0 +1,34 @@
+import { useQueryClient } from "@tanstack/react-query";
+import { router } from "expo-router";
+import { Alert } from "react-native";
+import { Button } from "~/components/ui/button";
+import { Text } from "~/components/ui/text";
+import { trpc } from "../utils/trpc";
+
+export const Logout: React.FC = () => {
+ const logoutMutation = trpc.logout.useMutation();
+ const queryClient = useQueryClient();
+
+ return (
+
+ );
+};
diff --git a/apps/app/src/hooks/useInterval.ts b/apps/app/src/hooks/useInterval.ts
new file mode 100644
index 0000000..754b8b5
--- /dev/null
+++ b/apps/app/src/hooks/useInterval.ts
@@ -0,0 +1,24 @@
+import { useEffect, useRef } from "react";
+
+type IntervalFunc = () => unknown | void;
+
+// Inspired by https://overreacted.io/making-setinterval-declarative-with-react-hooks/
+export const useInterval = (callback: IntervalFunc, delay: number | null) => {
+ const savedCallback = useRef(null);
+
+ useEffect(() => {
+ if (delay === null) return;
+ savedCallback.current = callback;
+ });
+
+ useEffect(() => {
+ if (delay === null) return;
+ function tick() {
+ if (savedCallback.current !== null) {
+ savedCallback.current();
+ }
+ }
+ const id = setInterval(tick, delay);
+ return () => clearInterval(id);
+ }, [delay]);
+};
diff --git a/apps/app/src/hooks/useLoadingLibsodium.ts b/apps/app/src/hooks/useLoadingLibsodium.ts
index c4588f4..044e505 100644
--- a/apps/app/src/hooks/useLoadingLibsodium.ts
+++ b/apps/app/src/hooks/useLoadingLibsodium.ts
@@ -1,4 +1,3 @@
-import * as SplashScreen from "expo-splash-screen";
import { useEffect, useState } from "react";
import { Alert } from "react-native";
import sodium from "react-native-libsodium";
@@ -10,13 +9,11 @@ export default function useLoadingLibsodium() {
useEffect(() => {
async function load() {
try {
- SplashScreen.preventAutoHideAsync();
await sodium.ready; // sodium must be ready before we load any devices or similar
} catch (e) {
Alert.alert("Couldn't load encryption library");
} finally {
setLoadingComplete(true);
- SplashScreen.hideAsync();
}
}
diff --git a/apps/app/src/hooks/useLogin.ts b/apps/app/src/hooks/useLogin.ts
new file mode 100644
index 0000000..b7cb504
--- /dev/null
+++ b/apps/app/src/hooks/useLogin.ts
@@ -0,0 +1,55 @@
+import { useQueryClient } from "@tanstack/react-query";
+import { useState } from "react";
+import * as opaque from "react-native-opaque";
+import { trpc } from "../utils/trpc";
+
+type LoginParams = {
+ userIdentifier: string;
+ password: string;
+};
+
+export const useLogin = () => {
+ const loginStartMutation = trpc.loginStart.useMutation();
+ const loginFinishMutation = trpc.loginFinish.useMutation();
+
+ const queryClient = useQueryClient();
+ const [isPending, setIsPending] = useState(false);
+
+ const login = async ({ userIdentifier, password }: LoginParams) => {
+ setIsPending(true);
+ try {
+ const { clientLoginState, startLoginRequest } = opaque.client.startLogin({
+ password,
+ });
+
+ const { loginResponse } = await loginStartMutation.mutateAsync({
+ userIdentifier,
+ startLoginRequest,
+ });
+
+ const loginResult = opaque.client.finishLogin({
+ clientLoginState,
+ loginResponse,
+ password,
+ });
+ if (!loginResult) {
+ return null;
+ }
+ const { sessionKey, finishLoginRequest } = loginResult;
+
+ const { success } = await loginFinishMutation.mutateAsync({
+ finishLoginRequest,
+ userIdentifier,
+ });
+
+ queryClient.invalidateQueries();
+
+ return success ? sessionKey : null;
+ } catch (error) {
+ return null;
+ } finally {
+ setIsPending(false);
+ }
+ };
+ return { isPending, login };
+};
diff --git a/apps/app/src/hooks/useRegisterAndLogin.ts b/apps/app/src/hooks/useRegisterAndLogin.ts
new file mode 100644
index 0000000..a0a0bf7
--- /dev/null
+++ b/apps/app/src/hooks/useRegisterAndLogin.ts
@@ -0,0 +1,51 @@
+import { useState } from "react";
+import * as opaque from "react-native-opaque";
+import { trpc } from "../utils/trpc";
+import { useLogin } from "./useLogin";
+
+type RegisterParams = {
+ userIdentifier: string;
+ password: string;
+};
+
+export const useRegisterAndLogin = () => {
+ const [isPending, setIsPending] = useState(false);
+ const registerStartMutation = trpc.registerStart.useMutation();
+ const registerFinishMutation = trpc.registerFinish.useMutation();
+ const { login } = useLogin();
+
+ const registerAndLogin = async ({
+ userIdentifier,
+ password,
+ }: RegisterParams) => {
+ setIsPending(true);
+ try {
+ const { clientRegistrationState, registrationRequest } =
+ opaque.client.startRegistration({ password });
+ const { registrationResponse } = await registerStartMutation.mutateAsync({
+ userIdentifier,
+ registrationRequest,
+ });
+
+ const { registrationRecord } = opaque.client.finishRegistration({
+ clientRegistrationState,
+ registrationResponse,
+ password,
+ });
+
+ await registerFinishMutation.mutateAsync({
+ userIdentifier,
+ registrationRecord,
+ });
+
+ const result = await login({ userIdentifier, password });
+ return result;
+ } catch (error) {
+ return null;
+ } finally {
+ setIsPending(false);
+ }
+ };
+
+ return { isPending, registerAndLogin };
+};
diff --git a/apps/app/src/rnr/components/primitives/hooks/index.ts b/apps/app/src/rnr/components/primitives/hooks/index.ts
new file mode 100644
index 0000000..58c0d1b
--- /dev/null
+++ b/apps/app/src/rnr/components/primitives/hooks/index.ts
@@ -0,0 +1,3 @@
+export { useAugmentedRef } from './useAugmentedRef';
+export { useRelativePosition, type LayoutPosition } from './useRelativePosition';
+export { useControllableState } from './useControllableState';
diff --git a/apps/app/src/rnr/components/primitives/hooks/useAugmentedRef.tsx b/apps/app/src/rnr/components/primitives/hooks/useAugmentedRef.tsx
new file mode 100644
index 0000000..13a5669
--- /dev/null
+++ b/apps/app/src/rnr/components/primitives/hooks/useAugmentedRef.tsx
@@ -0,0 +1,29 @@
+import * as React from 'react';
+
+interface AugmentRefProps {
+ ref: React.Ref;
+ methods?: Record any>;
+ deps?: any[];
+}
+
+export function useAugmentedRef({
+ ref,
+ methods,
+ deps = [],
+}: AugmentRefProps) {
+ const augmentedRef = React.useRef(null);
+ React.useImperativeHandle(
+ ref,
+ () => {
+ if (typeof augmentedRef === 'function' || !augmentedRef?.current) {
+ return {} as T;
+ }
+ return {
+ ...augmentedRef.current,
+ ...methods,
+ };
+ },
+ deps
+ );
+ return augmentedRef;
+}
diff --git a/apps/app/src/rnr/components/primitives/hooks/useControllableState.tsx b/apps/app/src/rnr/components/primitives/hooks/useControllableState.tsx
new file mode 100644
index 0000000..3b42b53
--- /dev/null
+++ b/apps/app/src/rnr/components/primitives/hooks/useControllableState.tsx
@@ -0,0 +1,75 @@
+// This project uses code from WorkOS/Radix Primitives.
+// The code is licensed under the MIT License.
+// https://github.com/radix-ui/primitives/tree/main
+
+import * as React from 'react';
+
+type UseControllableStateParams = {
+ prop?: T | undefined;
+ defaultProp?: T | undefined;
+ onChange?: (state: T) => void;
+};
+
+type SetStateFn = (prevState?: T) => T;
+
+function useControllableState({
+ prop,
+ defaultProp,
+ onChange = () => {},
+}: UseControllableStateParams) {
+ const [uncontrolledProp, setUncontrolledProp] = useUncontrolledState({ defaultProp, onChange });
+ const isControlled = prop !== undefined;
+ const value = isControlled ? prop : uncontrolledProp;
+ const handleChange = useCallbackRef(onChange);
+
+ const setValue: React.Dispatch> = React.useCallback(
+ (nextValue) => {
+ if (isControlled) {
+ const setter = nextValue as SetStateFn;
+ const value = typeof nextValue === 'function' ? setter(prop) : nextValue;
+ if (value !== prop) handleChange(value as T);
+ } else {
+ setUncontrolledProp(nextValue);
+ }
+ },
+ [isControlled, prop, setUncontrolledProp, handleChange]
+ );
+
+ return [value, setValue] as const;
+}
+
+function useUncontrolledState({
+ defaultProp,
+ onChange,
+}: Omit, 'prop'>) {
+ const uncontrolledState = React.useState(defaultProp);
+ const [value] = uncontrolledState;
+ const prevValueRef = React.useRef(value);
+ const handleChange = useCallbackRef(onChange);
+
+ React.useEffect(() => {
+ if (prevValueRef.current !== value) {
+ handleChange(value as T);
+ prevValueRef.current = value;
+ }
+ }, [value, prevValueRef, handleChange]);
+
+ return uncontrolledState;
+}
+
+/**
+ * A custom hook that converts a callback to a ref to avoid triggering re-renders when passed as a
+ * prop or avoid re-executing effects when passed as a dependency
+ */
+function useCallbackRef any>(callback: T | undefined): T {
+ const callbackRef = React.useRef(callback);
+
+ React.useEffect(() => {
+ callbackRef.current = callback;
+ });
+
+ // https://github.com/facebook/react/issues/19240
+ return React.useMemo(() => ((...args) => callbackRef.current?.(...args)) as T, []);
+}
+
+export { useControllableState };
diff --git a/apps/app/src/rnr/components/primitives/hooks/useRelativePosition.tsx b/apps/app/src/rnr/components/primitives/hooks/useRelativePosition.tsx
new file mode 100644
index 0000000..f1544be
--- /dev/null
+++ b/apps/app/src/rnr/components/primitives/hooks/useRelativePosition.tsx
@@ -0,0 +1,227 @@
+import * as React from 'react';
+import {
+ useWindowDimensions,
+ type LayoutRectangle,
+ type ScaledSize,
+ type ViewStyle,
+} from 'react-native';
+import type { Insets } from '~/components/primitives/types';
+
+const POSITION_ABSOLUTE: ViewStyle = {
+ position: 'absolute',
+};
+
+const HIDDEN_CONTENT: ViewStyle = {
+ position: 'absolute',
+ opacity: 0,
+ zIndex: -9999999,
+};
+
+type UseRelativePositionArgs = Omit<
+ GetContentStyleArgs,
+ 'triggerPosition' | 'contentLayout' | 'dimensions'
+> & {
+ triggerPosition: LayoutPosition | null;
+ contentLayout: LayoutRectangle | null;
+ disablePositioningStyle?: boolean;
+};
+
+export function useRelativePosition({
+ align,
+ avoidCollisions,
+ triggerPosition,
+ contentLayout,
+ alignOffset,
+ insets,
+ sideOffset,
+ side,
+ disablePositioningStyle,
+}: UseRelativePositionArgs) {
+ const dimensions = useWindowDimensions();
+ return React.useMemo(() => {
+ if (disablePositioningStyle) {
+ return {};
+ }
+ if (!triggerPosition || !contentLayout) {
+ return HIDDEN_CONTENT;
+ }
+ return getContentStyle({
+ align,
+ avoidCollisions,
+ contentLayout,
+ side,
+ triggerPosition,
+ alignOffset,
+ insets,
+ sideOffset,
+ dimensions,
+ });
+ }, [triggerPosition, contentLayout, dimensions.width, dimensions.height]);
+}
+
+export interface LayoutPosition {
+ pageY: number;
+ pageX: number;
+ width: number;
+ height: number;
+}
+
+interface GetPositionArgs {
+ dimensions: ScaledSize;
+ avoidCollisions: boolean;
+ triggerPosition: LayoutPosition;
+ contentLayout: LayoutRectangle;
+ insets?: Insets;
+}
+
+interface GetSidePositionArgs extends GetPositionArgs {
+ side: 'top' | 'bottom';
+ sideOffset: number;
+}
+
+function getSidePosition({
+ side,
+ triggerPosition,
+ contentLayout,
+ sideOffset,
+ insets,
+ avoidCollisions,
+ dimensions,
+}: GetSidePositionArgs) {
+ const insetTop = insets?.top ?? 0;
+ const insetBottom = insets?.bottom ?? 0;
+ const positionTop = triggerPosition?.pageY - sideOffset - contentLayout.height;
+ const positionBottom = triggerPosition.pageY + triggerPosition.height + sideOffset;
+
+ if (!avoidCollisions) {
+ return {
+ top: side === 'top' ? positionTop : positionBottom,
+ };
+ }
+
+ if (side === 'top') {
+ return {
+ top: Math.max(insetTop, positionTop),
+ };
+ }
+
+ return {
+ top: Math.min(dimensions.height - insetBottom - contentLayout.height, positionBottom),
+ };
+}
+
+interface GetAlignPositionArgs extends GetPositionArgs {
+ align: 'start' | 'center' | 'end';
+ alignOffset: number;
+}
+
+function getAlignPosition({
+ align,
+ avoidCollisions,
+ contentLayout,
+ triggerPosition,
+ alignOffset,
+ insets,
+ dimensions,
+}: GetAlignPositionArgs) {
+ const insetLeft = insets?.left ?? 0;
+ const insetRight = insets?.right ?? 0;
+ const maxContentWidth = dimensions.width - insetLeft - insetRight;
+
+ const contentWidth = Math.min(contentLayout.width, maxContentWidth);
+
+ let left = getLeftPosition(
+ align,
+ triggerPosition.pageX,
+ triggerPosition.width,
+ contentWidth,
+ alignOffset,
+ insetLeft,
+ insetRight,
+ dimensions
+ );
+
+ if (avoidCollisions) {
+ const doesCollide = left < insetLeft || left + contentWidth > dimensions.width - insetRight;
+ if (doesCollide) {
+ const spaceLeft = left - insetLeft;
+ const spaceRight = dimensions.width - insetRight - (left + contentWidth);
+
+ if (spaceLeft > spaceRight && spaceLeft >= contentWidth) {
+ left = insetLeft;
+ } else if (spaceRight >= contentWidth) {
+ left = dimensions.width - insetRight - contentWidth;
+ } else {
+ const centeredPosition = Math.max(
+ insetLeft,
+ (dimensions.width - contentWidth - insetRight) / 2
+ );
+ left = centeredPosition;
+ }
+ }
+ }
+
+ return { left, maxWidth: maxContentWidth };
+}
+
+function getLeftPosition(
+ align: 'start' | 'center' | 'end',
+ triggerPageX: number,
+ triggerWidth: number,
+ contentWidth: number,
+ alignOffset: number,
+ insetLeft: number,
+ insetRight: number,
+ dimensions: ScaledSize
+) {
+ let left = 0;
+ if (align === 'start') {
+ left = triggerPageX;
+ }
+ if (align === 'center') {
+ left = triggerPageX + triggerWidth / 2 - contentWidth / 2;
+ }
+ if (align === 'end') {
+ left = triggerPageX + triggerWidth - contentWidth;
+ }
+ return Math.max(
+ insetLeft,
+ Math.min(left + alignOffset, dimensions.width - contentWidth - insetRight)
+ );
+}
+
+type GetContentStyleArgs = GetPositionArgs & GetSidePositionArgs & GetAlignPositionArgs;
+
+function getContentStyle({
+ align,
+ avoidCollisions,
+ contentLayout,
+ side,
+ triggerPosition,
+ alignOffset,
+ insets,
+ sideOffset,
+ dimensions,
+}: GetContentStyleArgs) {
+ return Object.assign(
+ POSITION_ABSOLUTE,
+ getSidePosition({
+ side,
+ triggerPosition,
+ contentLayout,
+ sideOffset,
+ insets,
+ avoidCollisions,
+ dimensions,
+ }),
+ getAlignPosition({
+ align,
+ avoidCollisions,
+ triggerPosition,
+ contentLayout,
+ alignOffset,
+ insets,
+ dimensions,
+ })
+ );
+}
diff --git a/apps/app/src/rnr/components/primitives/portal.tsx b/apps/app/src/rnr/components/primitives/portal.tsx
new file mode 100644
index 0000000..bd3ede8
--- /dev/null
+++ b/apps/app/src/rnr/components/primitives/portal.tsx
@@ -0,0 +1,82 @@
+import * as React from 'react';
+import { Platform, type View, type ViewStyle } from 'react-native';
+import { create } from 'zustand';
+
+const DEFAULT_PORTAL_HOST = 'INTERNAL_PRIMITIVE_DEFAULT_HOST_NAME';
+
+type PortalMap = Map;
+type PortalHostMap = Map;
+
+const usePortal = create<{ map: PortalHostMap }>(() => ({
+ map: new Map().set(DEFAULT_PORTAL_HOST, new Map()),
+}));
+
+const updatePortal = (hostName: string, name: string, children: React.ReactNode) => {
+ usePortal.setState((prev) => {
+ const next = new Map(prev.map);
+ const portal = next.get(hostName) ?? new Map();
+ portal.set(name, children);
+ next.set(hostName, portal);
+ return { map: next };
+ });
+};
+const removePortal = (hostName: string, name: string) => {
+ usePortal.setState((prev) => {
+ const next = new Map(prev.map);
+ const portal = next.get(hostName) ?? new Map();
+ portal.delete(name);
+ next.set(hostName, portal);
+ return { map: next };
+ });
+};
+
+export function PortalHost({ name = DEFAULT_PORTAL_HOST }: { name?: string }) {
+ const portalMap = usePortal((state) => state.map).get(name) ?? new Map();
+ if (portalMap.size === 0) return null;
+ return <>{Array.from(portalMap.values())}>;
+}
+
+export function Portal({
+ name,
+ hostName = DEFAULT_PORTAL_HOST,
+ children,
+}: {
+ name: string;
+ hostName?: string;
+ children: React.ReactNode;
+}) {
+ React.useEffect(() => {
+ updatePortal(hostName, name, children);
+ }, [hostName, name, children]);
+
+ React.useEffect(() => {
+ return () => {
+ removePortal(hostName, name);
+ };
+ }, [hostName, name]);
+
+ return null;
+}
+
+const ROOT: ViewStyle = {
+ flex: 1,
+};
+
+export function useModalPortalRoot() {
+ const ref = React.useRef(null);
+ const [sideOffset, setSideOffSet] = React.useState(0);
+
+ const onLayout = React.useCallback(() => {
+ if (Platform.OS === 'web') return;
+ ref.current?.measure((_x, _y, _width, _height, _pageX, pageY) => {
+ setSideOffSet(-pageY);
+ });
+ }, []);
+
+ return {
+ ref,
+ sideOffset,
+ onLayout,
+ style: ROOT,
+ };
+}
diff --git a/apps/app/src/rnr/components/ui/card.tsx b/apps/app/src/rnr/components/ui/card.tsx
new file mode 100644
index 0000000..f5a8fc2
--- /dev/null
+++ b/apps/app/src/rnr/components/ui/card.tsx
@@ -0,0 +1,67 @@
+import * as React from 'react';
+import { Text, View } from 'react-native';
+import { TextClassContext } from '~/components/ui/text';
+import { TextRef, ViewRef } from '~/components/primitives/types';
+import { cn } from '~/lib/utils';
+
+const Card = React.forwardRef>(
+ ({ className, ...props }, ref) => (
+
+ )
+);
+Card.displayName = 'Card';
+
+const CardHeader = React.forwardRef>(
+ ({ className, ...props }, ref) => (
+
+ )
+);
+CardHeader.displayName = 'CardHeader';
+
+const CardTitle = React.forwardRef>(
+ ({ className, ...props }, ref) => (
+
+ )
+);
+CardTitle.displayName = 'CardTitle';
+
+const CardDescription = React.forwardRef>(
+ ({ className, ...props }, ref) => (
+
+ )
+);
+CardDescription.displayName = 'CardDescription';
+
+const CardContent = React.forwardRef>(
+ ({ className, ...props }, ref) => (
+
+
+
+ )
+);
+CardContent.displayName = 'CardContent';
+
+const CardFooter = React.forwardRef>(
+ ({ className, ...props }, ref) => (
+
+ )
+);
+CardFooter.displayName = 'CardFooter';
+
+export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };
diff --git a/apps/app/src/rnr/lib/icons/AlertCircle.ts b/apps/app/src/rnr/lib/icons/AlertCircle.ts
new file mode 100644
index 0000000..adaaeeb
--- /dev/null
+++ b/apps/app/src/rnr/lib/icons/AlertCircle.ts
@@ -0,0 +1,4 @@
+import { AlertCircle } from "lucide-react-native";
+import { iconWithClassName } from "./iconWithClassName";
+iconWithClassName(AlertCircle);
+export { AlertCircle };
diff --git a/apps/app/src/utils/placeholder.test.ts b/apps/app/src/utils/placeholder.test.ts
new file mode 100644
index 0000000..7b75194
--- /dev/null
+++ b/apps/app/src/utils/placeholder.test.ts
@@ -0,0 +1,5 @@
+// just to make jest not fail
+
+test("placeholder", () => {
+ expect(true).toBe(true);
+});
diff --git a/apps/app/src/utils/trpc.ts b/apps/app/src/utils/trpc.ts
new file mode 100644
index 0000000..82e3bd1
--- /dev/null
+++ b/apps/app/src/utils/trpc.ts
@@ -0,0 +1,4 @@
+import { createTRPCReact } from "@trpc/react-query";
+import type { AppRouter } from "../../../server/src/index";
+
+export const trpc = createTRPCReact();
diff --git a/apps/app/tsconfig.json b/apps/app/tsconfig.json
index 944e43d..0475f57 100644
--- a/apps/app/tsconfig.json
+++ b/apps/app/tsconfig.json
@@ -2,15 +2,9 @@
"extends": "expo/tsconfig.base",
"compilerOptions": {
"strict": true,
- "baseUrl": ".",
"paths": {
- "~/*": [
- "src/rnr/*"
- ]
+ "~/*": ["./src/rnr/*"]
}
},
- "include": [
- "**/*.ts",
- "**/*.tsx"
- ]
+ "include": ["**/*.ts", "**/*.tsx"]
}
diff --git a/apps/server/package.json b/apps/server/package.json
index 5211f62..c8af82a 100644
--- a/apps/server/package.json
+++ b/apps/server/package.json
@@ -8,20 +8,22 @@
"build:deploy": "rm -rf build && pnpm deploy --filter=server --prod build",
"build": "pnpm run build:ts && pnpm build:deploy",
"start:prod": "PORT=$PORT NODE_ENV=production node ./dist/index.js",
- "ts:check": "tsc --noEmit"
+ "ts:check": "tsc --noEmit",
+ "test": "echo \"Error: no test specified\"",
+ "lint": "echo \"Lint not setup\" # eslint . --ext .ts,.tsx"
},
"dependencies": {
"@prisma/client": "5.14.0",
"@serenity-kit/opaque": "^0.8.4",
- "@trpc/server": "11.0.0-rc.366",
+ "@trpc/server": "^11.0.0-rc.382",
"cookie": "^0.6.0",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"isomorphic-ws": "^5.0.0",
- "secsync-server": "^0.4.0",
"secsync": "^0.4.0",
+ "secsync-server": "^0.4.0",
"ws": "^8.17.0",
"zod": "^3.23.8"
},
diff --git a/apps/server/src/db/getOrCreateDocument.ts b/apps/server/src/db/getDocumentData.ts
similarity index 83%
rename from apps/server/src/db/getOrCreateDocument.ts
rename to apps/server/src/db/getDocumentData.ts
index dcd7734..98713e5 100644
--- a/apps/server/src/db/getOrCreateDocument.ts
+++ b/apps/server/src/db/getDocumentData.ts
@@ -2,27 +2,18 @@ import { GetDocumentParams } from "secsync";
import { serializeSnapshot, serializeUpdates } from "../utils/serialize.js";
import { prisma } from "./prisma.js";
-export async function getOrCreateDocument({
+export async function getDocumentData({
documentId,
knownSnapshotId,
knownSnapshotUpdateClocks,
mode,
}: GetDocumentParams) {
return prisma.$transaction(async (prisma) => {
- const doc = await prisma.document.findUnique({
+ const doc = await prisma.document.findUniqueOrThrow({
where: { id: documentId },
include: { activeSnapshot: { select: { id: true } } },
});
- if (!doc) {
- await prisma.document.create({
- data: { id: documentId, name: "TODO" },
- });
- return {
- updates: [],
- snapshotProofChain: [],
- };
- }
if (!doc.activeSnapshot) {
return {
updates: [],
@@ -54,11 +45,11 @@ export async function getOrCreateDocument({
let lastKnownVersion: number | undefined = undefined;
// in case the last known snapshot is the current one, try to find the lastKnownVersion number
if (knownSnapshotId === doc.activeSnapshot.id) {
- const updateIds = Object.entries(knownSnapshotUpdateClocks).map(
- ([pubKey, clock]) => {
- return `${knownSnapshotId}-${pubKey}-${clock}`;
- }
- );
+ const updateIds = knownSnapshotUpdateClocks
+ ? Object.entries(knownSnapshotUpdateClocks).map(([pubKey, clock]) => {
+ return `${knownSnapshotId}-${pubKey}-${clock}`;
+ })
+ : [];
const lastUpdate = await prisma.update.findFirst({
where: {
id: { in: updateIds },
@@ -73,7 +64,7 @@ export async function getOrCreateDocument({
// fetch the active snapshot with
// - all updates after the last known version if there is one and
// - all updates if there is none
- const activeSnapshot = await prisma.snapshot.findUnique({
+ const activeSnapshot = await prisma.snapshot.findUniqueOrThrow({
where: { id: doc.activeSnapshot.id },
include: {
updates:
diff --git a/apps/server/src/index.ts b/apps/server/src/index.ts
index ba0f265..7b2b8ad 100755
--- a/apps/server/src/index.ts
+++ b/apps/server/src/index.ts
@@ -1,46 +1,18 @@
-import * as opaque from "@serenity-kit/opaque";
-import { TRPCError } from "@trpc/server";
import * as trpcExpress from "@trpc/server/adapters/express";
+import cookie from "cookie";
import cookieParser from "cookie-parser";
import cors, { CorsOptions } from "cors";
import "dotenv/config";
import express from "express";
-import { createWebSocketConnection } from "secsync-server";
import { WebSocketServer } from "ws";
-import { z } from "zod";
-import { addUserToDocument } from "./db/addUserToDocument.js";
-import { createDocument } from "./db/createDocument.js";
-import { createLoginAttempt } from "./db/createLoginAttempt.js";
-import { createOrRefreshDocumentInvitation } from "./db/createOrRefreshDocumentInvitation.js";
-import { createSession } from "./db/createSession.js";
import { createSnapshot } from "./db/createSnapshot.js";
import { createUpdate } from "./db/createUpdate.js";
-import { createUser } from "./db/createUser.js";
-import { deleteLoginAttempt } from "./db/deleteLoginAttempt.js";
-import { deleteSession } from "./db/deleteSession.js";
-import { getDocument } from "./db/getDocument.js";
-import { getDocumentInvitation } from "./db/getDocumentInvitation.js";
-import { getDocumentMembers } from "./db/getDocumentMembers.js";
-import { getDocumentsByUserId } from "./db/getDocumentsByUserId.js";
-import { getLoginAttempt } from "./db/getLoginAttempt.js";
-import { getOrCreateDocument } from "./db/getOrCreateDocument.js";
-import { getUser } from "./db/getUser.js";
-import { getUserByUsername } from "./db/getUserByUsername.js";
-import { updateDocument } from "./db/updateDocument.js";
-import {
- LoginFinishParams,
- LoginStartParams,
- RegisterFinishParams,
- RegisterStartParams,
-} from "./schema.js";
-import { generateId } from "./utils/generateId/generateId.js";
-import { getOpaqueServerSetup } from "./utils/getOpaqueServerSetup/getOpaqueServerSetup.js";
-import {
- createContext,
- protectedProcedure,
- publicProcedure,
- router,
-} from "./utils/trpc/trpc.js";
+import { getDocumentData } from "./db/getDocumentData.js";
+import { getSession } from "./db/getSession.js";
+import { getUserHasAccessToDocument } from "./db/getUserHasAccessToDocument.js";
+import { createWebSocketConnection } from "./secsync-server/createWebsocketConnection.js";
+import { appRouter } from "./trpc/appRouter.js";
+import { createContext } from "./utils/trpc/trpc.js";
const webSocketServer = new WebSocketServer({ noServer: true });
const PORT = process.env.PORT !== undefined ? parseInt(process.env.PORT) : 3030;
@@ -53,219 +25,12 @@ const corsOptions: CorsOptions = {
origin:
process.env.NODE_ENV === "production"
? "https://livelist.vercel.app"
- : "http://localhost:5173",
+ : "http://localhost:8081",
credentials: true,
};
app.use(cors(corsOptions));
-const appRouter = router({
- me: protectedProcedure.query(async (opts) => {
- const user = await getUser(opts.ctx.session.userId);
- if (!user) return null;
- return { id: user.id, username: user.username };
- }),
- documents: protectedProcedure.query(async (opts) => {
- const documents = await getDocumentsByUserId(opts.ctx.session.userId);
- return documents.map((doc) => ({ id: doc.id, name: doc.name }));
- }),
- getDocument: protectedProcedure.input(z.string()).query(async (opts) => {
- const document = await getDocument({
- documentId: opts.input,
- userId: opts.ctx.session.userId,
- });
- if (!document) return null;
- return {
- id: document.id,
- name: document.name,
- isAdmin: document.users.length > 0 ? document.users[0].isAdmin : false,
- };
- }),
- updateDocument: protectedProcedure
- .input(
- z.object({
- id: z.string(),
- name: z.string(),
- })
- )
- .mutation(async (opts) => {
- const updatedDocument = await updateDocument({
- documentId: opts.input.id,
- userId: opts.ctx.session.userId,
- name: opts.input.name,
- });
- return { id: updatedDocument.id, name: updatedDocument.name };
- }),
- createDocument: protectedProcedure
- .input(
- z.object({
- name: z.string(),
- })
- )
- .mutation(async (opts) => {
- const documentId = "TODO";
- const document = await createDocument({
- userId: opts.ctx.session.userId,
- documentId,
- name: opts.input.name,
- });
- return { document: { id: document.id, name: document.name } };
- }),
-
- createOrRefreshDocumentInvitation: protectedProcedure
- .input(
- z.object({
- documentId: z.string(),
- })
- )
- .mutation(async (opts) => {
- const documentInvitation = await createOrRefreshDocumentInvitation({
- userId: opts.ctx.session.userId,
- documentId: opts.input.documentId,
- });
- return documentInvitation ? { token: documentInvitation.token } : null;
- }),
-
- documentInvitation: protectedProcedure
- .input(z.string())
- .query(async (opts) => {
- const documentInvitation = await getDocumentInvitation({
- documentId: opts.input,
- userId: opts.ctx.session.userId,
- });
- if (!documentInvitation) return null;
- return { token: documentInvitation.token };
- }),
-
- acceptDocumentInvitation: protectedProcedure
- .input(
- z.object({
- token: z.string(),
- })
- )
- .mutation(async (opts) => {
- const result = await addUserToDocument({
- userId: opts.ctx.session.userId,
- documentInvitationToken: opts.input.token,
- });
- return result ? { documentId: result.documentId } : null;
- }),
-
- documentMembers: protectedProcedure.input(z.string()).query(async (opts) => {
- const members = await getDocumentMembers({
- documentId: opts.input,
- userId: opts.ctx.session.userId,
- });
- return members;
- }),
-
- logout: protectedProcedure.mutation(async (opts) => {
- await deleteSession(opts.ctx.session.token);
- opts.ctx.clearCookie();
- }),
-
- registerStart: publicProcedure
- .input(RegisterStartParams)
- .mutation(async (opts) => {
- const { userIdentifier, registrationRequest } = opts.input;
-
- const user = await getUserByUsername(userIdentifier);
- if (user) {
- throw new TRPCError({
- code: "BAD_REQUEST",
- message: "user already registered",
- });
- }
-
- const { registrationResponse } = opaque.server.createRegistrationResponse(
- {
- serverSetup: getOpaqueServerSetup(),
- userIdentifier,
- registrationRequest,
- }
- );
-
- return { registrationResponse };
- }),
-
- registerFinish: publicProcedure
- .input(RegisterFinishParams)
- .mutation(async (opts) => {
- const { userIdentifier, registrationRecord } = opts.input;
-
- const existingUser = await getUserByUsername(userIdentifier);
- if (!existingUser) {
- await createUser({ username: userIdentifier, registrationRecord });
- }
-
- // return always the same result even if the user already exists to
- // avoid leaking the information if the user exists or not
- return;
- }),
-
- loginStart: publicProcedure.input(LoginStartParams).mutation(async (opts) => {
- const { userIdentifier, startLoginRequest } = opts.input;
-
- const user = await getUserByUsername(userIdentifier);
- if (!user)
- throw new TRPCError({
- code: "BAD_REQUEST",
- message: "user not registered",
- });
- const { registrationRecord, id: userId } = user;
-
- const loginAttempt = await getLoginAttempt(userIdentifier);
- if (loginAttempt) {
- throw new TRPCError({
- code: "BAD_REQUEST",
- message: "login already started",
- });
- }
-
- const { serverLoginState, loginResponse } = opaque.server.startLogin({
- serverSetup: getOpaqueServerSetup(),
- userIdentifier,
- registrationRecord,
- startLoginRequest,
- });
-
- await createLoginAttempt({ userId, serverLoginState });
-
- return { loginResponse };
- }),
- loginFinish: publicProcedure
- .input(LoginFinishParams)
- .mutation(async (opts) => {
- const { userIdentifier, finishLoginRequest } = opts.input;
-
- const loginAttempt = await getLoginAttempt(userIdentifier);
- if (!loginAttempt || !loginAttempt.serverLoginState)
- throw new TRPCError({
- code: "BAD_REQUEST",
- message: "login not started",
- });
- const { serverLoginState } = loginAttempt;
- const { sessionKey } = opaque.server.finishLogin({
- finishLoginRequest,
- serverLoginState,
- });
-
- const sessionToken = generateId(32);
- const user = await getUserByUsername(userIdentifier);
- if (!user) {
- throw new TRPCError({
- code: "INTERNAL_SERVER_ERROR",
- message: "user not found",
- });
- }
- await createSession({ token: sessionToken, sessionKey, userId: user.id });
- await deleteLoginAttempt(user.id);
-
- opts.ctx.setSessionCookie(sessionToken);
- return { success: true };
- }),
-});
-
export type AppRouter = typeof appRouter;
app.use(
@@ -287,11 +52,17 @@ const server = app.listen(PORT, () => {
webSocketServer.on(
"connection",
createWebSocketConnection({
- getDocument: getOrCreateDocument,
+ getDocument: getDocumentData,
createSnapshot: createSnapshot,
createUpdate: createUpdate,
- hasAccess: async () => true,
- hasBroadcastAccess: async ({ websocketSessionKeys }) =>
+ // @ts-expect-error
+ hasAccess: async ({ documentId, websocketSessionKey, connection }) => {
+ return getUserHasAccessToDocument({
+ documentId,
+ userId: connection.session.userId,
+ });
+ },
+ hasBroadcastAccess: async ({ documentId, websocketSessionKeys }) =>
websocketSessionKeys.map(() => true),
logging: "error",
})
@@ -299,23 +70,23 @@ webSocketServer.on(
server.on("upgrade", async (request, socket, head) => {
// validating the session
- // const cookies = cookie.parse(request.headers.cookie || "");
- // const sessionToken = cookies.session;
- // if (!sessionToken) {
- // socket.write("HTTP/1.1 401 Unauthorized\r\n\r\n");
- // socket.destroy();
- // return;
- // }
- // const session = await getSession(sessionToken);
- // if (!session) {
- // socket.write("HTTP/1.1 401 Unauthorized\r\n\r\n");
- // socket.destroy();
- // return;
- // }
+ const cookies = cookie.parse(request.headers.cookie || "");
+ const sessionToken = cookies.session;
+ if (!sessionToken) {
+ socket.write("HTTP/1.1 401 Unauthorized\r\n\r\n");
+ socket.destroy();
+ return;
+ }
+ const session = await getSession(sessionToken);
+ if (!session) {
+ socket.write("HTTP/1.1 401 Unauthorized\r\n\r\n");
+ socket.destroy();
+ return;
+ }
webSocketServer.handleUpgrade(request, socket, head, (currentSocket) => {
- // currentSocket.session = session;
-
+ // @ts-expect-error adding the session to the socket so we can access it in the network adapter
+ currentSocket.session = session;
webSocketServer.emit("connection", currentSocket, request);
});
});
diff --git a/apps/server/src/secsync-server/createWebsocketConnection.ts b/apps/server/src/secsync-server/createWebsocketConnection.ts
new file mode 100644
index 0000000..4533b52
--- /dev/null
+++ b/apps/server/src/secsync-server/createWebsocketConnection.ts
@@ -0,0 +1,454 @@
+import { IncomingMessage } from "http";
+import sodium from "libsodium-wrappers";
+import {
+ AdditionalAuthenticationDataValidations,
+ CreateSnapshotParams,
+ CreateUpdateParams,
+ GetDocumentParams,
+ HasAccessParams,
+ HasBroadcastAccessParams,
+ SecsyncNewSnapshotRequiredError,
+ SecsyncSnapshotBasedOnOutdatedSnapshotError,
+ SecsyncSnapshotMissesUpdatesError,
+ Snapshot,
+ SnapshotProofChainEntry,
+ SnapshotUpdateClocks,
+ Update,
+ parseEphemeralMessage,
+ parseSnapshotWithClientData,
+ parseUpdate,
+ verifySignature,
+} from "secsync";
+import { parse as parseUrl } from "url";
+import { WebSocket } from "ws";
+import { addConnection, broadcastMessage, removeConnection } from "./store.js";
+import { canonicalizeAndToBase64 } from "./utils/canonicalizeAndToBase64.js";
+import { retryAsyncFunction } from "./utils/retryAsyncFunction.js";
+
+type GetDocumentResult = {
+ snapshot?: Snapshot;
+ snapshotProofChain?: SnapshotProofChainEntry[];
+ updates: Update[];
+};
+
+type WebsocketConnectionParams = {
+ getDocument(
+ getDocumentParams: GetDocumentParams
+ ): Promise;
+ createSnapshot(createSnapshotParams: CreateSnapshotParams): Promise;
+ createUpdate(createUpdateParams: CreateUpdateParams): Promise;
+ hasAccess(hasAccessParams: HasAccessParams): Promise;
+ hasBroadcastAccess(
+ hasBroadcastAccessParams: HasBroadcastAccessParams
+ ): Promise;
+ additionalAuthenticationDataValidations?: AdditionalAuthenticationDataValidations;
+ /** default: "off" */
+ logging?: "off" | "error";
+};
+
+export const createWebSocketConnection =
+ ({
+ getDocument,
+ createSnapshot,
+ createUpdate,
+ hasAccess,
+ hasBroadcastAccess,
+ additionalAuthenticationDataValidations,
+ logging: loggingParam,
+ }: WebsocketConnectionParams) =>
+ async (connection: WebSocket, request: IncomingMessage) => {
+ const logging = loggingParam || "off";
+ let documentId = "";
+
+ const handleDocumentError = () => {
+ connection.send(JSON.stringify({ type: "document-error" }));
+ connection.close();
+ removeConnection({
+ documentId,
+ websocket: connection,
+ });
+ };
+
+ try {
+ if (request.url === undefined) {
+ handleDocumentError();
+ return;
+ }
+ const urlParts = parseUrl(request.url, true);
+ documentId = request.url?.slice(1)?.split("?")[0] || "";
+
+ const websocketSessionKey = Array.isArray(urlParts.query.sessionKey)
+ ? urlParts.query.sessionKey[0]
+ : urlParts.query.sessionKey;
+
+ // invalid connection without a sessionKey
+ if (websocketSessionKey === undefined) {
+ handleDocumentError();
+ return;
+ }
+
+ const getDocumentModeString = Array.isArray(urlParts.query.mode)
+ ? urlParts.query.mode[0]
+ : urlParts.query.mode;
+ const getDocumentMode =
+ getDocumentModeString === "delta" ? "delta" : "complete";
+
+ if (documentId === "") {
+ handleDocumentError();
+ return;
+ }
+
+ const documentAccess = await hasAccess({
+ action: "read",
+ documentId,
+ websocketSessionKey,
+ // @ts-expect-error
+ connection,
+ });
+ if (!documentAccess) {
+ connection.send(JSON.stringify({ type: "unauthorized" }));
+ connection.close();
+ return;
+ }
+
+ let knownSnapshotUpdateClocks: SnapshotUpdateClocks | undefined =
+ undefined;
+ try {
+ const knownSnapshotUpdateClocksQueryEntry = Array.isArray(
+ urlParts.query.knownSnapshotUpdateClocks
+ )
+ ? urlParts.query.knownSnapshotUpdateClocks[0]
+ : urlParts.query.knownSnapshotUpdateClocks;
+ if (knownSnapshotUpdateClocksQueryEntry) {
+ knownSnapshotUpdateClocks = SnapshotUpdateClocks.parse(
+ JSON.parse(decodeURIComponent(knownSnapshotUpdateClocksQueryEntry))
+ );
+ }
+ } catch (err) {}
+
+ const doc = await getDocument({
+ documentId,
+ knownSnapshotId: Array.isArray(urlParts.query.knownSnapshotId)
+ ? urlParts.query.knownSnapshotId[0]
+ : urlParts.query.knownSnapshotId,
+ knownSnapshotUpdateClocks,
+ mode: getDocumentMode,
+ });
+
+ if (!doc) {
+ connection.send(JSON.stringify({ type: "document-not-found" }));
+ connection.close();
+ return;
+ }
+
+ addConnection({ documentId, websocket: connection, websocketSessionKey });
+ connection.send(JSON.stringify({ type: "document", ...doc }));
+
+ connection.on("message", async function message(messageContent) {
+ const data = JSON.parse(messageContent.toString());
+
+ // new snapshot
+ if (data?.publicData?.snapshotId) {
+ try {
+ const snapshotMessage = parseSnapshotWithClientData(
+ data,
+ additionalAuthenticationDataValidations?.snapshot
+ );
+
+ const documentAccess = await hasAccess({
+ action: "write-snapshot",
+ documentId,
+ publicKey: snapshotMessage.publicData.pubKey,
+ websocketSessionKey,
+ // @ts-expect-error
+ connection,
+ });
+ if (!documentAccess) {
+ connection.send(JSON.stringify({ type: "unauthorized" }));
+ connection.close();
+ return;
+ }
+
+ const snapshotPublicKey = sodium.from_base64(
+ snapshotMessage.publicData.pubKey
+ );
+ const snapshotPublicDataAsBase64 = canonicalizeAndToBase64(
+ snapshotMessage.publicData,
+ sodium
+ );
+ const isValid = verifySignature(
+ {
+ nonce: snapshotMessage.nonce,
+ ciphertext: snapshotMessage.ciphertext,
+ publicData: snapshotPublicDataAsBase64,
+ },
+ "secsync_snapshot",
+ snapshotMessage.signature,
+ snapshotPublicKey,
+ sodium
+ );
+ if (!isValid) {
+ throw new Error("Snapshot message signature is not valid.");
+ }
+
+ const snapshot: Snapshot = await createSnapshot({
+ snapshot: snapshotMessage,
+ });
+ connection.send(
+ JSON.stringify({
+ type: "snapshot-saved",
+ snapshotId: snapshot.publicData.snapshotId,
+ })
+ );
+ const snapshotMsgForOtherClients: Snapshot = {
+ ciphertext: snapshotMessage.ciphertext,
+ nonce: snapshotMessage.nonce,
+ publicData: snapshotMessage.publicData,
+ signature: snapshotMessage.signature,
+ };
+ broadcastMessage({
+ documentId,
+ message: {
+ type: "snapshot",
+ snapshot: snapshotMsgForOtherClients,
+ },
+ currentWebsocket: connection,
+ hasBroadcastAccess,
+ });
+ } catch (error) {
+ if (logging === "error") {
+ console.error("SNAPSHOT FAILED ERROR:", error, data);
+ }
+ try {
+ if (
+ error instanceof SecsyncSnapshotBasedOnOutdatedSnapshotError
+ ) {
+ let document = await getDocument({
+ documentId,
+ knownSnapshotId: data.knownSnapshotId,
+ mode: "delta",
+ });
+ if (document) {
+ connection.send(
+ JSON.stringify({
+ type: "snapshot-save-failed",
+ snapshot: document.snapshot,
+ updates: document.updates,
+ snapshotProofChain: document.snapshotProofChain,
+ })
+ );
+ } else {
+ if (logging === "error") {
+ console.error(
+ 'document not found for "snapshotBasedOnOutdatedSnapshot" error'
+ );
+ }
+ connection.send(
+ JSON.stringify({
+ type: "snapshot-save-failed",
+ })
+ );
+ }
+ } else if (error instanceof SecsyncSnapshotMissesUpdatesError) {
+ const document = await getDocument({
+ documentId,
+ knownSnapshotId: data.knownSnapshotId,
+ mode: "delta",
+ });
+ if (document) {
+ connection.send(
+ JSON.stringify({
+ type: "snapshot-save-failed",
+ updates: document.updates,
+ })
+ );
+ } else {
+ // log since it's an unexpected error
+ if (logging === "error") {
+ console.error(
+ 'document not found for "snapshotMissesUpdates" error'
+ );
+ }
+ connection.send(
+ JSON.stringify({
+ type: "snapshot-save-failed",
+ })
+ );
+ }
+ } else if (error instanceof SecsyncNewSnapshotRequiredError) {
+ connection.send(
+ JSON.stringify({
+ type: "snapshot-save-failed",
+ })
+ );
+ } else {
+ connection.send(
+ JSON.stringify({
+ type: "snapshot-save-failed",
+ })
+ );
+ }
+ } catch (err) {
+ // log since it's an unexpected error
+ if (logging === "error") {
+ console.error("SNAPSHOT FAILED ERROR HANDLING FAILED:", err);
+ }
+ connection.send(
+ JSON.stringify({
+ type: "snapshot-save-failed",
+ })
+ );
+ }
+ }
+ // new update
+ } else if (data?.publicData?.refSnapshotId) {
+ let savedUpdate: undefined | Update = undefined;
+ try {
+ const updateMessage = parseUpdate(
+ data,
+ additionalAuthenticationDataValidations?.update
+ );
+
+ const documentAccess = await hasAccess({
+ action: "write-update",
+ documentId,
+ publicKey: updateMessage.publicData.pubKey,
+ websocketSessionKey,
+ // @ts-expect-error
+ connection,
+ });
+ if (!documentAccess) {
+ connection.send(JSON.stringify({ type: "unauthorized" }));
+ connection.close();
+ return;
+ }
+
+ const isValid = verifySignature(
+ {
+ nonce: updateMessage.nonce,
+ ciphertext: updateMessage.ciphertext,
+ publicData: canonicalizeAndToBase64(
+ updateMessage.publicData,
+ sodium
+ ),
+ },
+ "secsync_update",
+ updateMessage.signature,
+ sodium.from_base64(updateMessage.publicData.pubKey),
+ sodium
+ );
+ if (!isValid) {
+ throw new Error("Update message signature is not valid.");
+ }
+ // const random = Math.floor(Math.random() * 10);
+ // if (random < 8) {
+ // throw new Error("CUSTOM ERROR");
+ // }
+
+ savedUpdate = await retryAsyncFunction(
+ () =>
+ createUpdate({
+ update: updateMessage,
+ }),
+ [SecsyncNewSnapshotRequiredError]
+ );
+ if (savedUpdate === undefined) {
+ throw new Error("Update could not be saved.");
+ }
+
+ connection.send(
+ JSON.stringify({
+ type: "update-saved",
+ snapshotId: savedUpdate.publicData.refSnapshotId,
+ clock: savedUpdate.publicData.clock,
+ })
+ );
+ broadcastMessage({
+ documentId,
+ message: { ...savedUpdate, type: "update" },
+ currentWebsocket: connection,
+ hasBroadcastAccess,
+ });
+ } catch (err) {
+ if (logging === "error") {
+ console.error("update failed", err);
+ }
+ if (savedUpdate === null || savedUpdate === undefined) {
+ connection.send(
+ JSON.stringify({
+ type: "update-save-failed",
+ snapshotId: data.publicData.refSnapshotId,
+ clock: data.publicData.clock,
+ requiresNewSnapshot:
+ err instanceof SecsyncNewSnapshotRequiredError,
+ })
+ );
+ }
+ }
+ // new ephemeral message
+ } else {
+ try {
+ const ephemeralMessageMessage = parseEphemeralMessage(
+ data,
+ additionalAuthenticationDataValidations?.ephemeralMessage
+ );
+
+ const documentAccess = await hasAccess({
+ action: "send-ephemeral-message",
+ documentId,
+ publicKey: ephemeralMessageMessage.publicData.pubKey,
+ websocketSessionKey,
+ // @ts-expect-error
+ connection,
+ });
+ if (!documentAccess) {
+ connection.send(JSON.stringify({ type: "unauthorized" }));
+ connection.close();
+ return;
+ }
+
+ const isValid = verifySignature(
+ {
+ nonce: ephemeralMessageMessage.nonce,
+ ciphertext: ephemeralMessageMessage.ciphertext,
+ publicData: canonicalizeAndToBase64(
+ ephemeralMessageMessage.publicData,
+ sodium
+ ),
+ },
+ "secsync_ephemeral_message",
+ ephemeralMessageMessage.signature,
+ sodium.from_base64(ephemeralMessageMessage.publicData.pubKey),
+ sodium
+ );
+ if (!isValid) {
+ return {
+ error: new Error("SECSYNC_ERROR_308"),
+ };
+ }
+
+ broadcastMessage({
+ documentId,
+ message: {
+ ...ephemeralMessageMessage,
+ type: "ephemeral-message",
+ },
+ currentWebsocket: connection,
+ hasBroadcastAccess,
+ });
+ } catch (err) {
+ console.error("Ephemeral message failed due:", err);
+ }
+ }
+ });
+
+ connection.on("close", function () {
+ removeConnection({ documentId, websocket: connection });
+ });
+ } catch (error) {
+ if (logging === "error") {
+ console.error(error);
+ }
+ handleDocumentError();
+ }
+ };
diff --git a/apps/server/src/secsync-server/store.ts b/apps/server/src/secsync-server/store.ts
new file mode 100644
index 0000000..2973a25
--- /dev/null
+++ b/apps/server/src/secsync-server/store.ts
@@ -0,0 +1,94 @@
+import { HasBroadcastAccessParams } from "secsync";
+import WebSocket from "ws";
+
+type ConnectionEntry = { websocketSessionKey: string; websocket: WebSocket };
+
+const documents: { [key: string]: ConnectionEntry[] } = {};
+const messageQueues: { [key: string]: BroadcastMessageParams[] } = {};
+
+export type BroadcastMessageParams = {
+ documentId: string;
+ message: any;
+ currentWebsocket: any;
+ hasBroadcastAccess: (params: HasBroadcastAccessParams) => Promise;
+};
+
+export const broadcastMessage = async (params: BroadcastMessageParams) => {
+ const { documentId } = params;
+
+ if (!messageQueues[documentId]) {
+ messageQueues[documentId] = [];
+ }
+
+ messageQueues[documentId].push(params);
+
+ // only start processing if this is the only message in the queue to avoid overlapping calls
+ if (messageQueues[documentId].length === 1) {
+ processMessageQueue(documentId);
+ }
+};
+
+const processMessageQueue = async (documentId: string) => {
+ if (!documents[documentId] || messageQueues[documentId].length === 0) return;
+
+ const { hasBroadcastAccess } = messageQueues[documentId][0];
+
+ const websocketSessionKeys = documents[documentId].map(
+ ({ websocketSessionKey }) => websocketSessionKey
+ );
+
+ const accessResults = await hasBroadcastAccess({
+ documentId,
+ websocketSessionKeys,
+ });
+
+ documents[documentId] = documents[documentId].filter(
+ (_, index) => accessResults[index]
+ );
+
+ // Send all the messages in the queue to the allowed connections
+ messageQueues[documentId].forEach(({ message, currentWebsocket }) => {
+ documents[documentId].forEach(({ websocket }) => {
+ if (websocket !== currentWebsocket) {
+ websocket.send(JSON.stringify(message));
+ }
+ });
+ });
+
+ // clear the message queue after it's broadcasted
+ messageQueues[documentId] = [];
+};
+
+export type AddConnectionParams = {
+ documentId: string;
+ websocket: WebSocket;
+ websocketSessionKey: string;
+};
+
+export const addConnection = ({
+ documentId,
+ websocket,
+ websocketSessionKey,
+}: AddConnectionParams) => {
+ if (documents[documentId]) {
+ documents[documentId].push({ websocket, websocketSessionKey });
+ } else {
+ documents[documentId] = [{ websocket, websocketSessionKey }];
+ }
+};
+
+export type RemoveConnectionParams = {
+ documentId: string;
+ websocket: WebSocket;
+};
+
+export const removeConnection = ({
+ documentId,
+ websocket: currentWebsocket,
+}: RemoveConnectionParams) => {
+ if (documents[documentId]) {
+ documents[documentId] = documents[documentId].filter(
+ ({ websocket }) => websocket !== currentWebsocket
+ );
+ }
+};
diff --git a/apps/server/src/secsync-server/utils/canonicalizeAndToBase64.ts b/apps/server/src/secsync-server/utils/canonicalizeAndToBase64.ts
new file mode 100644
index 0000000..f20baf6
--- /dev/null
+++ b/apps/server/src/secsync-server/utils/canonicalizeAndToBase64.ts
@@ -0,0 +1,12 @@
+import canonicalize from "canonicalize";
+
+export const canonicalizeAndToBase64 = (
+ input: unknown,
+ sodium: typeof import("libsodium-wrappers")
+): string => {
+ const canonicalized = canonicalize(input);
+ if (!canonicalized) {
+ throw new Error("Failed to canonicalize input");
+ }
+ return sodium.to_base64(canonicalized);
+};
diff --git a/apps/server/src/secsync-server/utils/retryAsyncFunction.ts b/apps/server/src/secsync-server/utils/retryAsyncFunction.ts
new file mode 100644
index 0000000..93030d2
--- /dev/null
+++ b/apps/server/src/secsync-server/utils/retryAsyncFunction.ts
@@ -0,0 +1,31 @@
+export async function retryAsyncFunction(
+ asyncFunction: () => Promise,
+ errorsToBailOn: any[] = [],
+ maxRetries: number = 5
+): Promise {
+ let delay = 100;
+ let retries = 0;
+
+ while (retries < maxRetries) {
+ try {
+ return await asyncFunction();
+ } catch (err) {
+ // if the error message is in the errorsToBailOn array, throw the error immediately
+ for (const error of errorsToBailOn) {
+ if (err instanceof error) {
+ throw err;
+ }
+ }
+ // increase retries count
+ retries += 1;
+ // ff the retries exceed maxRetries, throw the last error
+ if (retries >= maxRetries) {
+ throw err;
+ }
+ // wait for a delay before retrying the function
+ await new Promise((resolve) => setTimeout(resolve, delay));
+ // double the delay value
+ delay *= 2;
+ }
+ }
+}
diff --git a/apps/server/src/trpc/appRouter.ts b/apps/server/src/trpc/appRouter.ts
new file mode 100644
index 0000000..c47e9eb
--- /dev/null
+++ b/apps/server/src/trpc/appRouter.ts
@@ -0,0 +1,240 @@
+import * as opaque from "@serenity-kit/opaque";
+import { TRPCError } from "@trpc/server";
+import "dotenv/config";
+import { z } from "zod";
+import { addUserToDocument } from "../db/addUserToDocument.js";
+import { createDocument } from "../db/createDocument.js";
+import { createLoginAttempt } from "../db/createLoginAttempt.js";
+import { createOrRefreshDocumentInvitation } from "../db/createOrRefreshDocumentInvitation.js";
+import { createSession } from "../db/createSession.js";
+import { createUser } from "../db/createUser.js";
+import { deleteLoginAttempt } from "../db/deleteLoginAttempt.js";
+import { deleteSession } from "../db/deleteSession.js";
+import { getDocument } from "../db/getDocument.js";
+import { getDocumentInvitation } from "../db/getDocumentInvitation.js";
+import { getDocumentMembers } from "../db/getDocumentMembers.js";
+import { getDocumentsByUserId } from "../db/getDocumentsByUserId.js";
+import { getLoginAttempt } from "../db/getLoginAttempt.js";
+import { getUser } from "../db/getUser.js";
+import { getUserByUsername } from "../db/getUserByUsername.js";
+import { updateDocument } from "../db/updateDocument.js";
+import {
+ LoginFinishParams,
+ LoginStartParams,
+ RegisterFinishParams,
+ RegisterStartParams,
+} from "../schema.js";
+import { generateId } from "../utils/generateId/generateId.js";
+import { getOpaqueServerSetup } from "../utils/getOpaqueServerSetup/getOpaqueServerSetup.js";
+import {
+ protectedProcedure,
+ publicProcedure,
+ router,
+} from "../utils/trpc/trpc.js";
+
+export const appRouter = router({
+ me: protectedProcedure.query(async (opts) => {
+ const user = await getUser(opts.ctx.session.userId);
+ if (!user) return null;
+ return { id: user.id, username: user.username };
+ }),
+ documents: protectedProcedure.query(async (opts) => {
+ const documents = await getDocumentsByUserId(opts.ctx.session.userId);
+ return documents.map((doc) => ({ id: doc.id, name: doc.name }));
+ }),
+ getDocument: protectedProcedure.input(z.string()).query(async (opts) => {
+ const document = await getDocument({
+ documentId: opts.input,
+ userId: opts.ctx.session.userId,
+ });
+ if (!document) return null;
+ return {
+ id: document.id,
+ name: document.name,
+ isAdmin: document.users.length > 0 ? document.users[0].isAdmin : false,
+ };
+ }),
+ updateDocument: protectedProcedure
+ .input(
+ z.object({
+ id: z.string(),
+ name: z.string(),
+ })
+ )
+ .mutation(async (opts) => {
+ const updatedDocument = await updateDocument({
+ documentId: opts.input.id,
+ userId: opts.ctx.session.userId,
+ name: opts.input.name,
+ });
+ return { id: updatedDocument.id, name: updatedDocument.name };
+ }),
+ createDocument: protectedProcedure
+ .input(
+ z.object({
+ name: z.string(),
+ })
+ )
+ .mutation(async (opts) => {
+ const documentId = generateId();
+ const document = await createDocument({
+ userId: opts.ctx.session.userId,
+ documentId,
+ name: opts.input.name,
+ });
+ return { document: { id: document.id, name: document.name } };
+ }),
+
+ createOrRefreshDocumentInvitation: protectedProcedure
+ .input(
+ z.object({
+ documentId: z.string(),
+ })
+ )
+ .mutation(async (opts) => {
+ const documentInvitation = await createOrRefreshDocumentInvitation({
+ userId: opts.ctx.session.userId,
+ documentId: opts.input.documentId,
+ });
+ return documentInvitation ? { token: documentInvitation.token } : null;
+ }),
+
+ documentInvitation: protectedProcedure
+ .input(z.string())
+ .query(async (opts) => {
+ const documentInvitation = await getDocumentInvitation({
+ documentId: opts.input,
+ userId: opts.ctx.session.userId,
+ });
+ if (!documentInvitation) return null;
+ return { token: documentInvitation.token };
+ }),
+
+ acceptDocumentInvitation: protectedProcedure
+ .input(
+ z.object({
+ token: z.string(),
+ })
+ )
+ .mutation(async (opts) => {
+ const result = await addUserToDocument({
+ userId: opts.ctx.session.userId,
+ documentInvitationToken: opts.input.token,
+ });
+ return result ? { documentId: result.documentId } : null;
+ }),
+
+ documentMembers: protectedProcedure.input(z.string()).query(async (opts) => {
+ const members = await getDocumentMembers({
+ documentId: opts.input,
+ userId: opts.ctx.session.userId,
+ });
+ return members;
+ }),
+
+ logout: protectedProcedure.mutation(async (opts) => {
+ await deleteSession(opts.ctx.session.token);
+ opts.ctx.clearCookie();
+ }),
+
+ registerStart: publicProcedure
+ .input(RegisterStartParams)
+ .mutation(async (opts) => {
+ const { userIdentifier, registrationRequest } = opts.input;
+
+ const user = await getUserByUsername(userIdentifier);
+ if (user) {
+ throw new TRPCError({
+ code: "BAD_REQUEST",
+ message: "user already registered",
+ });
+ }
+
+ const { registrationResponse } = opaque.server.createRegistrationResponse(
+ {
+ serverSetup: getOpaqueServerSetup(),
+ userIdentifier,
+ registrationRequest,
+ }
+ );
+
+ return { registrationResponse };
+ }),
+
+ registerFinish: publicProcedure
+ .input(RegisterFinishParams)
+ .mutation(async (opts) => {
+ const { userIdentifier, registrationRecord } = opts.input;
+
+ const existingUser = await getUserByUsername(userIdentifier);
+ if (!existingUser) {
+ await createUser({ username: userIdentifier, registrationRecord });
+ }
+
+ // return always the same result even if the user already exists to
+ // avoid leaking the information if the user exists or not
+ return;
+ }),
+
+ loginStart: publicProcedure.input(LoginStartParams).mutation(async (opts) => {
+ const { userIdentifier, startLoginRequest } = opts.input;
+
+ const user = await getUserByUsername(userIdentifier);
+ if (!user)
+ throw new TRPCError({
+ code: "BAD_REQUEST",
+ message: "user not registered",
+ });
+ const { registrationRecord, id: userId } = user;
+
+ const loginAttempt = await getLoginAttempt(userIdentifier);
+ if (loginAttempt) {
+ throw new TRPCError({
+ code: "BAD_REQUEST",
+ message: "login already started",
+ });
+ }
+
+ const { serverLoginState, loginResponse } = opaque.server.startLogin({
+ serverSetup: getOpaqueServerSetup(),
+ userIdentifier,
+ registrationRecord,
+ startLoginRequest,
+ });
+
+ await createLoginAttempt({ userId, serverLoginState });
+
+ return { loginResponse };
+ }),
+ loginFinish: publicProcedure
+ .input(LoginFinishParams)
+ .mutation(async (opts) => {
+ const { userIdentifier, finishLoginRequest } = opts.input;
+
+ const loginAttempt = await getLoginAttempt(userIdentifier);
+ if (!loginAttempt || !loginAttempt.serverLoginState)
+ throw new TRPCError({
+ code: "BAD_REQUEST",
+ message: "login not started",
+ });
+ const { serverLoginState } = loginAttempt;
+ const { sessionKey } = opaque.server.finishLogin({
+ finishLoginRequest,
+ serverLoginState,
+ });
+
+ const sessionToken = generateId(32);
+ const user = await getUserByUsername(userIdentifier);
+ if (!user) {
+ throw new TRPCError({
+ code: "INTERNAL_SERVER_ERROR",
+ message: "user not found",
+ });
+ }
+ await createSession({ token: sessionToken, sessionKey, userId: user.id });
+ await deleteLoginAttempt(user.id);
+
+ opts.ctx.setSessionCookie(sessionToken);
+ return { success: true };
+ }),
+});
diff --git a/apps/server/src/utils/generateId/generateId.test.ts b/apps/server/src/utils/generateId/generateId.test.ts
new file mode 100644
index 0000000..5338459
--- /dev/null
+++ b/apps/server/src/utils/generateId/generateId.test.ts
@@ -0,0 +1,8 @@
+import { generateId } from "./generateId";
+
+// test for generateId
+test("should generate a unique id", () => {
+ const id1 = generateId();
+ const id2 = generateId();
+ expect(id1).not.toBe(id2);
+});
diff --git a/apps/server/src/utils/generateId/generateId.ts b/apps/server/src/utils/generateId/generateId.ts
index ed8bb47..988a539 100644
--- a/apps/server/src/utils/generateId/generateId.ts
+++ b/apps/server/src/utils/generateId/generateId.ts
@@ -1,3 +1,4 @@
+// @ts-ignore
const { randomBytes } = await import("node:crypto");
export const generateId = (length = 16) => {
diff --git a/apps/server/tsconfig.json b/apps/server/tsconfig.json
index 300eb56..ff30506 100644
--- a/apps/server/tsconfig.json
+++ b/apps/server/tsconfig.json
@@ -9,7 +9,7 @@
"noEmit": false,
"outDir": "dist",
"lib": ["esnext"],
- "types": ["node"],
+ "types": ["node", "jest"],
"baseUrl": "./",
"strict": true
},
diff --git a/yarn.lock b/yarn.lock
index 5ffebd3..1a27065 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -40,7 +40,7 @@
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.6.tgz#b3600217688cabb26e25f8e467019e66d71b7ae2"
integrity sha512-aC2DGhBq5eEdyXWqrDInSqQjO0k8xtPRf5YylULqx8MCd6jBtzqfta/3ETMRpuKIc5hyswfO80ObyA1MvkCcUQ==
-"@babel/core@^7.13.16", "@babel/core@^7.20.0", "@babel/core@^7.24.3":
+"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.13.16", "@babel/core@^7.20.0", "@babel/core@^7.23.9":
version "7.24.6"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.6.tgz#8650e0e4b03589ebe886c4e4a60398db0a7ec787"
integrity sha512-qAHSfAdVyFmIvl0VHELib8xar7ONuSHrE2hLnsaWkYNTI68dmi1x8GYDhJjMI/e7XWal9QBlZkwbOnkcw7Z8gQ==
@@ -61,7 +61,7 @@
json5 "^2.2.3"
semver "^6.3.1"
-"@babel/generator@^7.20.0", "@babel/generator@^7.20.5", "@babel/generator@^7.24.6":
+"@babel/generator@^7.20.0", "@babel/generator@^7.20.5", "@babel/generator@^7.24.6", "@babel/generator@^7.7.2":
version "7.24.6"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.6.tgz#dfac82a228582a9d30c959fe50ad28951d4737a7"
integrity sha512-S7m4eNa6YAPJRHmKsLHIDJhNAGNKoWNiWefz1MBbpnt8g9lvMDl1hir4P9bo/57bQEmuwEhnRU/AMWsD0G/Fbg==
@@ -176,7 +176,7 @@
dependencies:
"@babel/types" "^7.24.6"
-"@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.24.6", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
+"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.24.6", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
version "7.24.6"
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.6.tgz#fa02a32410a15a6e8f8185bcbf608f10528d2a24"
integrity sha512-MZG/JcWfxybKwsA9N9PmtF2lOSFSEMVCpIRrbxccZFLJPrJciJdG/UhSh5W96GEteJI2ARqm5UAHxISwRDLSNg==
@@ -262,7 +262,7 @@
js-tokens "^4.0.0"
picocolors "^1.0.0"
-"@babel/parser@^7.1.0", "@babel/parser@^7.13.16", "@babel/parser@^7.20.0", "@babel/parser@^7.20.7", "@babel/parser@^7.24.6":
+"@babel/parser@^7.1.0", "@babel/parser@^7.13.16", "@babel/parser@^7.14.7", "@babel/parser@^7.20.0", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.24.6":
version "7.24.6"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.6.tgz#5e030f440c3c6c78d195528c3b688b101a365328"
integrity sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==
@@ -361,6 +361,20 @@
dependencies:
"@babel/helper-plugin-utils" "^7.8.0"
+"@babel/plugin-syntax-bigint@^7.8.3":
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea"
+ integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-class-properties@^7.8.3":
+ version "7.12.13"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10"
+ integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.12.13"
+
"@babel/plugin-syntax-decorators@^7.24.6":
version "7.24.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.24.6.tgz#904d53fc158e8fb9f0754c76071e0ce38fe318eb"
@@ -396,14 +410,28 @@
dependencies:
"@babel/helper-plugin-utils" "^7.24.6"
-"@babel/plugin-syntax-jsx@^7.24.6":
+"@babel/plugin-syntax-import-meta@^7.8.3":
+ version "7.10.4"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51"
+ integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.10.4"
+
+"@babel/plugin-syntax-json-strings@^7.8.3":
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a"
+ integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-jsx@^7.24.6", "@babel/plugin-syntax-jsx@^7.7.2":
version "7.24.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.6.tgz#bcca2964150437f88f65e3679e3d68762287b9c8"
integrity sha512-lWfvAIFNWMlCsU0DRUun2GpFwZdGTukLaHJqRh1JRb80NdAP5Sb1HDHB5X9P9OtgZHQl089UzQkpYlBq2VTPRw==
dependencies:
"@babel/helper-plugin-utils" "^7.24.6"
-"@babel/plugin-syntax-logical-assignment-operators@^7.10.4":
+"@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699"
integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==
@@ -417,7 +445,7 @@
dependencies:
"@babel/helper-plugin-utils" "^7.8.0"
-"@babel/plugin-syntax-numeric-separator@^7.10.4":
+"@babel/plugin-syntax-numeric-separator@^7.10.4", "@babel/plugin-syntax-numeric-separator@^7.8.3":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97"
integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==
@@ -452,7 +480,14 @@
dependencies:
"@babel/helper-plugin-utils" "^7.14.5"
-"@babel/plugin-syntax-typescript@^7.24.6":
+"@babel/plugin-syntax-top-level-await@^7.8.3":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c"
+ integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.14.5"
+
+"@babel/plugin-syntax-typescript@^7.24.6", "@babel/plugin-syntax-typescript@^7.7.2":
version "7.24.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.6.tgz#769daf2982d60308bc83d8936eaecb7582463c87"
integrity sha512-TzCtxGgVTEJWWwcYwQhCIQ6WaKlo80/B+Onsk4RRCcYqpYGFcG9etPW94VToGte5AAcxRrhjPUFvUS3Y2qKi4A==
@@ -766,14 +801,14 @@
resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310"
integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==
-"@babel/runtime@^7.0.0", "@babel/runtime@^7.13.10", "@babel/runtime@^7.13.9", "@babel/runtime@^7.18.6", "@babel/runtime@^7.20.0", "@babel/runtime@^7.24.1":
+"@babel/runtime@^7.0.0", "@babel/runtime@^7.13.10", "@babel/runtime@^7.18.6", "@babel/runtime@^7.20.0", "@babel/runtime@^7.24.1":
version "7.24.6"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.6.tgz#5b76eb89ad45e2e4a0a8db54c456251469a3358e"
integrity sha512-Ja18XcETdEl5mzzACGd+DKgaGJzPTCow7EglgwTmHdwokzDFYh/MHua6lU6DV/hjF2IaOJ4oX2nqnjG7RElKOw==
dependencies:
regenerator-runtime "^0.14.0"
-"@babel/template@^7.0.0", "@babel/template@^7.24.6":
+"@babel/template@^7.0.0", "@babel/template@^7.24.6", "@babel/template@^7.3.3":
version "7.24.6"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.6.tgz#048c347b2787a6072b24c723664c8d02b67a44f9"
integrity sha512-3vgazJlLwNXi9jhrR1ef8qiB65L1RK90+lEQwv4OxveHnqC3BfmnHdgySwRLzf6akhlOYenT+b7AfWq+a//AHw==
@@ -798,7 +833,7 @@
debug "^4.3.1"
globals "^11.1.0"
-"@babel/types@^7.0.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.23.0", "@babel/types@^7.24.6":
+"@babel/types@^7.0.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.23.0", "@babel/types@^7.24.6", "@babel/types@^7.3.3":
version "7.24.6"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.6.tgz#ba4e1f59870c10dc2fa95a274ac4feec23b21912"
integrity sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==
@@ -807,6 +842,11 @@
"@babel/helper-validator-identifier" "^7.24.6"
to-fast-properties "^2.0.0"
+"@bcoe/v8-coverage@^0.2.3":
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
+ integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
+
"@cspotcode/source-map-support@^0.8.0":
version "0.8.1"
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
@@ -814,12 +854,12 @@
dependencies:
"@jridgewell/trace-mapping" "0.3.9"
-"@effect/schema@^0.67.15":
- version "0.67.15"
- resolved "https://registry.yarnpkg.com/@effect/schema/-/schema-0.67.15.tgz#b57ce1617a1ed6ec689a486f1ba392a1c521b9a4"
- integrity sha512-+AO29qX0GIDARbQE1TcnWz3cUBCOm3x8KP6SXpWUot1cfG4ccoWrrfzVBaaCl1FDT5egvAtwfQ26GPVMJEobEg==
+"@egjs/hammerjs@^2.0.17":
+ version "2.0.17"
+ resolved "https://registry.yarnpkg.com/@egjs/hammerjs/-/hammerjs-2.0.17.tgz#5dc02af75a6a06e4c2db0202cae38c9263895124"
+ integrity sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==
dependencies:
- fast-check "^3.17.2"
+ "@types/hammerjs" "^2.0.36"
"@eslint-community/eslint-utils@^4.2.0":
version "4.4.0"
@@ -1116,7 +1156,7 @@
postcss "~8.4.32"
resolve-from "^5.0.0"
-"@expo/metro-runtime@3.2.1", "@expo/metro-runtime@~3.2.1":
+"@expo/metro-runtime@3.2.1":
version "3.2.1"
resolved "https://registry.yarnpkg.com/@expo/metro-runtime/-/metro-runtime-3.2.1.tgz#bbab2ca9d0c8d256172eb4688123af6be67c7674"
integrity sha512-L7xNo5SmK+rcuXDm/+VBBImpA7FZsVB+m/rNr3fNl5or+1+yrZe99ViF7LZ8DOoVqAqcb4aCAXvGrP2JNYo1/Q==
@@ -1215,17 +1255,6 @@
dependencies:
prop-types "^15.8.1"
-"@expo/websql@^1.0.1":
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/@expo/websql/-/websql-1.0.1.tgz#fff0cf9c1baa1f70f9e1d658b7c39a420d9b10a9"
- integrity sha512-H9/t1V7XXyKC343FJz/LwaVBfDhs6IqhDtSYWpt8LNSQDVjf5NvVJLc5wp+KCpRidZx8+0+YeHJN45HOXmqjFA==
- dependencies:
- argsarray "^0.0.1"
- immediate "^3.2.2"
- noop-fn "^1.0.0"
- pouchdb-collections "^1.0.1"
- tiny-queue "^0.2.1"
-
"@expo/xcpretty@^4.3.0":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@expo/xcpretty/-/xcpretty-4.3.1.tgz#e0a6a92d1e46ab5ac5e90d9a8e66ac1a2a2f5920"
@@ -1294,7 +1323,69 @@
resolved "https://registry.yarnpkg.com/@isaacs/ttlcache/-/ttlcache-1.4.1.tgz#21fb23db34e9b6220c6ba023a0118a2dd3461ea2"
integrity sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==
-"@jest/create-cache-key-function@^29.6.3":
+"@istanbuljs/load-nyc-config@^1.0.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
+ integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==
+ dependencies:
+ camelcase "^5.3.1"
+ find-up "^4.1.0"
+ get-package-type "^0.1.0"
+ js-yaml "^3.13.1"
+ resolve-from "^5.0.0"
+
+"@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3":
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98"
+ integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==
+
+"@jest/console@^29.7.0":
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.7.0.tgz#cd4822dbdb84529265c5a2bdb529a3c9cc950ffc"
+ integrity sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==
+ dependencies:
+ "@jest/types" "^29.6.3"
+ "@types/node" "*"
+ chalk "^4.0.0"
+ jest-message-util "^29.7.0"
+ jest-util "^29.7.0"
+ slash "^3.0.0"
+
+"@jest/core@^29.7.0":
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.7.0.tgz#b6cccc239f30ff36609658c5a5e2291757ce448f"
+ integrity sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==
+ dependencies:
+ "@jest/console" "^29.7.0"
+ "@jest/reporters" "^29.7.0"
+ "@jest/test-result" "^29.7.0"
+ "@jest/transform" "^29.7.0"
+ "@jest/types" "^29.6.3"
+ "@types/node" "*"
+ ansi-escapes "^4.2.1"
+ chalk "^4.0.0"
+ ci-info "^3.2.0"
+ exit "^0.1.2"
+ graceful-fs "^4.2.9"
+ jest-changed-files "^29.7.0"
+ jest-config "^29.7.0"
+ jest-haste-map "^29.7.0"
+ jest-message-util "^29.7.0"
+ jest-regex-util "^29.6.3"
+ jest-resolve "^29.7.0"
+ jest-resolve-dependencies "^29.7.0"
+ jest-runner "^29.7.0"
+ jest-runtime "^29.7.0"
+ jest-snapshot "^29.7.0"
+ jest-util "^29.7.0"
+ jest-validate "^29.7.0"
+ jest-watcher "^29.7.0"
+ micromatch "^4.0.4"
+ pretty-format "^29.7.0"
+ slash "^3.0.0"
+ strip-ansi "^6.0.0"
+
+"@jest/create-cache-key-function@^29.2.1", "@jest/create-cache-key-function@^29.6.3":
version "29.7.0"
resolved "https://registry.yarnpkg.com/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz#793be38148fab78e65f40ae30c36785f4ad859f0"
integrity sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==
@@ -1311,6 +1402,21 @@
"@types/node" "*"
jest-mock "^29.7.0"
+"@jest/expect-utils@^29.7.0":
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6"
+ integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==
+ dependencies:
+ jest-get-type "^29.6.3"
+
+"@jest/expect@^29.7.0":
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.7.0.tgz#76a3edb0cb753b70dfbfe23283510d3d45432bf2"
+ integrity sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==
+ dependencies:
+ expect "^29.7.0"
+ jest-snapshot "^29.7.0"
+
"@jest/fake-timers@^29.7.0":
version "29.7.0"
resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565"
@@ -1323,6 +1429,46 @@
jest-mock "^29.7.0"
jest-util "^29.7.0"
+"@jest/globals@^29.7.0":
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.7.0.tgz#8d9290f9ec47ff772607fa864ca1d5a2efae1d4d"
+ integrity sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==
+ dependencies:
+ "@jest/environment" "^29.7.0"
+ "@jest/expect" "^29.7.0"
+ "@jest/types" "^29.6.3"
+ jest-mock "^29.7.0"
+
+"@jest/reporters@^29.7.0":
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.7.0.tgz#04b262ecb3b8faa83b0b3d321623972393e8f4c7"
+ integrity sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==
+ dependencies:
+ "@bcoe/v8-coverage" "^0.2.3"
+ "@jest/console" "^29.7.0"
+ "@jest/test-result" "^29.7.0"
+ "@jest/transform" "^29.7.0"
+ "@jest/types" "^29.6.3"
+ "@jridgewell/trace-mapping" "^0.3.18"
+ "@types/node" "*"
+ chalk "^4.0.0"
+ collect-v8-coverage "^1.0.0"
+ exit "^0.1.2"
+ glob "^7.1.3"
+ graceful-fs "^4.2.9"
+ istanbul-lib-coverage "^3.0.0"
+ istanbul-lib-instrument "^6.0.0"
+ istanbul-lib-report "^3.0.0"
+ istanbul-lib-source-maps "^4.0.0"
+ istanbul-reports "^3.1.3"
+ jest-message-util "^29.7.0"
+ jest-util "^29.7.0"
+ jest-worker "^29.7.0"
+ slash "^3.0.0"
+ string-length "^4.0.1"
+ strip-ansi "^6.0.0"
+ v8-to-istanbul "^9.0.1"
+
"@jest/schemas@^29.6.3":
version "29.6.3"
resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03"
@@ -1330,6 +1476,56 @@
dependencies:
"@sinclair/typebox" "^0.27.8"
+"@jest/source-map@^29.6.3":
+ version "29.6.3"
+ resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.3.tgz#d90ba772095cf37a34a5eb9413f1b562a08554c4"
+ integrity sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==
+ dependencies:
+ "@jridgewell/trace-mapping" "^0.3.18"
+ callsites "^3.0.0"
+ graceful-fs "^4.2.9"
+
+"@jest/test-result@^29.7.0":
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.7.0.tgz#8db9a80aa1a097bb2262572686734baed9b1657c"
+ integrity sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==
+ dependencies:
+ "@jest/console" "^29.7.0"
+ "@jest/types" "^29.6.3"
+ "@types/istanbul-lib-coverage" "^2.0.0"
+ collect-v8-coverage "^1.0.0"
+
+"@jest/test-sequencer@^29.7.0":
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz#6cef977ce1d39834a3aea887a1726628a6f072ce"
+ integrity sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==
+ dependencies:
+ "@jest/test-result" "^29.7.0"
+ graceful-fs "^4.2.9"
+ jest-haste-map "^29.7.0"
+ slash "^3.0.0"
+
+"@jest/transform@^29.7.0":
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.7.0.tgz#df2dd9c346c7d7768b8a06639994640c642e284c"
+ integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==
+ dependencies:
+ "@babel/core" "^7.11.6"
+ "@jest/types" "^29.6.3"
+ "@jridgewell/trace-mapping" "^0.3.18"
+ babel-plugin-istanbul "^6.1.1"
+ chalk "^4.0.0"
+ convert-source-map "^2.0.0"
+ fast-json-stable-stringify "^2.1.0"
+ graceful-fs "^4.2.9"
+ jest-haste-map "^29.7.0"
+ jest-regex-util "^29.6.3"
+ jest-util "^29.7.0"
+ micromatch "^4.0.4"
+ pirates "^4.0.4"
+ slash "^3.0.0"
+ write-file-atomic "^4.0.2"
+
"@jest/types@^26.6.2":
version "26.6.2"
resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e"
@@ -1393,7 +1589,7 @@
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10"
-"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25":
+"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25":
version "0.3.25"
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0"
integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==
@@ -1655,11 +1851,6 @@
resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.74.83.tgz#c1815dc10f9e1075e0d03b4c8a9619145969522e"
integrity sha512-2vkLMVnp+YTZYTNSDIBZojSsjz8sl5PscP3j4GcV6idD8V978SZfwFlk8K0ti0BzRs11mzL0Pj17km597S/eTQ==
-"@react-native/assets-registry@0.75.0-main":
- version "0.75.0-main"
- resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.75.0-main.tgz#d2e8ffc330cd67b3e077a168637fecf63d85ea82"
- integrity sha512-QXqlChMBbKbVgYyZIDPvNYy1JvnCOsxxDn5szL6hLDmT9ITBLPihVWI7vCgS/THsX7PaIxk3g9fuYCIH4JCvWQ==
-
"@react-native/babel-plugin-codegen@0.74.83":
version "0.74.83"
resolved "https://registry.yarnpkg.com/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.74.83.tgz#971f9cfec980dd05598d81964c05a26c6166f9fb"
@@ -1838,7 +2029,7 @@
"@react-navigation/elements" "^1.3.30"
warn-once "^0.1.0"
-"@react-navigation/native@~6.1.6":
+"@react-navigation/native@^6.0.2", "@react-navigation/native@~6.1.6":
version "6.1.17"
resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-6.1.17.tgz#439f15a99809d26ea4682d2a3766081cf2ca31cf"
integrity sha512-mer3OvfwWOHoUSMJyLa4vnBH3zpFmCwuzrBPlw7feXklurr/ZDiLjLxUScOot6jLRMz/67GyilEYMmP99LL0RQ==
@@ -1949,7 +2140,7 @@
component-type "^1.2.1"
join-component "^1.1.0"
-"@serenity-kit/opaque@^0.8.4":
+"@serenity-kit/opaque@^0.8.0", "@serenity-kit/opaque@^0.8.4":
version "0.8.4"
resolved "https://registry.yarnpkg.com/@serenity-kit/opaque/-/opaque-0.8.4.tgz#c765905b338abcd8eaee8d44f6b9c40850925b40"
integrity sha512-sFxGxZWdBciJ1Bp2F5Pey5q3kW+bN/RYpsZueLogb/KAWF50XuYk5bSG0Y8gH784jV+2XI/G8ptX+kWA0w6N3Q==
@@ -1990,10 +2181,37 @@
dependencies:
"@sinonjs/commons" "^3.0.0"
-"@trpc/server@11.0.0-rc.366":
- version "11.0.0-rc.366"
- resolved "https://registry.yarnpkg.com/@trpc/server/-/server-11.0.0-rc.366.tgz#ffea6f1616bad4e9d77160c7aa4fe7a381317117"
- integrity sha512-Pr7SdpIVrOGtIGt9vs7i3v0hqzlpXbi8/8RV7XfrXVJ5hlzKYOz5VE0AjckhHXuhrUlpTGTDm0/2nz0ywLcQ2g==
+"@tanstack/query-core@5.40.0":
+ version "5.40.0"
+ resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.40.0.tgz#c74ae8303752ed4b5a0ab848ec71a0e6e8179f83"
+ integrity sha512-eD8K8jsOIq0Z5u/QbvOmfvKKE/XC39jA7yv4hgpl/1SRiU+J8QCIwgM/mEHuunQsL87dcvnHqSVLmf9pD4CiaA==
+
+"@tanstack/react-query@^5.40.0":
+ version "5.40.0"
+ resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.40.0.tgz#654afa2d9ab328c22be7e1f025ec9b6267c6baa9"
+ integrity sha512-iv/W0Axc4aXhFzkrByToE1JQqayxTPNotCoSCnarR/A1vDIHaoKpg7FTIfP3Ev2mbKn1yrxq0ZKYUdLEJxs6Tg==
+ dependencies:
+ "@tanstack/query-core" "5.40.0"
+
+"@tootallnate/once@2":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
+ integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==
+
+"@trpc/client@^11.0.0-rc.382":
+ version "11.0.0-rc.382"
+ resolved "https://registry.yarnpkg.com/@trpc/client/-/client-11.0.0-rc.382.tgz#0bb2222aaa5cbbb7c8d5c9cdde21572bd148a20e"
+ integrity sha512-O+MSRed5r8AJJ+j3peZkd/b7WINEkhKaFilRuPH8VQsrlMZToxUzQl9aShPIgnOhhQGxvWqdh2lXwUvrFCea/A==
+
+"@trpc/react-query@^11.0.0-rc.382":
+ version "11.0.0-rc.382"
+ resolved "https://registry.yarnpkg.com/@trpc/react-query/-/react-query-11.0.0-rc.382.tgz#2ab7c9282d4f9a57b6e25bf601ec532f4fe0979d"
+ integrity sha512-VlYe+ufYy/hWQFpBEG2MHKsGrGmt2oqqPBO4lHWBpuCcQnzttvsW+LkBkMoy6qZqFcrGyQJC8KQXHO6njmfmZQ==
+
+"@trpc/server@^11.0.0-rc.382":
+ version "11.0.0-rc.382"
+ resolved "https://registry.yarnpkg.com/@trpc/server/-/server-11.0.0-rc.382.tgz#ef2a561cbbf97d14eb283a979be849be0cf08c78"
+ integrity sha512-a3A0osTgFhbClRjE+fZ3nA3TEjupnWM23L4hidjecg3xN+QghwYTjwXJcYXPsdKyT6PhFtzWBKJxShmsZRElZw==
"@tsconfig/node10@^1.0.7":
version "1.0.11"
@@ -2015,7 +2233,7 @@
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9"
integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==
-"@types/babel__core@^7.1.12":
+"@types/babel__core@^7.1.14":
version "7.20.5"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017"
integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==
@@ -2041,7 +2259,7 @@
"@babel/parser" "^7.1.0"
"@babel/types" "^7.0.0"
-"@types/babel__traverse@*":
+"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6":
version "7.20.6"
resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.6.tgz#8dc9f0ae0f202c08d8d4dab648912c8d6038e3f7"
integrity sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==
@@ -2102,12 +2320,24 @@
"@types/qs" "*"
"@types/serve-static" "*"
+"@types/graceful-fs@^4.1.3":
+ version "4.1.9"
+ resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4"
+ integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==
+ dependencies:
+ "@types/node" "*"
+
+"@types/hammerjs@^2.0.36":
+ version "2.0.45"
+ resolved "https://registry.yarnpkg.com/@types/hammerjs/-/hammerjs-2.0.45.tgz#ffa764bb68a66c08db6efb9c816eb7be850577b1"
+ integrity sha512-qkcUlZmX6c4J8q45taBKTL3p+LbITgyx7qhlPYOdOHZB7B31K0mXbP5YA7i7SgDeEGuI9MnumiKPEMrxg8j3KQ==
+
"@types/http-errors@*":
version "2.0.4"
resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f"
integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==
-"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
+"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1":
version "2.0.6"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7"
integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==
@@ -2126,6 +2356,23 @@
dependencies:
"@types/istanbul-lib-report" "*"
+"@types/jest@^29.5.12":
+ version "29.5.12"
+ resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.12.tgz#7f7dc6eb4cf246d2474ed78744b05d06ce025544"
+ integrity sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==
+ dependencies:
+ expect "^29.0.0"
+ pretty-format "^29.0.0"
+
+"@types/jsdom@^20.0.0":
+ version "20.0.1"
+ resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-20.0.1.tgz#07c14bc19bd2f918c1929541cdaacae894744808"
+ integrity sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==
+ dependencies:
+ "@types/node" "*"
+ "@types/tough-cookie" "*"
+ parse5 "^7.0.0"
+
"@types/json-schema@^7.0.9":
version "7.0.15"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
@@ -2193,10 +2440,10 @@
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb"
integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==
-"@types/react@~18.3.3":
- version "18.3.3"
- resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.3.tgz#9679020895318b0915d7a3ab004d92d33375c45f"
- integrity sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==
+"@types/react@~18.2.45":
+ version "18.2.79"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.79.tgz#c40efb4f255711f554d47b449f796d1c7756d865"
+ integrity sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w==
dependencies:
"@types/prop-types" "*"
csstype "^3.0.2"
@@ -2228,6 +2475,11 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8"
integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==
+"@types/tough-cookie@*":
+ version "4.0.5"
+ resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.5.tgz#cb6e2a691b70cb177c6e3ae9c1d2e8b2ea8cd304"
+ integrity sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==
+
"@types/ws@^8.5.10":
version "8.5.10"
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.10.tgz#4acfb517970853fa6574a3a6886791d04a396787"
@@ -2306,6 +2558,11 @@
resolved "https://registry.yarnpkg.com/@zxing/text-encoding/-/text-encoding-0.9.0.tgz#fb50ffabc6c7c66a0c96b4c03e3d9be74864b70b"
integrity sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==
+abab@^2.0.6:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291"
+ integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==
+
abort-controller@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
@@ -2321,17 +2578,25 @@ accepts@^1.3.7, accepts@^1.3.8, accepts@~1.3.5, accepts@~1.3.7, accepts@~1.3.8:
mime-types "~2.1.34"
negotiator "0.6.3"
+acorn-globals@^7.0.0:
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-7.0.1.tgz#0dbf05c44fa7c94332914c02066d5beff62c40c3"
+ integrity sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==
+ dependencies:
+ acorn "^8.1.0"
+ acorn-walk "^8.0.2"
+
acorn-jsx@^5.3.2:
version "5.3.2"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
-acorn-walk@^8.1.1:
+acorn-walk@^8.0.2, acorn-walk@^8.1.1:
version "8.3.2"
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa"
integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==
-acorn@^8.11.3, acorn@^8.4.1, acorn@^8.8.2:
+acorn@^8.1.0, acorn@^8.11.3, acorn@^8.4.1, acorn@^8.8.1, acorn@^8.8.2:
version "8.11.3"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a"
integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==
@@ -2400,14 +2665,14 @@ anser@^1.4.9:
resolved "https://registry.yarnpkg.com/anser/-/anser-1.4.10.tgz#befa3eddf282684bd03b63dcda3927aef8c2e35b"
integrity sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==
-ansi-escapes@^4.2.1, ansi-escapes@^4.3.2:
+ansi-escapes@^4.2.1, ansi-escapes@^4.3.0, ansi-escapes@^4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e"
integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==
dependencies:
type-fest "^0.21.3"
-ansi-escapes@^6.2.0:
+ansi-escapes@^6.0.0, ansi-escapes@^6.2.0:
version "6.2.1"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-6.2.1.tgz#76c54ce9b081dad39acec4b5d53377913825fb0f"
integrity sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==
@@ -2505,11 +2770,6 @@ argparse@^2.0.1:
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
-argsarray@^0.0.1:
- version "0.0.1"
- resolved "https://registry.yarnpkg.com/argsarray/-/argsarray-0.0.1.tgz#6e7207b4ecdb39b0af88303fa5ae22bda8df61cb"
- integrity sha512-u96dg2GcAKtpTrBdDoFIM7PjcBA+6rSP0OR94MOReNRyUECL6MtQt5XXmRr4qrftYaef9+l5hcpO5te7sML1Cg==
-
array-buffer-byte-length@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz#1e5583ec16763540a27ae52eed99ff899223568f"
@@ -2586,6 +2846,40 @@ babel-core@^7.0.0-bridge.0:
resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece"
integrity sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==
+babel-jest@^29.2.1, babel-jest@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5"
+ integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==
+ dependencies:
+ "@jest/transform" "^29.7.0"
+ "@types/babel__core" "^7.1.14"
+ babel-plugin-istanbul "^6.1.1"
+ babel-preset-jest "^29.6.3"
+ chalk "^4.0.0"
+ graceful-fs "^4.2.9"
+ slash "^3.0.0"
+
+babel-plugin-istanbul@^6.1.1:
+ version "6.1.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73"
+ integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.0.0"
+ "@istanbuljs/load-nyc-config" "^1.0.0"
+ "@istanbuljs/schema" "^0.1.2"
+ istanbul-lib-instrument "^5.0.4"
+ test-exclude "^6.0.0"
+
+babel-plugin-jest-hoist@^29.6.3:
+ version "29.6.3"
+ resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz#aadbe943464182a8922c3c927c3067ff40d24626"
+ integrity sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==
+ dependencies:
+ "@babel/template" "^7.3.3"
+ "@babel/types" "^7.3.3"
+ "@types/babel__core" "^7.1.14"
+ "@types/babel__traverse" "^7.0.6"
+
babel-plugin-polyfill-corejs2@^0.4.10:
version "0.4.11"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz#30320dfe3ffe1a336c15afdcdafd6fd615b25e33"
@@ -2633,13 +2927,23 @@ babel-plugin-transform-flow-enums@^0.0.2:
dependencies:
"@babel/plugin-syntax-flow" "^7.12.1"
-babel-plugin-transform-vite-meta-env@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-vite-meta-env/-/babel-plugin-transform-vite-meta-env-1.0.3.tgz#cbf81becc95b71dcc170ee4863cb7f6919ed99bb"
- integrity sha512-eyfuDEXrMu667TQpmctHeTlJrZA6jXYHyEJFjcM0yEa60LS/LXlOg2PBbMb8DVS+V9CnTj/j9itdlDVMcY2zEg==
+babel-preset-current-node-syntax@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b"
+ integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==
dependencies:
- "@babel/runtime" "^7.13.9"
- "@types/babel__core" "^7.1.12"
+ "@babel/plugin-syntax-async-generators" "^7.8.4"
+ "@babel/plugin-syntax-bigint" "^7.8.3"
+ "@babel/plugin-syntax-class-properties" "^7.8.3"
+ "@babel/plugin-syntax-import-meta" "^7.8.3"
+ "@babel/plugin-syntax-json-strings" "^7.8.3"
+ "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3"
+ "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
+ "@babel/plugin-syntax-numeric-separator" "^7.8.3"
+ "@babel/plugin-syntax-object-rest-spread" "^7.8.3"
+ "@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
+ "@babel/plugin-syntax-optional-chaining" "^7.8.3"
+ "@babel/plugin-syntax-top-level-await" "^7.8.3"
babel-preset-expo@~11.0.0, babel-preset-expo@~11.0.6:
version "11.0.6"
@@ -2656,6 +2960,14 @@ babel-preset-expo@~11.0.0, babel-preset-expo@~11.0.6:
babel-plugin-react-native-web "~0.19.10"
react-refresh "^0.14.2"
+babel-preset-jest@^29.6.3:
+ version "29.6.3"
+ resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz#fa05fa510e7d493896d7b0dd2033601c840f171c"
+ integrity sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==
+ dependencies:
+ babel-plugin-jest-hoist "^29.6.3"
+ babel-preset-current-node-syntax "^1.0.0"
+
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
@@ -2879,7 +3191,7 @@ camelcase-css@^2.0.1:
resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5"
integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==
-camelcase@^5.0.0:
+camelcase@^5.0.0, camelcase@^5.3.1:
version "5.3.1"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
@@ -2908,6 +3220,14 @@ chalk@^2.0.1, chalk@^2.4.2:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
+chalk@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4"
+ integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==
+ dependencies:
+ ansi-styles "^4.1.0"
+ supports-color "^7.1.0"
+
chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
@@ -2921,6 +3241,16 @@ chalk@~5.3.0:
resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385"
integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==
+char-regex@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf"
+ integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==
+
+char-regex@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-2.0.1.tgz#6dafdb25f9d3349914079f010ba8d0e6ff9cd01e"
+ integrity sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==
+
charenc@0.0.2, charenc@~0.0.1:
version "0.0.2"
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
@@ -2966,6 +3296,11 @@ ci-info@^3.2.0, ci-info@^3.3.0:
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4"
integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==
+cjs-module-lexer@^1.0.0:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz#c485341ae8fd999ca4ee5af2d7a1c9ae01e0099c"
+ integrity sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==
+
class-variance-authority@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/class-variance-authority/-/class-variance-authority-0.7.0.tgz#1c3134d634d80271b1837452b06d821915954522"
@@ -3059,6 +3394,16 @@ clsx@^2.1.1:
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999"
integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==
+co@^4.6.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
+ integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==
+
+collect-v8-coverage@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9"
+ integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==
+
color-convert@^1.9.0:
version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
@@ -3271,6 +3616,19 @@ cosmiconfig@^5.0.5, cosmiconfig@^5.1.0:
js-yaml "^3.13.1"
parse-json "^4.0.0"
+create-jest@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320"
+ integrity sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==
+ dependencies:
+ "@jest/types" "^29.6.3"
+ chalk "^4.0.0"
+ exit "^0.1.2"
+ graceful-fs "^4.2.9"
+ jest-config "^29.7.0"
+ jest-util "^29.7.0"
+ prompts "^2.0.1"
+
create-require@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
@@ -3354,6 +3712,23 @@ cssesc@^3.0.0:
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
+cssom@^0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36"
+ integrity sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==
+
+cssom@~0.3.6:
+ version "0.3.8"
+ resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a"
+ integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==
+
+cssstyle@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852"
+ integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==
+ dependencies:
+ cssom "~0.3.6"
+
csstype@^3.0.2:
version "3.1.3"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
@@ -3369,6 +3744,15 @@ data-uri-to-buffer@^3.0.1:
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636"
integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==
+data-urls@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-3.0.2.tgz#9cf24a477ae22bcef5cd5f6f0bfbc1d2d3be9143"
+ integrity sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==
+ dependencies:
+ abab "^2.0.6"
+ whatwg-mimetype "^3.0.0"
+ whatwg-url "^11.0.0"
+
data-view-buffer@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/data-view-buffer/-/data-view-buffer-1.0.1.tgz#8ea6326efec17a2e42620696e671d7d5a8bc66b2"
@@ -3427,11 +3811,21 @@ decamelize@^1.2.0:
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==
+decimal.js@^10.4.2:
+ version "10.4.3"
+ resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23"
+ integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==
+
decode-uri-component@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9"
integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==
+dedent@^1.0.0:
+ version "1.5.3"
+ resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.3.tgz#99aee19eb9bae55a67327717b6e848d0bf777e5a"
+ integrity sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==
+
deep-extend@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
@@ -3442,7 +3836,7 @@ deep-is@^0.1.3:
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
-deepmerge@^4.3.0:
+deepmerge@^4.2.2, deepmerge@^4.3.0:
version "4.3.1"
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a"
integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
@@ -3524,11 +3918,21 @@ detect-libc@^1.0.3:
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==
+detect-newline@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651"
+ integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==
+
didyoumean@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==
+diff-sequences@^29.6.3:
+ version "29.6.3"
+ resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921"
+ integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==
+
diff@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
@@ -3560,6 +3964,13 @@ domelementtype@^2.3.0:
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
+domexception@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673"
+ integrity sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==
+ dependencies:
+ webidl-conversions "^7.0.0"
+
domhandler@^5.0.2, domhandler@^5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31"
@@ -3603,6 +4014,11 @@ electron-to-chromium@^1.4.668:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.787.tgz#3eedd0a3b8be2b9e96e21675d399786ad90b99ed"
integrity sha512-d0EFmtLPjctczO3LogReyM2pbBiiZbnsKnGF+cdZhsYzHm/A0GV7W94kqzLD8SN4O3f3iHlgLUChqghgyznvCQ==
+emittery@^0.13.1:
+ version "0.13.1"
+ resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad"
+ integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==
+
emoji-regex@^10.3.0:
version "10.3.0"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.3.0.tgz#76998b9268409eb3dae3de989254d456e70cfe23"
@@ -3630,7 +4046,7 @@ end-of-stream@^1.1.0:
dependencies:
once "^1.4.0"
-entities@^4.2.0:
+entities@^4.2.0, entities@^4.4.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
@@ -3786,6 +4202,17 @@ escape-string-regexp@^4.0.0:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
+escodegen@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17"
+ integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==
+ dependencies:
+ esprima "^4.0.1"
+ estraverse "^5.2.0"
+ esutils "^2.0.2"
+ optionalDependencies:
+ source-map "~0.6.1"
+
eslint-scope@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.0.1.tgz#a9601e4b81a0b9171657c343fb13111688963cfc"
@@ -3853,7 +4280,7 @@ espree@^10.0.1:
acorn-jsx "^5.3.2"
eslint-visitor-keys "^4.0.0"
-esprima@^4.0.0, esprima@~4.0.0:
+esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
@@ -3945,6 +4372,22 @@ execa@~8.0.1:
signal-exit "^4.1.0"
strip-final-newline "^3.0.0"
+exit@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
+ integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==
+
+expect@^29.0.0, expect@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc"
+ integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==
+ dependencies:
+ "@jest/expect-utils" "^29.7.0"
+ jest-get-type "^29.6.3"
+ jest-matcher-utils "^29.7.0"
+ jest-message-util "^29.7.0"
+ jest-util "^29.7.0"
+
expo-asset@~10.0.6:
version "10.0.6"
resolved "https://registry.yarnpkg.com/expo-asset/-/expo-asset-10.0.6.tgz#0894c4e824ce90e130852e6eecaba386e9f2e5aa"
@@ -3955,11 +4398,6 @@ expo-asset@~10.0.6:
invariant "^2.2.4"
md5-file "^3.2.3"
-expo-clipboard@~6.0.3:
- version "6.0.3"
- resolved "https://registry.yarnpkg.com/expo-clipboard/-/expo-clipboard-6.0.3.tgz#dfea74d4a004dce59ecefd063d6fb9f1c356a03f"
- integrity sha512-RIKDsuHkYfaspifbFpVC8sBVFKR05L7Pj7mU2/XkbrW9m01OBNvdpGraXEMsTFCx97xMGsZpEw9pPquL4j4xVg==
-
expo-constants@~16.0.0, expo-constants@~16.0.2:
version "16.0.2"
resolved "https://registry.yarnpkg.com/expo-constants/-/expo-constants-16.0.2.tgz#eb5a1bddb7308fd8cadac8fc44decaf4784cac5e"
@@ -4081,20 +4519,13 @@ expo-router@~3.5.14:
react-native-helmet-async "2.0.4"
schema-utils "^4.0.1"
-expo-splash-screen@0.27.4:
+expo-splash-screen@0.27.4, expo-splash-screen@~0.27.4:
version "0.27.4"
resolved "https://registry.yarnpkg.com/expo-splash-screen/-/expo-splash-screen-0.27.4.tgz#d7a86a2a1a87824ed47388aa8836e91b61268c62"
integrity sha512-JwepK1FjbwiOK2nwIFanfzj9s7UXYnpTwLX8A9v7Ec3K4V28yu8HooSc9X60cftBw9UZrs8Gwj4PgTpQabBS9A==
dependencies:
"@expo/prebuild-config" "7.0.3"
-expo-sqlite@~14.0.3:
- version "14.0.3"
- resolved "https://registry.yarnpkg.com/expo-sqlite/-/expo-sqlite-14.0.3.tgz#7d91e564b86cea09db40fd6fe0ccd79785234ffb"
- integrity sha512-H9+QXpB9ppPFeI5ZIPzIZJAdj4hgP2XJEoNe6xlhSUqcEhiq7k55Hs4mf1LX2r1JgSbIjucMEuDlMT8ntU4Pew==
- dependencies:
- "@expo/websql" "^1.0.1"
-
expo-standard-web-crypto@^1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/expo-standard-web-crypto/-/expo-standard-web-crypto-1.8.1.tgz#f7d61ae7040a357b18a48c304c3c36e57110dc4b"
@@ -4105,12 +4536,20 @@ expo-status-bar@~1.12.1:
resolved "https://registry.yarnpkg.com/expo-status-bar/-/expo-status-bar-1.12.1.tgz#52ce594aab5064a0511d14375364d718ab78aa66"
integrity sha512-/t3xdbS8KB0prj5KG5w7z+wZPFlPtkgs95BsmrP/E7Q0xHXTcDcQ6Cu2FkFuRM+PKTb17cJDnLkawyS5vDLxMA==
+expo-system-ui@~3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/expo-system-ui/-/expo-system-ui-3.0.4.tgz#5ace49d38eb03c09a8041b3b82c581a6b974741a"
+ integrity sha512-v1n6hBO30k9qw6RE8/au4yNoovs71ExGuXizJUlR5KSo4Ruogpb+0/2q3uRZMDIYWWCANvms8L0UOh6fQJ5TXg==
+ dependencies:
+ "@react-native/normalize-colors" "~0.74.83"
+ debug "^4.3.2"
+
expo-updates-interface@~0.16.2:
version "0.16.2"
resolved "https://registry.yarnpkg.com/expo-updates-interface/-/expo-updates-interface-0.16.2.tgz#ad1ac2ca8ee5a8cc84052ea3c18a11da64da569b"
integrity sha512-929XBU70q5ELxkKADj1xL0UIm3HvhYhNAOZv5DSk7rrKvLo7QDdPyl+JVnwZm9LrkNbH4wuE2rLoKu1KMgZ+9A==
-expo@51.0.9:
+expo@~51.0.9:
version "51.0.9"
resolved "https://registry.yarnpkg.com/expo/-/expo-51.0.9.tgz#a47de1b3d3afe1bf51f37bf69e487d0317686722"
integrity sha512-USckGusi4389X/mFy8X8tEA59vgsc5joOILQrTsDPdDJawkUidDAVqY4NIjJxOY7zEq1SfPv/LglJ4cOdtvfsg==
@@ -4168,13 +4607,6 @@ express@^4.19.2:
utils-merge "1.0.1"
vary "~1.1.2"
-fast-check@^3.17.2:
- version "3.19.0"
- resolved "https://registry.yarnpkg.com/fast-check/-/fast-check-3.19.0.tgz#6a0b7cabc3aa82bc00967332de216c5452ff7ea5"
- integrity sha512-CO2JX/8/PT9bDGO1iXa5h5ey1skaKI1dvecERyhH4pp3PGjwd3KIjMAXEg79Ps9nclsdt4oPbfqiAnLU0EwrAQ==
- dependencies:
- pure-rand "^6.1.0"
-
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
@@ -4191,7 +4623,7 @@ fast-glob@^3.2.5, fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.2:
merge2 "^1.3.0"
micromatch "^4.0.4"
-fast-json-stable-stringify@^2.0.0:
+fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
@@ -4206,11 +4638,6 @@ fast-loops@^1.1.3:
resolved "https://registry.yarnpkg.com/fast-loops/-/fast-loops-1.1.3.tgz#ce96adb86d07e7bf9b4822ab9c6fac9964981f75"
integrity sha512-8EZzEP0eKkEEVX+drtd9mtuQ+/QrlfW/5MlwcwK5Nds6EkZ/tRzEexkzUY2mIssnAyVLT+TKHuRXmFNNXYUd6g==
-fast-text-encoding@^1.0.6:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/fast-text-encoding/-/fast-text-encoding-1.0.6.tgz#0aa25f7f638222e3396d72bf936afcf1d42d6867"
- integrity sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==
-
fast-xml-parser@^4.0.12, fast-xml-parser@^4.2.4:
version "4.4.0"
resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.4.0.tgz#341cc98de71e9ba9e651a67f41f1752d1441a501"
@@ -4323,7 +4750,7 @@ find-up@^3.0.0:
dependencies:
locate-path "^3.0.0"
-find-up@^4.1.0:
+find-up@^4.0.0, find-up@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
@@ -4398,6 +4825,15 @@ form-data@^3.0.1:
combined-stream "^1.0.8"
mime-types "^2.1.12"
+form-data@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
+ integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
+ dependencies:
+ asynckit "^0.4.0"
+ combined-stream "^1.0.8"
+ mime-types "^2.1.12"
+
forwarded@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
@@ -4521,6 +4957,11 @@ get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.3, get-intrinsic@
has-symbols "^1.0.3"
hasown "^2.0.0"
+get-package-type@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
+ integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==
+
get-port@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc"
@@ -4605,7 +5046,7 @@ glob@^6.0.1:
once "^1.3.0"
path-is-absolute "^1.0.0"
-glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.7, glob@^7.2.3:
+glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.7, glob@^7.2.3:
version "7.2.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
@@ -4748,6 +5189,13 @@ hermes-profile-transformer@^0.0.6:
dependencies:
source-map "^0.7.3"
+hoist-non-react-statics@^3.3.0:
+ version "3.3.2"
+ resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
+ integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
+ dependencies:
+ react-is "^16.7.0"
+
hosted-git-info@^3.0.2:
version "3.0.8"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.8.tgz#6e35d4cc87af2c5f816e4cb9ce350ba87a3f370d"
@@ -4755,6 +5203,18 @@ hosted-git-info@^3.0.2:
dependencies:
lru-cache "^6.0.0"
+html-encoding-sniffer@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9"
+ integrity sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==
+ dependencies:
+ whatwg-encoding "^2.0.0"
+
+html-escaper@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453"
+ integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==
+
http-errors@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
@@ -4766,6 +5226,15 @@ http-errors@2.0.0:
statuses "2.0.1"
toidentifier "1.0.1"
+http-proxy-agent@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43"
+ integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==
+ dependencies:
+ "@tootallnate/once" "2"
+ agent-base "6"
+ debug "4"
+
https-proxy-agent@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6"
@@ -4801,6 +5270,13 @@ iconv-lite@0.4.24:
dependencies:
safer-buffer ">= 2.1.2 < 3"
+iconv-lite@0.6.3:
+ version "0.6.3"
+ resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"
+ integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==
+ dependencies:
+ safer-buffer ">= 2.1.2 < 3.0.0"
+
ieee754@^1.1.13:
version "1.2.1"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
@@ -4823,11 +5299,6 @@ image-size@^1.0.2:
dependencies:
queue "6.0.2"
-immediate@^3.2.2:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.3.0.tgz#1aef225517836bcdf7f2a2de2600c79ff0269266"
- integrity sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==
-
import-fresh@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546"
@@ -4844,6 +5315,14 @@ import-fresh@^3.2.1:
parent-module "^1.0.0"
resolve-from "^4.0.0"
+import-local@^3.0.2:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4"
+ integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==
+ dependencies:
+ pkg-dir "^4.2.0"
+ resolve-cwd "^3.0.0"
+
imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
@@ -5035,6 +5514,11 @@ is-fullwidth-code-point@^5.0.0:
dependencies:
get-east-asian-width "^1.0.0"
+is-generator-fn@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118"
+ integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==
+
is-generator-function@^1.0.7:
version "1.0.10"
resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72"
@@ -5102,6 +5586,11 @@ is-plain-object@^2.0.4:
dependencies:
isobject "^3.0.1"
+is-potential-custom-element-name@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5"
+ integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==
+
is-regex@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958"
@@ -5214,16 +5703,191 @@ isomorphic.js@^0.2.4:
resolved "https://registry.yarnpkg.com/isomorphic.js/-/isomorphic.js-0.2.5.tgz#13eecf36f2dba53e85d355e11bf9d4208c6f7f88"
integrity sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==
-jackspeak@^3.1.2:
- version "3.1.2"
- resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.1.2.tgz#eada67ea949c6b71de50f1b09c92a961897b90ab"
- integrity sha512-kWmLKn2tRtfYMF/BakihVVRzBKOxz4gJMiL2Rj91WnAB5TPZumSH99R/Yf1qE1u4uRimvCSJfm6hnxohXeEXjQ==
+istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0:
+ version "3.2.2"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756"
+ integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==
+
+istanbul-lib-instrument@^5.0.4:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d"
+ integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==
+ dependencies:
+ "@babel/core" "^7.12.3"
+ "@babel/parser" "^7.14.7"
+ "@istanbuljs/schema" "^0.1.2"
+ istanbul-lib-coverage "^3.2.0"
+ semver "^6.3.0"
+
+istanbul-lib-instrument@^6.0.0:
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz#91655936cf7380e4e473383081e38478b69993b1"
+ integrity sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==
+ dependencies:
+ "@babel/core" "^7.23.9"
+ "@babel/parser" "^7.23.9"
+ "@istanbuljs/schema" "^0.1.3"
+ istanbul-lib-coverage "^3.2.0"
+ semver "^7.5.4"
+
+istanbul-lib-report@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d"
+ integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==
+ dependencies:
+ istanbul-lib-coverage "^3.0.0"
+ make-dir "^4.0.0"
+ supports-color "^7.1.0"
+
+istanbul-lib-source-maps@^4.0.0:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551"
+ integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==
+ dependencies:
+ debug "^4.1.1"
+ istanbul-lib-coverage "^3.0.0"
+ source-map "^0.6.1"
+
+istanbul-reports@^3.1.3:
+ version "3.1.7"
+ resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.7.tgz#daed12b9e1dca518e15c056e1e537e741280fa0b"
+ integrity sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==
+ dependencies:
+ html-escaper "^2.0.0"
+ istanbul-lib-report "^3.0.0"
+
+jackspeak@^3.1.2:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.1.2.tgz#eada67ea949c6b71de50f1b09c92a961897b90ab"
+ integrity sha512-kWmLKn2tRtfYMF/BakihVVRzBKOxz4gJMiL2Rj91WnAB5TPZumSH99R/Yf1qE1u4uRimvCSJfm6hnxohXeEXjQ==
dependencies:
"@isaacs/cliui" "^8.0.2"
optionalDependencies:
"@pkgjs/parseargs" "^0.11.0"
-jest-environment-node@^29.6.3:
+jest-changed-files@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a"
+ integrity sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==
+ dependencies:
+ execa "^5.0.0"
+ jest-util "^29.7.0"
+ p-limit "^3.1.0"
+
+jest-circus@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.7.0.tgz#b6817a45fcc835d8b16d5962d0c026473ee3668a"
+ integrity sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==
+ dependencies:
+ "@jest/environment" "^29.7.0"
+ "@jest/expect" "^29.7.0"
+ "@jest/test-result" "^29.7.0"
+ "@jest/types" "^29.6.3"
+ "@types/node" "*"
+ chalk "^4.0.0"
+ co "^4.6.0"
+ dedent "^1.0.0"
+ is-generator-fn "^2.0.0"
+ jest-each "^29.7.0"
+ jest-matcher-utils "^29.7.0"
+ jest-message-util "^29.7.0"
+ jest-runtime "^29.7.0"
+ jest-snapshot "^29.7.0"
+ jest-util "^29.7.0"
+ p-limit "^3.1.0"
+ pretty-format "^29.7.0"
+ pure-rand "^6.0.0"
+ slash "^3.0.0"
+ stack-utils "^2.0.3"
+
+jest-cli@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.7.0.tgz#5592c940798e0cae677eec169264f2d839a37995"
+ integrity sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==
+ dependencies:
+ "@jest/core" "^29.7.0"
+ "@jest/test-result" "^29.7.0"
+ "@jest/types" "^29.6.3"
+ chalk "^4.0.0"
+ create-jest "^29.7.0"
+ exit "^0.1.2"
+ import-local "^3.0.2"
+ jest-config "^29.7.0"
+ jest-util "^29.7.0"
+ jest-validate "^29.7.0"
+ yargs "^17.3.1"
+
+jest-config@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.7.0.tgz#bcbda8806dbcc01b1e316a46bb74085a84b0245f"
+ integrity sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==
+ dependencies:
+ "@babel/core" "^7.11.6"
+ "@jest/test-sequencer" "^29.7.0"
+ "@jest/types" "^29.6.3"
+ babel-jest "^29.7.0"
+ chalk "^4.0.0"
+ ci-info "^3.2.0"
+ deepmerge "^4.2.2"
+ glob "^7.1.3"
+ graceful-fs "^4.2.9"
+ jest-circus "^29.7.0"
+ jest-environment-node "^29.7.0"
+ jest-get-type "^29.6.3"
+ jest-regex-util "^29.6.3"
+ jest-resolve "^29.7.0"
+ jest-runner "^29.7.0"
+ jest-util "^29.7.0"
+ jest-validate "^29.7.0"
+ micromatch "^4.0.4"
+ parse-json "^5.2.0"
+ pretty-format "^29.7.0"
+ slash "^3.0.0"
+ strip-json-comments "^3.1.1"
+
+jest-diff@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a"
+ integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==
+ dependencies:
+ chalk "^4.0.0"
+ diff-sequences "^29.6.3"
+ jest-get-type "^29.6.3"
+ pretty-format "^29.7.0"
+
+jest-docblock@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.7.0.tgz#8fddb6adc3cdc955c93e2a87f61cfd350d5d119a"
+ integrity sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==
+ dependencies:
+ detect-newline "^3.0.0"
+
+jest-each@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.7.0.tgz#162a9b3f2328bdd991beaabffbb74745e56577d1"
+ integrity sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==
+ dependencies:
+ "@jest/types" "^29.6.3"
+ chalk "^4.0.0"
+ jest-get-type "^29.6.3"
+ jest-util "^29.7.0"
+ pretty-format "^29.7.0"
+
+jest-environment-jsdom@^29.2.1:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-29.7.0.tgz#d206fa3551933c3fd519e5dfdb58a0f5139a837f"
+ integrity sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==
+ dependencies:
+ "@jest/environment" "^29.7.0"
+ "@jest/fake-timers" "^29.7.0"
+ "@jest/types" "^29.6.3"
+ "@types/jsdom" "^20.0.0"
+ "@types/node" "*"
+ jest-mock "^29.7.0"
+ jest-util "^29.7.0"
+ jsdom "^20.0.0"
+
+jest-environment-node@^29.6.3, jest-environment-node@^29.7.0:
version "29.7.0"
resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376"
integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==
@@ -5235,11 +5899,66 @@ jest-environment-node@^29.6.3:
jest-mock "^29.7.0"
jest-util "^29.7.0"
+jest-expo@~51.0.1:
+ version "51.0.2"
+ resolved "https://registry.yarnpkg.com/jest-expo/-/jest-expo-51.0.2.tgz#9c06ed5e890acf835a84200deb0969738e9f8721"
+ integrity sha512-ijIcjEASh2uORA3DBubOiIJTrPZXp8J3FedaEdnZPT09FkyTH8tZXp/ZRv37LKUomGA5XEHDYR2FY3UMfdIa7g==
+ dependencies:
+ "@expo/config" "~9.0.0"
+ "@expo/json-file" "^8.3.0"
+ "@jest/create-cache-key-function" "^29.2.1"
+ babel-jest "^29.2.1"
+ find-up "^5.0.0"
+ jest-environment-jsdom "^29.2.1"
+ jest-watch-select-projects "^2.0.0"
+ jest-watch-typeahead "2.2.1"
+ json5 "^2.2.3"
+ lodash "^4.17.19"
+ react-test-renderer "18.2.0"
+ stacktrace-js "^2.0.2"
+
jest-get-type@^29.6.3:
version "29.6.3"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1"
integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==
+jest-haste-map@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.7.0.tgz#3c2396524482f5a0506376e6c858c3bbcc17b104"
+ integrity sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==
+ dependencies:
+ "@jest/types" "^29.6.3"
+ "@types/graceful-fs" "^4.1.3"
+ "@types/node" "*"
+ anymatch "^3.0.3"
+ fb-watchman "^2.0.0"
+ graceful-fs "^4.2.9"
+ jest-regex-util "^29.6.3"
+ jest-util "^29.7.0"
+ jest-worker "^29.7.0"
+ micromatch "^4.0.4"
+ walker "^1.0.8"
+ optionalDependencies:
+ fsevents "^2.3.2"
+
+jest-leak-detector@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz#5b7ec0dadfdfec0ca383dc9aa016d36b5ea4c728"
+ integrity sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==
+ dependencies:
+ jest-get-type "^29.6.3"
+ pretty-format "^29.7.0"
+
+jest-matcher-utils@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12"
+ integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==
+ dependencies:
+ chalk "^4.0.0"
+ jest-diff "^29.7.0"
+ jest-get-type "^29.6.3"
+ pretty-format "^29.7.0"
+
jest-message-util@^29.7.0:
version "29.7.0"
resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3"
@@ -5264,6 +5983,120 @@ jest-mock@^29.7.0:
"@types/node" "*"
jest-util "^29.7.0"
+jest-pnp-resolver@^1.2.2:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e"
+ integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==
+
+jest-regex-util@^29.0.0, jest-regex-util@^29.6.3:
+ version "29.6.3"
+ resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.6.3.tgz#4a556d9c776af68e1c5f48194f4d0327d24e8a52"
+ integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==
+
+jest-resolve-dependencies@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz#1b04f2c095f37fc776ff40803dc92921b1e88428"
+ integrity sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==
+ dependencies:
+ jest-regex-util "^29.6.3"
+ jest-snapshot "^29.7.0"
+
+jest-resolve@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.7.0.tgz#64d6a8992dd26f635ab0c01e5eef4399c6bcbc30"
+ integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==
+ dependencies:
+ chalk "^4.0.0"
+ graceful-fs "^4.2.9"
+ jest-haste-map "^29.7.0"
+ jest-pnp-resolver "^1.2.2"
+ jest-util "^29.7.0"
+ jest-validate "^29.7.0"
+ resolve "^1.20.0"
+ resolve.exports "^2.0.0"
+ slash "^3.0.0"
+
+jest-runner@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.7.0.tgz#809af072d408a53dcfd2e849a4c976d3132f718e"
+ integrity sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==
+ dependencies:
+ "@jest/console" "^29.7.0"
+ "@jest/environment" "^29.7.0"
+ "@jest/test-result" "^29.7.0"
+ "@jest/transform" "^29.7.0"
+ "@jest/types" "^29.6.3"
+ "@types/node" "*"
+ chalk "^4.0.0"
+ emittery "^0.13.1"
+ graceful-fs "^4.2.9"
+ jest-docblock "^29.7.0"
+ jest-environment-node "^29.7.0"
+ jest-haste-map "^29.7.0"
+ jest-leak-detector "^29.7.0"
+ jest-message-util "^29.7.0"
+ jest-resolve "^29.7.0"
+ jest-runtime "^29.7.0"
+ jest-util "^29.7.0"
+ jest-watcher "^29.7.0"
+ jest-worker "^29.7.0"
+ p-limit "^3.1.0"
+ source-map-support "0.5.13"
+
+jest-runtime@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.7.0.tgz#efecb3141cf7d3767a3a0cc8f7c9990587d3d817"
+ integrity sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==
+ dependencies:
+ "@jest/environment" "^29.7.0"
+ "@jest/fake-timers" "^29.7.0"
+ "@jest/globals" "^29.7.0"
+ "@jest/source-map" "^29.6.3"
+ "@jest/test-result" "^29.7.0"
+ "@jest/transform" "^29.7.0"
+ "@jest/types" "^29.6.3"
+ "@types/node" "*"
+ chalk "^4.0.0"
+ cjs-module-lexer "^1.0.0"
+ collect-v8-coverage "^1.0.0"
+ glob "^7.1.3"
+ graceful-fs "^4.2.9"
+ jest-haste-map "^29.7.0"
+ jest-message-util "^29.7.0"
+ jest-mock "^29.7.0"
+ jest-regex-util "^29.6.3"
+ jest-resolve "^29.7.0"
+ jest-snapshot "^29.7.0"
+ jest-util "^29.7.0"
+ slash "^3.0.0"
+ strip-bom "^4.0.0"
+
+jest-snapshot@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.7.0.tgz#c2c574c3f51865da1bb329036778a69bf88a6be5"
+ integrity sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==
+ dependencies:
+ "@babel/core" "^7.11.6"
+ "@babel/generator" "^7.7.2"
+ "@babel/plugin-syntax-jsx" "^7.7.2"
+ "@babel/plugin-syntax-typescript" "^7.7.2"
+ "@babel/types" "^7.3.3"
+ "@jest/expect-utils" "^29.7.0"
+ "@jest/transform" "^29.7.0"
+ "@jest/types" "^29.6.3"
+ babel-preset-current-node-syntax "^1.0.0"
+ chalk "^4.0.0"
+ expect "^29.7.0"
+ graceful-fs "^4.2.9"
+ jest-diff "^29.7.0"
+ jest-get-type "^29.6.3"
+ jest-matcher-utils "^29.7.0"
+ jest-message-util "^29.7.0"
+ jest-util "^29.7.0"
+ natural-compare "^1.4.0"
+ pretty-format "^29.7.0"
+ semver "^7.5.3"
+
jest-util@^29.7.0:
version "29.7.0"
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc"
@@ -5276,7 +6109,7 @@ jest-util@^29.7.0:
graceful-fs "^4.2.9"
picomatch "^2.2.3"
-jest-validate@^29.6.3:
+jest-validate@^29.6.3, jest-validate@^29.7.0:
version "29.7.0"
resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c"
integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==
@@ -5288,7 +6121,43 @@ jest-validate@^29.6.3:
leven "^3.1.0"
pretty-format "^29.7.0"
-jest-worker@^29.6.3:
+jest-watch-select-projects@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/jest-watch-select-projects/-/jest-watch-select-projects-2.0.0.tgz#4373d7e4de862aae28b46e036b669a4c913ea867"
+ integrity sha512-j00nW4dXc2NiCW6znXgFLF9g8PJ0zP25cpQ1xRro/HU2GBfZQFZD0SoXnAlaoKkIY4MlfTMkKGbNXFpvCdjl1w==
+ dependencies:
+ ansi-escapes "^4.3.0"
+ chalk "^3.0.0"
+ prompts "^2.2.1"
+
+jest-watch-typeahead@2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-2.2.1.tgz#36601520a2a30fd561788552dbda9c76bb44814a"
+ integrity sha512-jYpYmUnTzysmVnwq49TAxlmtOAwp8QIqvZyoofQFn8fiWhEDZj33ZXzg3JA4nGnzWFm1hbWf3ADpteUokvXgFA==
+ dependencies:
+ ansi-escapes "^6.0.0"
+ chalk "^4.0.0"
+ jest-regex-util "^29.0.0"
+ jest-watcher "^29.0.0"
+ slash "^5.0.0"
+ string-length "^5.0.1"
+ strip-ansi "^7.0.1"
+
+jest-watcher@^29.0.0, jest-watcher@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.7.0.tgz#7810d30d619c3a62093223ce6bb359ca1b28a2f2"
+ integrity sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==
+ dependencies:
+ "@jest/test-result" "^29.7.0"
+ "@jest/types" "^29.6.3"
+ "@types/node" "*"
+ ansi-escapes "^4.2.1"
+ chalk "^4.0.0"
+ emittery "^0.13.1"
+ jest-util "^29.7.0"
+ string-length "^4.0.1"
+
+jest-worker@^29.6.3, jest-worker@^29.7.0:
version "29.7.0"
resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a"
integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==
@@ -5298,6 +6167,16 @@ jest-worker@^29.6.3:
merge-stream "^2.0.0"
supports-color "^8.0.0"
+jest@^29.2.1:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest/-/jest-29.7.0.tgz#994676fc24177f088f1c5e3737f5697204ff2613"
+ integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==
+ dependencies:
+ "@jest/core" "^29.7.0"
+ "@jest/types" "^29.6.3"
+ import-local "^3.0.2"
+ jest-cli "^29.7.0"
+
jimp-compact@0.16.1:
version "0.16.1"
resolved "https://registry.yarnpkg.com/jimp-compact/-/jimp-compact-0.16.1.tgz#9582aea06548a2c1e04dd148d7c3ab92075aefa3"
@@ -5379,6 +6258,38 @@ jscodeshift@^0.14.0:
temp "^0.8.4"
write-file-atomic "^2.3.0"
+jsdom@^20.0.0:
+ version "20.0.3"
+ resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-20.0.3.tgz#886a41ba1d4726f67a8858028c99489fed6ad4db"
+ integrity sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==
+ dependencies:
+ abab "^2.0.6"
+ acorn "^8.8.1"
+ acorn-globals "^7.0.0"
+ cssom "^0.5.0"
+ cssstyle "^2.3.0"
+ data-urls "^3.0.2"
+ decimal.js "^10.4.2"
+ domexception "^4.0.0"
+ escodegen "^2.0.0"
+ form-data "^4.0.0"
+ html-encoding-sniffer "^3.0.0"
+ http-proxy-agent "^5.0.0"
+ https-proxy-agent "^5.0.1"
+ is-potential-custom-element-name "^1.0.1"
+ nwsapi "^2.2.2"
+ parse5 "^7.1.1"
+ saxes "^6.0.0"
+ symbol-tree "^3.2.4"
+ tough-cookie "^4.1.2"
+ w3c-xmlserializer "^4.0.0"
+ webidl-conversions "^7.0.0"
+ whatwg-encoding "^2.0.0"
+ whatwg-mimetype "^3.0.0"
+ whatwg-url "^11.0.0"
+ ws "^8.11.0"
+ xml-name-validator "^4.0.0"
+
jsesc@^2.5.1:
version "2.5.2"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
@@ -5399,6 +6310,11 @@ json-parse-better-errors@^1.0.1:
resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==
+json-parse-even-better-errors@^2.3.0:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
+ integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
+
json-schema-deref-sync@^0.13.0:
version "0.13.0"
resolved "https://registry.yarnpkg.com/json-schema-deref-sync/-/json-schema-deref-sync-0.13.0.tgz#cb08b4ff435a48b5a149652d7750fdd071009823"
@@ -5721,7 +6637,7 @@ lodash.throttle@^4.1.1:
resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==
-lodash@^4.17.13, lodash@^4.17.21:
+lodash@^4.17.13, lodash@^4.17.19, lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -5800,6 +6716,13 @@ make-dir@^2.0.0, make-dir@^2.1.0:
pify "^4.0.1"
semver "^5.6.0"
+make-dir@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e"
+ integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==
+ dependencies:
+ semver "^7.5.3"
+
make-error@^1.1.1:
version "1.3.6"
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
@@ -6343,11 +7266,6 @@ nodemon@^3.1.0:
touch "^3.1.0"
undefsafe "^2.0.5"
-noop-fn@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/noop-fn/-/noop-fn-1.0.0.tgz#5f33d47f13d2150df93e0cb036699e982f78ffbf"
- integrity sha512-pQ8vODlgXt2e7A3mIbFDlizkr46r75V+BJxVAyat8Jl7YmI513gG5cfyRL0FedKraoZ+VAouI1h4/IWpus5pcQ==
-
normalize-path@^3.0.0, normalize-path@~3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
@@ -6396,6 +7314,11 @@ nullthrows@^1.1.1:
resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1"
integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==
+nwsapi@^2.2.2:
+ version "2.2.10"
+ resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.10.tgz#0b77a68e21a0b483db70b11fad055906e867cda8"
+ integrity sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==
+
ob1@0.80.9:
version "0.80.9"
resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.80.9.tgz#4ae3edd807536097674ff943509089f5d4e0649f"
@@ -6576,7 +7499,7 @@ p-limit@^2.0.0, p-limit@^2.2.0:
dependencies:
p-try "^2.0.0"
-p-limit@^3.0.2:
+p-limit@^3.0.2, p-limit@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
@@ -6631,6 +7554,16 @@ parse-json@^4.0.0:
error-ex "^1.3.1"
json-parse-better-errors "^1.0.1"
+parse-json@^5.2.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd"
+ integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==
+ dependencies:
+ "@babel/code-frame" "^7.0.0"
+ error-ex "^1.3.1"
+ json-parse-even-better-errors "^2.3.0"
+ lines-and-columns "^1.1.6"
+
parse-png@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/parse-png/-/parse-png-2.1.0.tgz#2a42ad719fedf90f81c59ebee7ae59b280d6b338"
@@ -6638,6 +7571,13 @@ parse-png@^2.1.0:
dependencies:
pngjs "^3.3.0"
+parse5@^7.0.0, parse5@^7.1.1:
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32"
+ integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==
+ dependencies:
+ entities "^4.4.0"
+
parseurl@~1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
@@ -6762,7 +7702,7 @@ pify@^4.0.1:
resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==
-pirates@^4.0.1, pirates@^4.0.6:
+pirates@^4.0.1, pirates@^4.0.4, pirates@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9"
integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==
@@ -6774,6 +7714,13 @@ pkg-dir@^3.0.0:
dependencies:
find-up "^3.0.0"
+pkg-dir@^4.2.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
+ integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
+ dependencies:
+ find-up "^4.0.0"
+
plist@^3.0.5:
version "3.1.0"
resolved "https://registry.yarnpkg.com/plist/-/plist-3.1.0.tgz#797a516a93e62f5bde55e0b9cc9c967f860893c9"
@@ -6885,11 +7832,6 @@ postinstall-postinstall@^2.1.0:
resolved "https://registry.yarnpkg.com/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz#4f7f77441ef539d1512c40bd04c71b06a4704ca3"
integrity sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==
-pouchdb-collections@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/pouchdb-collections/-/pouchdb-collections-1.0.1.tgz#fe63a17da977611abef7cb8026cb1a9553fd8359"
- integrity sha512-31db6JRg4+4D5Yzc2nqsRqsA2oOkZS8DpFav3jf/qVNBxusKa2ClkEIZ2bJNpaDbMfWtnuSq59p6Bn+CipPMdg==
-
prelude-ls@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
@@ -6925,7 +7867,7 @@ pretty-format@^26.5.2, pretty-format@^26.6.2:
ansi-styles "^4.0.0"
react-is "^17.0.1"
-pretty-format@^29.7.0:
+pretty-format@^29.0.0, pretty-format@^29.7.0:
version "29.7.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812"
integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==
@@ -6965,7 +7907,7 @@ promise@^8.3.0:
dependencies:
asap "~2.0.6"
-prompts@^2.3.2, prompts@^2.4.2:
+prompts@^2.0.1, prompts@^2.2.1, prompts@^2.3.2, prompts@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069"
integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==
@@ -6973,7 +7915,7 @@ prompts@^2.3.2, prompts@^2.4.2:
kleur "^3.0.3"
sisteransi "^1.0.5"
-prop-types@^15.8.1:
+prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -6990,6 +7932,11 @@ proxy-addr@~2.0.7:
forwarded "0.2.0"
ipaddr.js "1.9.1"
+psl@^1.1.33:
+ version "1.9.0"
+ resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"
+ integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==
+
pstree.remy@^1.1.8:
version "1.1.8"
resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a"
@@ -7008,7 +7955,7 @@ punycode@^2.1.0, punycode@^2.1.1:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
-pure-rand@^6.1.0:
+pure-rand@^6.0.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.1.0.tgz#d173cf23258231976ccbdb05247c9787957604f2"
integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==
@@ -7040,6 +7987,11 @@ querystring@^0.2.1:
resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd"
integrity sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==
+querystringify@^2.1.1:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
+ integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==
+
queue-microtask@^1.2.2:
version "1.2.3"
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
@@ -7085,13 +8037,13 @@ react-devtools-core@^5.0.0:
shell-quote "^1.6.1"
ws "^7"
-react-dom@^18.2.0:
- version "18.3.1"
- resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4"
- integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==
+react-dom@18.2.0:
+ version "18.2.0"
+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
+ integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
dependencies:
loose-envify "^1.1.0"
- scheduler "^0.23.2"
+ scheduler "^0.23.0"
react-fast-compare@^3.2.2:
version "3.2.2"
@@ -7103,12 +8055,12 @@ react-freeze@^1.0.0:
resolved "https://registry.yarnpkg.com/react-freeze/-/react-freeze-1.0.4.tgz#cbbea2762b0368b05cbe407ddc9d518c57c6f3ad"
integrity sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA==
-"react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^18.0.0:
+"react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^18.0.0, react-is@^18.2.0:
version "18.3.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e"
integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==
-react-is@^16.13.0, react-is@^16.13.1:
+react-is@^16.13.0, react-is@^16.13.1, react-is@^16.7.0:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
@@ -7129,6 +8081,17 @@ react-native-css-interop@0.0.36:
babel-plugin-tester "^11.0.4"
lightningcss "1.22.0"
+react-native-gesture-handler@~2.16.1:
+ version "2.16.2"
+ resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-2.16.2.tgz#032bd2a07334292d7f6cff1dc9d1ec928f72e26d"
+ integrity sha512-vGFlrDKlmyI+BT+FemqVxmvO7nqxU33cgXVsn6IKAFishvlG3oV2Ds67D5nPkHMea8T+s1IcuMm0bF8ntZtAyg==
+ dependencies:
+ "@egjs/hammerjs" "^2.0.17"
+ hoist-non-react-statics "^3.3.0"
+ invariant "^2.2.4"
+ lodash "^4.17.21"
+ prop-types "^15.7.2"
+
react-native-helmet-async@2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/react-native-helmet-async/-/react-native-helmet-async-2.0.4.tgz#93f53a1ff22d6898039688a541653a2d6b6866bb"
@@ -7149,10 +8112,17 @@ react-native-libsodium@^1.3.1:
libsodium-wrappers "^0.7.13"
libsodium-wrappers-sumo "^0.7.13"
-react-native-reanimated@~3.11.0:
- version "3.11.0"
- resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-3.11.0.tgz#d4265d4e0232623f5958ed60e1686ca884fc3452"
- integrity sha512-BNw/XDgUfs8UhfY1X6IniU8kWpnotWGyt8qmQviaHisTi5lvwnaOdXQKfN1KGONx6ekdFRHRP5EFwLi0UajwKA==
+react-native-opaque@^0.3.1:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/react-native-opaque/-/react-native-opaque-0.3.1.tgz#a01672064ad0d9b12b0c07d18555ed872f39956c"
+ integrity sha512-DShK07S9uUquI0L9ErHvhudQOzoOrCQSdyieHrXCL2RMb2IXPhS3Qmb+av47vlHbYQQvhXRwd4fUAKGsa+vN1A==
+ dependencies:
+ "@serenity-kit/opaque" "^0.8.0"
+
+react-native-reanimated@~3.10.1:
+ version "3.10.1"
+ resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-3.10.1.tgz#3c37d1100bbba0065df39c96aab0c1ff1b50c0fa"
+ integrity sha512-sfxg6vYphrDc/g4jf/7iJ7NRi+26z2+BszPmvmk0Vnrz6FL7HYljJqTf531F1x6tFmsf+FEAmuCtTUIXFLVo9w==
dependencies:
"@babel/plugin-transform-arrow-functions" "^7.0.0-0"
"@babel/plugin-transform-nullish-coalescing-operator" "^7.0.0-0"
@@ -7163,10 +8133,10 @@ react-native-reanimated@~3.11.0:
convert-source-map "^2.0.0"
invariant "^2.2.4"
-react-native-safe-area-context@4.10.3:
- version "4.10.3"
- resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-4.10.3.tgz#ad132b64e1e7cdd043b4e82a7a2449d99f4f7630"
- integrity sha512-nW9B0fydpJSN798awtdslamYzRqDM/FIEh80ZPDEXVYpqYNsDLpz52pMtuKyhF5aOgJlfiroQrgdOxQNFtSM8A==
+react-native-safe-area-context@4.10.1:
+ version "4.10.1"
+ resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-4.10.1.tgz#29fb27395ff7dfa2fa38788a27226330d73a81cc"
+ integrity sha512-w8tCuowDorUkPoWPXmhqosovBr33YsukkwYCDERZFHAxIkx6qBadYxfeoaJ91nCQKjkNzGrK5qhoNOeSIcYSpA==
react-native-screens@3.31.1:
version "3.31.1"
@@ -7176,15 +8146,15 @@ react-native-screens@3.31.1:
react-freeze "^1.0.0"
warn-once "^0.1.0"
-react-native-svg@15.3.0:
- version "15.3.0"
- resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-15.3.0.tgz#e24b833fe330714c99f1dd894bb0da52ad859a4c"
- integrity sha512-mBHu/fdlzUbpGX8SZFxgbKvK/sgqLfDLP8uh8G7Us+zJgdjO8OSEeqHQs+kPRdQmdLJQiqPJX2WXgCl7ToTWqw==
+react-native-svg@15.2.0:
+ version "15.2.0"
+ resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-15.2.0.tgz#9561a6b3bd6b44689f437ba13182afee33bd5557"
+ integrity sha512-R0E6IhcJfVLsL0lRmnUSm72QO+mTqcAOM5Jb8FVGxJqX3NfJMlMP0YyvcajZiaRR8CqQUpEoqrY25eyZb006kw==
dependencies:
css-select "^5.1.0"
css-tree "^1.1.3"
-react-native-web@~0.19.6:
+react-native-web@~0.19.10:
version "0.19.12"
resolved "https://registry.yarnpkg.com/react-native-web/-/react-native-web-0.19.12.tgz#30d1fd70bdff7886f43c0c2698629d830fade6bc"
integrity sha512-o2T0oztoVDQjztt4YksO9S1XRjoH/AqcSvifgWLrPJgGVbMWsfhILgl6lfUdEamVZzZSVV/2gqDVMAk/qq7mZw==
@@ -7254,10 +8224,19 @@ react-shallow-renderer@^16.15.0:
object-assign "^4.1.1"
react-is "^16.12.0 || ^17.0.0 || ^18.0.0"
-react@18.3.1:
- version "18.3.1"
- resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891"
- integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==
+react-test-renderer@18.2.0:
+ version "18.2.0"
+ resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-18.2.0.tgz#1dd912bd908ff26da5b9fca4fd1c489b9523d37e"
+ integrity sha512-JWD+aQ0lh2gvh4NM3bBM42Kx+XybOxCpgYK7F8ugAlpaTSnWsX+39Z4XkOykGZAHrjwwTZT3x3KxswVWxHPUqA==
+ dependencies:
+ react-is "^18.2.0"
+ react-shallow-renderer "^16.15.0"
+ scheduler "^0.23.0"
+
+react@18.2.0:
+ version "18.2.0"
+ resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
+ integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
dependencies:
loose-envify "^1.1.0"
@@ -7392,6 +8371,18 @@ requireg@^0.2.2:
rc "~1.2.7"
resolve "~1.7.1"
+requires-port@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
+ integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==
+
+resolve-cwd@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d"
+ integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==
+ dependencies:
+ resolve-from "^5.0.0"
+
resolve-from@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748"
@@ -7407,12 +8398,12 @@ resolve-from@^5.0.0:
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
-resolve.exports@^2.0.2:
+resolve.exports@^2.0.0, resolve.exports@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800"
integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==
-resolve@^1.1.7, resolve@^1.14.2, resolve@^1.22.2:
+resolve@^1.1.7, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.2:
version "1.22.8"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
@@ -7531,7 +8522,7 @@ safe-regex-test@^1.0.3:
es-errors "^1.3.0"
is-regex "^1.1.4"
-"safer-buffer@>= 2.1.2 < 3":
+"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0":
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
@@ -7541,6 +8532,13 @@ sax@>=0.6.0:
resolved "https://registry.yarnpkg.com/sax/-/sax-1.4.1.tgz#44cc8988377f126304d3b3fc1010c733b929ef0f"
integrity sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==
+saxes@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/saxes/-/saxes-6.0.0.tgz#fe5b4a4768df4f14a201b1ba6a65c1f3d9988cc5"
+ integrity sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==
+ dependencies:
+ xmlchars "^2.2.0"
+
scheduler@0.24.0-canary-efb381bbf-20230505:
version "0.24.0-canary-efb381bbf-20230505"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.24.0-canary-efb381bbf-20230505.tgz#5dddc60e29f91cd7f8b983d7ce4a99c2202d178f"
@@ -7548,7 +8546,7 @@ scheduler@0.24.0-canary-efb381bbf-20230505:
dependencies:
loose-envify "^1.1.0"
-scheduler@^0.23.2:
+scheduler@^0.23.0:
version "0.23.2"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3"
integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==
@@ -7605,7 +8603,7 @@ semver@^5.5.0, semver@^5.6.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8"
integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==
-semver@^6.3.1:
+semver@^6.3.0, semver@^6.3.1:
version "6.3.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
@@ -7742,7 +8740,7 @@ side-channel@^1.0.4:
get-intrinsic "^1.2.4"
object-inspect "^1.13.1"
-signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3:
+signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7:
version "3.0.7"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
@@ -7785,6 +8783,11 @@ slash@^3.0.0:
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
+slash@^5.0.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/slash/-/slash-5.1.0.tgz#be3adddcdf09ac38eebe8dcdc7b1a57a75b095ce"
+ integrity sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==
+
slice-ansi@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636"
@@ -7820,6 +8823,14 @@ source-map-js@^1.2.0:
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af"
integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==
+source-map-support@0.5.13:
+ version "0.5.13"
+ resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932"
+ integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==
+ dependencies:
+ buffer-from "^1.0.0"
+ source-map "^0.6.0"
+
source-map-support@^0.5.16, source-map-support@^0.5.21, source-map-support@~0.5.20, source-map-support@~0.5.21:
version "0.5.21"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
@@ -7828,6 +8839,11 @@ source-map-support@^0.5.16, source-map-support@^0.5.21, source-map-support@~0.5.
buffer-from "^1.0.0"
source-map "^0.6.0"
+source-map@0.5.6:
+ version "0.5.6"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
+ integrity sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==
+
source-map@^0.5.6:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
@@ -7867,6 +8883,13 @@ ssri@^10.0.0:
dependencies:
minipass "^7.0.3"
+stack-generator@^2.0.5:
+ version "2.0.10"
+ resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.10.tgz#8ae171e985ed62287d4f1ed55a1633b3fb53bb4d"
+ integrity sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==
+ dependencies:
+ stackframe "^1.3.4"
+
stack-utils@^2.0.3:
version "2.0.6"
resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f"
@@ -7879,6 +8902,23 @@ stackframe@^1.3.4:
resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310"
integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==
+stacktrace-gps@^3.0.4:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.1.2.tgz#0c40b24a9b119b20da4525c398795338966a2fb0"
+ integrity sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==
+ dependencies:
+ source-map "0.5.6"
+ stackframe "^1.3.4"
+
+stacktrace-js@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/stacktrace-js/-/stacktrace-js-2.0.2.tgz#4ca93ea9f494752d55709a081d400fdaebee897b"
+ integrity sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==
+ dependencies:
+ error-stack-parser "^2.0.6"
+ stack-generator "^2.0.5"
+ stacktrace-gps "^3.0.4"
+
stacktrace-parser@^0.1.10:
version "0.1.10"
resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a"
@@ -7916,6 +8956,22 @@ string-argv@~0.3.2:
resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6"
integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==
+string-length@^4.0.1:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a"
+ integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==
+ dependencies:
+ char-regex "^1.0.2"
+ strip-ansi "^6.0.0"
+
+string-length@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/string-length/-/string-length-5.0.1.tgz#3d647f497b6e8e8d41e422f7e0b23bc536c8381e"
+ integrity sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==
+ dependencies:
+ char-regex "^2.0.0"
+ strip-ansi "^7.0.1"
+
"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
@@ -8022,6 +9078,11 @@ strip-ansi@^7.0.1, strip-ansi@^7.1.0:
dependencies:
ansi-regex "^6.0.1"
+strip-bom@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878"
+ integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==
+
strip-eof@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
@@ -8144,6 +9205,11 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
+symbol-tree@^3.2.4:
+ version "3.2.4"
+ resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
+ integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
+
tailwind-merge@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-2.3.0.tgz#27d2134fd00a1f77eca22bcaafdd67055917d286"
@@ -8251,6 +9317,15 @@ terser@^5.15.0:
commander "^2.20.0"
source-map-support "~0.5.20"
+test-exclude@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e"
+ integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==
+ dependencies:
+ "@istanbuljs/schema" "^0.1.2"
+ glob "^7.1.4"
+ minimatch "^3.0.4"
+
text-table@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
@@ -8288,11 +9363,6 @@ through@2:
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
-tiny-queue@^0.2.1:
- version "0.2.1"
- resolved "https://registry.yarnpkg.com/tiny-queue/-/tiny-queue-0.2.1.tgz#25a67f2c6e253b2ca941977b5ef7442ef97a6046"
- integrity sha512-EijGsv7kzd9I9g0ByCl6h42BWNGUZrlCSejfrb3AKeHC33SGbASu1VDf5O3rRiiUOhAC9CHdZxFPbZu0HmR70A==
-
tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
@@ -8327,6 +9397,23 @@ touch@^3.1.0:
resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.1.tgz#097a23d7b161476435e5c1344a95c0f75b4a5694"
integrity sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==
+tough-cookie@^4.1.2:
+ version "4.1.4"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.4.tgz#945f1461b45b5a8c76821c33ea49c3ac192c1b36"
+ integrity sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==
+ dependencies:
+ psl "^1.1.33"
+ punycode "^2.1.1"
+ universalify "^0.2.0"
+ url-parse "^1.5.3"
+
+tr46@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9"
+ integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==
+ dependencies:
+ punycode "^2.1.1"
+
tr46@~0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
@@ -8471,11 +9558,16 @@ typedarray.prototype.slice@^1.0.3:
typed-array-buffer "^1.0.2"
typed-array-byte-offset "^1.0.2"
-typescript@^5.4.5, typescript@~5.4.5:
+typescript@^5.4.5:
version "5.4.5"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611"
integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==
+typescript@~5.3.3:
+ version "5.3.3"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37"
+ integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==
+
ua-parser-js@^1.0.35:
version "1.0.38"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.38.tgz#66bb0c4c0e322fe48edfe6d446df6042e62f25e2"
@@ -8562,6 +9654,11 @@ universalify@^0.1.0:
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
+universalify@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0"
+ integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==
+
universalify@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d"
@@ -8597,6 +9694,14 @@ url-join@4.0.0:
resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.0.tgz#4d3340e807d3773bda9991f8305acdcc2a665d2a"
integrity sha512-EGXjXJZhIHiQMK2pQukuFcL303nskqIRzWvPvV5O8miOfwoUb9G+a/Cld60kUyeaybEI94wvVClT10DtfeAExA==
+url-parse@^1.5.3:
+ version "1.5.10"
+ resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1"
+ integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==
+ dependencies:
+ querystringify "^2.1.1"
+ requires-port "^1.0.0"
+
use-isomorphic-layout-effect@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb"
@@ -8653,6 +9758,15 @@ v8-compile-cache-lib@^3.0.1:
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
+v8-to-istanbul@^9.0.1:
+ version "9.2.0"
+ resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz#2ed7644a245cddd83d4e087b9b33b3e62dfd10ad"
+ integrity sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==
+ dependencies:
+ "@jridgewell/trace-mapping" "^0.3.12"
+ "@types/istanbul-lib-coverage" "^2.0.1"
+ convert-source-map "^2.0.0"
+
valid-url@~1.0.9:
version "1.0.9"
resolved "https://registry.yarnpkg.com/valid-url/-/valid-url-1.0.9.tgz#1c14479b40f1397a75782f115e4086447433a200"
@@ -8675,7 +9789,14 @@ vlq@^1.0.0:
resolved "https://registry.yarnpkg.com/vlq/-/vlq-1.0.1.tgz#c003f6e7c0b4c1edd623fd6ee50bbc0d6a1de468"
integrity sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==
-walker@^1.0.7:
+w3c-xmlserializer@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz#aebdc84920d806222936e3cdce408e32488a3073"
+ integrity sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==
+ dependencies:
+ xml-name-validator "^4.0.0"
+
+walker@^1.0.7, walker@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f"
integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==
@@ -8718,11 +9839,28 @@ webidl-conversions@^5.0.0:
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff"
integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==
+webidl-conversions@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a"
+ integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==
+
+whatwg-encoding@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz#e7635f597fd87020858626805a2729fa7698ac53"
+ integrity sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==
+ dependencies:
+ iconv-lite "0.6.3"
+
whatwg-fetch@^3.0.0:
version "3.6.20"
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz#580ce6d791facec91d37c72890995a0b48d31c70"
integrity sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==
+whatwg-mimetype@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz#5fa1a7623867ff1af6ca3dc72ad6b8a4208beba7"
+ integrity sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==
+
whatwg-url-without-unicode@8.0.0-3:
version "8.0.0-3"
resolved "https://registry.yarnpkg.com/whatwg-url-without-unicode/-/whatwg-url-without-unicode-8.0.0-3.tgz#ab6df4bf6caaa6c85a59f6e82c026151d4bb376b"
@@ -8732,6 +9870,14 @@ whatwg-url-without-unicode@8.0.0-3:
punycode "^2.1.1"
webidl-conversions "^5.0.0"
+whatwg-url@^11.0.0:
+ version "11.0.0"
+ resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-11.0.0.tgz#0a849eebb5faf2119b901bb76fd795c2848d4018"
+ integrity sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==
+ dependencies:
+ tr46 "^3.0.0"
+ webidl-conversions "^7.0.0"
+
whatwg-url@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
@@ -8855,6 +10001,14 @@ write-file-atomic@^2.3.0:
imurmurhash "^0.1.4"
signal-exit "^3.0.2"
+write-file-atomic@^4.0.2:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd"
+ integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==
+ dependencies:
+ imurmurhash "^0.1.4"
+ signal-exit "^3.0.7"
+
ws@^6.2.2:
version "6.2.2"
resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e"
@@ -8867,7 +10021,7 @@ ws@^7, ws@^7.5.1:
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591"
integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==
-ws@^8.12.1, ws@^8.17.0:
+ws@^8.11.0, ws@^8.12.1, ws@^8.17.0:
version "8.17.0"
resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.0.tgz#d145d18eca2ed25aaf791a183903f7be5e295fea"
integrity sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==
@@ -8880,6 +10034,11 @@ xcode@^3.0.1:
simple-plist "^1.1.0"
uuid "^7.0.3"
+xml-name-validator@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835"
+ integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==
+
xml2js@0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.6.0.tgz#07afc447a97d2bd6507a1f76eeadddb09f7a8282"
@@ -8903,6 +10062,11 @@ xmlbuilder@~11.0.0:
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3"
integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==
+xmlchars@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
+ integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
+
xstate@^5.13.0:
version "5.13.0"
resolved "https://registry.yarnpkg.com/xstate/-/xstate-5.13.0.tgz#7f7092d813a89d94024b083fe23a86b6cf4a323a"
@@ -8975,7 +10139,7 @@ yargs@^15.1.0:
y18n "^4.0.0"
yargs-parser "^18.1.2"
-yargs@^17.6.2:
+yargs@^17.3.1, yargs@^17.6.2:
version "17.7.2"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"
integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==