diff --git a/Account.js b/Account.js
deleted file mode 100644
index f520a47..0000000
--- a/Account.js
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2023 The Casdoor Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import totp from "totp-generator";
-
-class Account {
- constructor(accountName, issuer, secretKey, onUpdate) {
- this.accountName = accountName;
- this.secretKey = secretKey;
- this.onUpdate = onUpdate;
- this.token = this.generateToken();
- this.isEditing = false;
- this.issuer = issuer;
- }
-
- calculateCountdown() {
- const currentTime = Math.floor(Date.now() / 1000);
- return 30 - (currentTime % 30);
- }
-
- generateToken() {
- if (this.secretKey !== null && this.secretKey !== undefined && this.secretKey !== "") {
- const token = totp(this.secretKey);
- const tokenWithSpace = token.slice(0, 3) + " " + token.slice(3);
- return tokenWithSpace;
- }
- }
-
- generateAndSetToken() {
- this.token = this.generateToken();
- this.onUpdate();
- }
-
- setAccountName(accountName) {
- this.accountName = accountName;
- this.setEditingStatus(false);
- }
-
- setEditingStatus(status) {
- this.isEditing = status;
- this.onUpdate();
- }
-
- getEditStatus() {
- return this.isEditing;
- }
-
- deleteAccount() {
- this.onUpdate();
- }
-}
-
-export default Account;
diff --git a/App.js b/App.js
index 8ef8ee7..9061e7f 100644
--- a/App.js
+++ b/App.js
@@ -15,28 +15,24 @@
import * as React from "react";
import {PaperProvider} from "react-native-paper";
import {NavigationContainer} from "@react-navigation/native";
+import {BulletList} from "react-content-loader/native";
+import {SQLiteProvider} from "expo-sqlite";
import Header from "./Header";
import NavigationBar from "./NavigationBar";
-import {UserProvider} from "./UserContext";
-import {CasdoorServerProvider} from "./CasdoorServerContext";
+import {migrateDb} from "./TotpDatabase";
const App = () => {
-
- const [userInfo, setUserInfo] = React.useState(null);
- const [token, setToken] = React.useState(null);
- const [casdoorServer, setCasdoorServer] = React.useState(null);
-
return (
-
-
+ }>
+
-
-
+
+
);
};
export default App;
diff --git a/CasdoorLoginPage.js b/CasdoorLoginPage.js
index 76c96af..2c4b1b1 100644
--- a/CasdoorLoginPage.js
+++ b/CasdoorLoginPage.js
@@ -12,15 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import React, {useEffect} from "react";
+import React, {useEffect, useState} from "react";
import {WebView} from "react-native-webview";
import {View} from "react-native";
import {Portal} from "react-native-paper";
import SDK from "casdoor-react-native-sdk";
-import UserContext from "./UserContext";
import PropTypes from "prop-types";
import EnterCasdoorSdkConfig from "./EnterCasdoorSdkConfig";
-import CasdoorServerContext from "./CasdoorServerContext";
+import useStore from "./useStorage";
// import {LogBox} from "react-native";
// LogBox.ignoreAllLogs();
@@ -29,10 +28,20 @@ const CasdoorLoginPage = ({onWebviewClose}) => {
CasdoorLoginPage.propTypes = {
onWebviewClose: PropTypes.func.isRequired,
};
- const [casdoorLoginURL, setCasdoorLoginURL] = React.useState("");
- const {setUserInfo, setToken} = React.useContext(UserContext);
- const [showConfigPage, setShowConfigPage] = React.useState(true);
- const {casdoorServer} = React.useContext(CasdoorServerContext);
+ const [casdoorLoginURL, setCasdoorLoginURL] = useState("");
+ const [showConfigPage, setShowConfigPage] = useState(true);
+
+ const {
+ serverUrl,
+ clientId,
+ redirectPath,
+ appName,
+ organizationName,
+ getCasdoorConfig,
+ setUserInfo,
+ setToken,
+ } = useStore();
+
const handleHideConfigPage = () => {
setShowConfigPage(false);
};
@@ -42,14 +51,15 @@ const CasdoorLoginPage = ({onWebviewClose}) => {
};
useEffect(() => {
- if (casdoorServer) {
- sdk = new SDK(casdoorServer);
+ if (serverUrl && clientId && redirectPath && appName && organizationName) {
+ sdk = new SDK(getCasdoorConfig());
getCasdoorSignInUrl();
}
- }, [casdoorServer]);
+ }, [serverUrl, clientId, redirectPath, appName, organizationName]);
const onNavigationStateChange = async(navState) => {
- if (navState.url.startsWith(casdoorServer.redirectPath)) {
+ const {redirectPath} = getCasdoorConfig();
+ if (navState.url.startsWith(redirectPath)) {
onWebviewClose();
const token = await sdk.getAccessToken(navState.url);
const userInfo = sdk.JwtDecode(token);
@@ -75,7 +85,9 @@ const CasdoorLoginPage = ({onWebviewClose}) => {
);
};
+
export const CasdoorLogout = () => {
- sdk.clearState();
+ if (sdk) {sdk.clearState();}
};
+
export default CasdoorLoginPage;
diff --git a/CasdoorServerContext.js b/CasdoorServerContext.js
deleted file mode 100644
index fe3d569..0000000
--- a/CasdoorServerContext.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2023 The Casdoor Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import React from "react";
-
-const CasdoorServerContext = React.createContext();
-export const CasdoorServerProvider = CasdoorServerContext.Provider;
-export const CasdoorServerConsumer = CasdoorServerContext.Consumer;
-export default CasdoorServerContext;
diff --git a/EditAccountDetails.js b/EditAccountDetails.js
index 30bcd51..a74cc12 100644
--- a/EditAccountDetails.js
+++ b/EditAccountDetails.js
@@ -29,6 +29,7 @@ export default function EnterAccountDetails({onClose, onEdit, placeholder}) {
const handleConfirm = () => {
onEdit(accountName);
};
+
return (
Enter new account name
diff --git a/EnterCasdoorSdkConfig.js b/EnterCasdoorSdkConfig.js
index aca4460..2de356b 100644
--- a/EnterCasdoorSdkConfig.js
+++ b/EnterCasdoorSdkConfig.js
@@ -12,52 +12,46 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import React, {useState} from "react";
+import React from "react";
import {Alert, Text, View} from "react-native";
import {Button, IconButton, Portal, TextInput} from "react-native-paper";
import DefaultCasdoorSdkConfig from "./DefaultCasdoorSdkConfig";
-import CasdoorServerContext from "./CasdoorServerContext";
import PropTypes from "prop-types";
+import useStore from "./useStorage";
const EnterCasdoorSdkConfig = ({onClose, onWebviewClose}) => {
EnterCasdoorSdkConfig.propTypes = {
onClose: PropTypes.func.isRequired,
};
- const {setCasdoorServer} = React.useContext(CasdoorServerContext);
- const [CasdoorSdkConfig, setCasdoorSdkConfig] = useState({
- serverUrl: "",
- clientId: "",
- appName: "",
- organizationName: "",
- redirectPath: "http://casdoor-app",
- signinPath: "/api/signin",
- });
-
- const handleInputChange = (key, value) => {
- setCasdoorSdkConfig({...CasdoorSdkConfig, [key]: value});
- };
+ const {
+ serverUrl,
+ clientId,
+ redirectPath,
+ appName,
+ organizationName,
+ setServerUrl,
+ setClientId,
+ setAppName,
+ setOrganizationName,
+ setCasdoorConfig,
+ } = useStore();
const closeConfigPage = () => {
onClose();
onWebviewClose();
};
+
const handleSave = () => {
- if (
- !CasdoorSdkConfig.serverUrl ||
- !CasdoorSdkConfig.clientId ||
- !CasdoorSdkConfig.appName ||
- !CasdoorSdkConfig.organizationName ||
- !CasdoorSdkConfig.redirectPath
- ) {
+ if (!serverUrl || !clientId || !appName || !organizationName || !redirectPath) {
Alert.alert("Please fill in all the fields!");
return;
}
- setCasdoorServer(CasdoorSdkConfig);
onClose();
};
+
const handleUseDefault = () => {
- setCasdoorServer(DefaultCasdoorSdkConfig);
+ setCasdoorConfig(DefaultCasdoorSdkConfig);
onClose();
};
@@ -68,8 +62,8 @@ const EnterCasdoorSdkConfig = ({onClose, onWebviewClose}) => {
Casdoor server
handleInputChange("serverUrl", text)}
+ value={serverUrl}
+ onChangeText={setServerUrl}
autoCapitalize="none"
style={{
borderWidth: 3,
@@ -85,8 +79,8 @@ const EnterCasdoorSdkConfig = ({onClose, onWebviewClose}) => {
/>
handleInputChange("clientId", text)}
+ value={clientId}
+ onChangeText={setClientId}
autoCapitalize="none"
style={{
borderWidth: 3,
@@ -102,8 +96,8 @@ const EnterCasdoorSdkConfig = ({onClose, onWebviewClose}) => {
/>
handleInputChange("appName", text)}
+ value={appName}
+ onChangeText={setAppName}
autoCapitalize="none"
style={{
borderWidth: 3,
@@ -119,8 +113,8 @@ const EnterCasdoorSdkConfig = ({onClose, onWebviewClose}) => {
/>
handleInputChange("organizationName", text)}
+ value={organizationName}
+ onChangeText={setOrganizationName}
autoCapitalize="none"
style={{
borderWidth: 3,
@@ -173,4 +167,5 @@ const EnterCasdoorSdkConfig = ({onClose, onWebviewClose}) => {
);
};
+
export default EnterCasdoorSdkConfig;
diff --git a/Header.js b/Header.js
index f471973..e814259 100644
--- a/Header.js
+++ b/Header.js
@@ -13,82 +13,139 @@
// limitations under the License.
import * as React from "react";
-import {Appbar, Avatar, Button, Menu, Text} from "react-native-paper";
-import UserContext from "./UserContext";
-import {StyleSheet, View} from "react-native";
+import {Dimensions, StyleSheet, View} from "react-native";
+import {Appbar, Avatar, Menu, Text, TouchableRipple} from "react-native-paper";
import CasdoorLoginPage, {CasdoorLogout} from "./CasdoorLoginPage";
+import useStore from "./useStorage";
+
+const {width} = Dimensions.get("window");
const Header = () => {
- const {userInfo, setUserInfo, setToken} = React.useContext(UserContext);
+ const {userInfo, clearAll} = useStore();
const [showLoginPage, setShowLoginPage] = React.useState(false);
const [menuVisible, setMenuVisible] = React.useState(false);
+
const openMenu = () => setMenuVisible(true);
const closeMenu = () => setMenuVisible(false);
+
const handleMenuLogoutClicked = () => {
handleCasdoorLogout();
closeMenu();
};
- const handleCasdoorLogin = () => {
- setShowLoginPage(true);
- };
+ const handleCasdoorLogin = () => setShowLoginPage(true);
+ const handleHideLoginPage = () => setShowLoginPage(false);
+
const handleCasdoorLogout = () => {
CasdoorLogout();
- setUserInfo(null);
- setToken(null);
- };
- const handleHideLoginPage = () => {
- setShowLoginPage(false);
+ clearAll();
};
return (
-
-
-
-
-
-
+
+
+
-
+
{showLoginPage && }
-
+
);
};
+const styles = StyleSheet.create({
+ leftContainer: {
+ position: "absolute",
+ left: 0,
+ top: 0,
+ bottom: 0,
+ justifyContent: "center",
+ paddingLeft: width * 0.03,
+ },
+ rightContainer: {
+ position: "absolute",
+ right: 0,
+ top: 0,
+ bottom: 0,
+ justifyContent: "center",
+ paddingRight: width * 0.03,
+ },
+ titleContainer: {
+ position: "absolute",
+ left: 0,
+ right: 0,
+ top: 0,
+ bottom: 0,
+ justifyContent: "center",
+ alignItems: "center",
+ },
+ titleText: {
+ fontSize: Math.max(20, width * 0.045),
+ fontWeight: "bold",
+ textAlign: "center",
+ },
+ buttonContainer: {
+ borderRadius: 20,
+ overflow: "hidden",
+ },
+ buttonContent: {
+ flexDirection: "row",
+ alignItems: "center",
+ justifyContent: "center",
+ paddingVertical: 8,
+ paddingHorizontal: 16,
+ },
+ buttonText: {
+ fontSize: Math.max(14, width * 0.035),
+ fontWeight: "bold",
+ },
+ menuContent: {
+ backgroundColor: "#FFFFFF",
+ borderRadius: 8,
+ elevation: 3,
+ shadowColor: "#000000",
+ shadowOffset: {width: 0, height: 2},
+ shadowOpacity: 0.2,
+ shadowRadius: 3,
+ },
+ avatar: {
+ backgroundColor: "transparent",
+ },
+});
+
export default Header;
diff --git a/HomePage.js b/HomePage.js
index 380104f..d07e3bb 100644
--- a/HomePage.js
+++ b/HomePage.js
@@ -12,21 +12,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import React, {useContext, useEffect, useRef, useState} from "react";
-import {Dimensions, FlatList, RefreshControl, Text, TouchableOpacity, View} from "react-native";
-import {Divider, IconButton, List, Modal, Portal} from "react-native-paper";
+import React, {useEffect, useRef, useState} from "react";
+import {Dimensions, RefreshControl, TouchableOpacity, View} from "react-native";
+import {Divider, IconButton, List, Modal, Portal, Text} from "react-native-paper";
import {GestureHandlerRootView, Swipeable} from "react-native-gesture-handler";
import {CountdownCircleTimer} from "react-native-countdown-circle-timer";
+import {useNetInfo} from "@react-native-community/netinfo";
+import {FlashList} from "@shopify/flash-list";
+import * as SQLite from "expo-sqlite/next";
import SearchBar from "./SearchBar";
import EnterAccountDetails from "./EnterAccountDetails";
import ScanQRCode from "./ScanQRCode";
import EditAccountDetails from "./EditAccountDetails";
import AvatarWithFallback from "./AvatarWithFallback";
-import Account from "./Account";
-import UserContext from "./UserContext";
-import CasdoorServerContext from "./CasdoorServerContext";
-import useSync, {SYNC_STATUS} from "./useSync";
+import * as TotpDatabase from "./TotpDatabase";
+import useStore from "./useStorage";
+import useSyncStore from "./useSyncStore";
const {width, height} = Dimensions.get("window");
const REFRESH_INTERVAL = 10000;
@@ -37,56 +39,83 @@ export default function HomePage() {
const [isPlusButton, setIsPlusButton] = useState(true);
const [showOptions, setShowOptions] = useState(false);
const [showEnterAccountModal, setShowEnterAccountModal] = useState(false);
- const [accountList, setAccountList] = useState([]);
const [searchQuery, setSearchQuery] = useState("");
- const [filteredData, setFilteredData] = useState(accountList);
+ const [accounts, setAccounts] = useState([]);
+ const [filteredData, setFilteredData] = useState(accounts);
const [showScanner, setShowScanner] = useState(false);
const [showEditAccountModal, setShowEditAccountModal] = useState(false);
+ const [editingAccount, setEditingAccount] = useState(null);
const [placeholder, setPlaceholder] = useState("");
const [refreshing, setRefreshing] = useState(false);
+ const {isConnected} = useNetInfo();
+ const [canSync, setCanSync] = useState(false);
const swipeableRef = useRef(null);
- const isSyncing = useRef(false);
+ const {userInfo, serverUrl, token} = useStore();
+ const {startSync} = useSyncStore();
+ const db = SQLite.useSQLiteContext();
- const {userInfo, token} = useContext(UserContext);
- const {casdoorServer} = useContext(CasdoorServerContext);
- const {syncAccounts, syncSignal, resetSyncSignal, addToSyncData} = useSync(userInfo, token, casdoorServer);
-
- const handleSync = async() => {
- if (isSyncing.current) {return;}
- isSyncing.current = true;
- try {
- const syncedAccounts = await syncAccounts();
- if (syncedAccounts.success && syncedAccounts.accountList) {
- accountList.forEach(account => account.deleteAccount());
- const newAccountList = syncedAccounts.accountList.map(account => new Account(
- account.accountName,
- account.issuer,
- account.secretKey,
- onUpdate
- ));
- setAccountList(newAccountList);
- }
- } finally {
- isSyncing.current = false;
- setRefreshing(false);
- resetSyncSignal();
+ useEffect(() => {
+ if (db) {
+ const subscription = SQLite.addDatabaseChangeListener((event) => {loadAccounts();});
+ return () => {if (subscription) {subscription.remove();}};
}
- };
+ }, [db]);
useEffect(() => {
- if ((syncSignal || refreshing) && !isSyncing.current) {
- handleSync();
- }
- }, [syncSignal, refreshing]);
+ setCanSync(Boolean(isConnected && userInfo && serverUrl));
+ }, [isConnected, userInfo, serverUrl]);
+
+ useEffect(() => {
+ setFilteredData(accounts);
+ }, [accounts]);
+
+ useEffect(() => {
+ loadAccounts();
+ }, []);
useEffect(() => {
- const timer = setInterval(handleSync, REFRESH_INTERVAL);
+ const timer = setInterval(() => {
+ if (canSync) {startSync(db, userInfo, serverUrl, token);}
+ }, REFRESH_INTERVAL);
return () => clearInterval(timer);
- }, [handleSync]);
+ }, [startSync]);
+
+ const loadAccounts = async() => {
+ const loadedAccounts = await TotpDatabase.getAllAccounts(db);
+ setAccounts(loadedAccounts);
+ setFilteredData(loadedAccounts);
+ };
- const onRefresh = () => {
+ const onRefresh = async() => {
setRefreshing(true);
+ if (canSync) {await startSync(db, userInfo, serverUrl, token);}
+ setRefreshing(false);
+ };
+
+ const handleAddAccount = async(accountData) => {
+ await TotpDatabase.insertAccount(db, accountData);
+ closeEnterAccountModal();
+ };
+
+ const handleDeleteAccount = async(id) => {
+ await TotpDatabase.deleteAccount(db, id);
+ };
+
+ const handleEditAccount = (account) => {
+ closeSwipeableMenu();
+ setEditingAccount(account);
+ setPlaceholder(account.accountName);
+ setShowEditAccountModal(true);
+ };
+
+ const onAccountEdit = async(newAccountName) => {
+ if (editingAccount) {
+ await TotpDatabase.updateAccountName(db, editingAccount.id, newAccountName);
+ setPlaceholder("");
+ setEditingAccount(null);
+ closeEditAccountModal();
+ }
};
const closeEditAccountModal = () => setShowEditAccountModal(false);
@@ -117,46 +146,6 @@ export default function HomePage() {
const closeEnterAccountModal = () => setShowEnterAccountModal(false);
- const onUpdate = () => setAccountList(prev => [...prev]);
-
- const handleAddAccount = (accountData) => {
- const newAccount = new Account(accountData.accountName, accountData.issuer, accountData.secretKey, onUpdate);
- addToSyncData(newAccount, SYNC_STATUS.ADD);
- newAccount.token = newAccount.generateToken();
-
- setAccountList(prev => [...prev, newAccount]);
- closeEnterAccountModal();
- };
-
- const handleDeleteAccount = (accountName) => {
- const accountToDelete = accountList.find(account => account.accountName === accountName);
- if (accountToDelete) {
- accountToDelete.deleteAccount();
- addToSyncData(accountToDelete, SYNC_STATUS.DELETE);
- }
- setAccountList(prevList => prevList.filter(account => account.accountName !== accountName));
- };
-
- const handleEditAccount = (accountName) => {
- closeSwipeableMenu();
- const accountToEdit = accountList.find(account => account.accountName === accountName);
- if (accountToEdit) {
- setPlaceholder(accountToEdit.accountName);
- setShowEditAccountModal(true);
- accountToEdit.setEditingStatus(true);
- }
- };
-
- const onAccountEdit = (newAccountName) => {
- const accountToEdit = accountList.find(account => account.getEditStatus() === true);
- if (accountToEdit) {
- addToSyncData(accountToEdit, SYNC_STATUS.EDIT, newAccountName);
- accountToEdit.setAccountName(newAccountName);
- }
- setPlaceholder("");
- closeEditAccountModal();
- };
-
const closeSwipeableMenu = () => {
if (swipeableRef.current) {
swipeableRef.current.close();
@@ -166,17 +155,18 @@ export default function HomePage() {
const handleSearch = (query) => {
setSearchQuery(query);
setFilteredData(query.trim() !== ""
- ? accountList.filter(item => item.accountName.toLowerCase().includes(query.toLowerCase()))
- : accountList
+ ? accounts.filter(item => item.accountName.toLowerCase().includes(query.toLowerCase()))
+ : accounts
);
};
return (
- index.toString()}
+ `${item.id}`}
+ estimatedItemSize={10}
refreshControl={
}
@@ -184,17 +174,17 @@ export default function HomePage() {
(
+ renderRightActions={() => (
handleEditAccount(item)}
>
Edit
handleDeleteAccount(item.id)}
>
Delete
@@ -202,36 +192,49 @@ export default function HomePage() {
)}
>
- {item.accountName}
- {item.token}
+
+ {item.accountName}
+ {item.token}
}
- left={(props) => (
+ left={() => (
)}
- right={(props) => (
- {item.generateAndSetToken(); return {shouldRepeat: true};}}
- strokeWidth={5}
- >
- {({remainingTime}) => (
- {remainingTime}s
- )}
-
+ right={() => (
+
+ {
+ TotpDatabase.updateToken(db, item.id);
+ return {shouldRepeat: true, delay: 0};
+ }}
+ strokeWidth={5}
+ >
+ {({remainingTime}) => (
+ {remainingTime}s
+ )}
+
+
)}
/>
diff --git a/SearchBar.js b/SearchBar.js
index cd474df..1561d5b 100644
--- a/SearchBar.js
+++ b/SearchBar.js
@@ -22,6 +22,7 @@ const SearchBar = ({onSearch}) => {
setSearchQuery(query);
onSearch(query);
};
+
return (
{
const [showLoginPage, setShowLoginPage] = React.useState(false);
- const {userInfo, setUserInfo, setToken} = React.useContext(UserContext);
- const handleCasdoorLogin = () => {
- setShowLoginPage(true);
- };
+ const {userInfo, clearAll} = useStore();
+
+ const handleCasdoorLogin = () => setShowLoginPage(true);
+ const handleHideLoginPage = () => setShowLoginPage(false);
+
const handleCasdoorLogout = () => {
CasdoorLogout();
- setUserInfo(null);
- setToken(null);
- };
-
- const handleHideLoginPage = () => {
- setShowLoginPage(false);
+ clearAll();
};
return (
diff --git a/TotpDatabase.js b/TotpDatabase.js
new file mode 100644
index 0000000..0c7b5bb
--- /dev/null
+++ b/TotpDatabase.js
@@ -0,0 +1,298 @@
+// Copyright 2024 The Casdoor Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import totp from "totp-generator";
+import * as api from "./api";
+
+export async function migrateDb(db) {
+ const DATABASE_VERSION = 1;
+ const result = await db.getFirstAsync("PRAGMA user_version");
+ let currentVersion = result?.user_version ?? 0;
+ if (currentVersion === DATABASE_VERSION) {
+ return;
+ }
+
+ if (currentVersion === 0) {
+ await db.execAsync(`
+PRAGMA journal_mode = 'wal';
+CREATE TABLE accounts (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ issuer TEXT,
+ account_name TEXT NOT NULL,
+ old_account_name TEXT DEFAULT NULL,
+ secret TEXT NOT NULL,
+ token TEXT,
+ is_deleted INTEGER DEFAULT 0,
+ last_change_time INTEGER DEFAULT (strftime('%s', 'now')),
+ last_sync_time INTEGER DEFAULT NULL
+);
+`);
+ await db.execAsync(`PRAGMA user_version = ${DATABASE_VERSION}`);
+ currentVersion = 1;
+ }
+
+ await db.execAsync(`PRAGMA user_version = ${DATABASE_VERSION}`);
+}
+
+const generateToken = (secretKey) => {
+ if (secretKey !== null && secretKey !== undefined && secretKey !== "") {
+ try {
+ const token = totp(secretKey);
+ const tokenWithSpace = token.slice(0, 3) + " " + token.slice(3);
+ return tokenWithSpace;
+ } catch (error) {
+ return "Secret Invalid";
+ }
+ } else {
+ return "Secret Empty";
+ }
+};
+
+export async function insertAccount(db, account) {
+ const token = generateToken(account.secretKey);
+ const currentTime = Math.floor(Date.now() / 1000);
+ return await db.runAsync(
+ "INSERT INTO accounts (issuer, account_name, secret, token, last_change_time) VALUES (?, ?, ?, ?, ?)",
+ account.issuer ?? "",
+ account.accountName,
+ account.secretKey,
+ token ?? "",
+ currentTime
+ );
+}
+
+export async function updateAccountName(db, id, newAccountName) {
+ const account = await db.getFirstAsync("SELECT * FROM accounts WHERE id = ?", id);
+ const currentTime = Math.floor(Date.now() / 1000);
+
+ // Only update old_account_name if it's null or if last_sync_time is more recent than last_change_time
+ if (account.old_account_name === null || (account.last_sync_time && account.last_sync_time > account.last_change_time)) {
+ await db.runAsync(`
+ UPDATE accounts
+ SET account_name = ?,
+ old_account_name = ?,
+ last_change_time = ?
+ WHERE id = ?
+ `, newAccountName, account.account_name, currentTime, id);
+ } else {
+ await db.runAsync(`
+ UPDATE accounts
+ SET account_name = ?,
+ last_change_time = ?
+ WHERE id = ?
+ `, newAccountName, currentTime, id);
+ }
+}
+
+export async function updateAccount(db, account, id) {
+ const token = generateToken(account.secretKey);
+ const currentTime = Math.floor(Date.now() / 1000);
+ const result = await db.runAsync(
+ "UPDATE accounts SET issuer = ?, account_name = ?, old_account_name = ?, secret = ?, token = ?, last_change_time = ? WHERE id = ?",
+ account.issuer,
+ account.accountName,
+ account.oldAccountName ?? null,
+ account.secretKey,
+ token ?? "",
+ currentTime,
+ id
+ );
+
+ if (result.changes === 0) {
+ throw new Error(`No account updated for id: ${id}`);
+ }
+ return result;
+}
+
+export async function deleteAccount(db, id) {
+ const currentTime = Math.floor(Date.now() / 1000);
+ await db.runAsync("UPDATE accounts SET is_deleted = 1, last_change_time = ? WHERE id = ?", currentTime, id);
+}
+
+export async function trueDeleteAccount(db, id) {
+ return await db.runAsync("DELETE FROM accounts WHERE id = ?", id);
+}
+
+export function updateToken(db, id) {
+ const result = db.getFirstSync("SELECT secret FROM accounts WHERE id = ?", id);
+ if (result.secret === null) {
+ return;
+ }
+ const token = generateToken(result.secret);
+ return db.runSync("UPDATE accounts SET token = ? WHERE id = ?", token, id);
+}
+
+export async function updateTokenForAll(db) {
+ const accounts = await db.getAllAsync("SELECT * FROM accounts WHERE is_deleted = 0");
+ for (const account of accounts) {
+ const token = generateToken(account.secret);
+ await db.runAsync("UPDATE accounts SET token = ? WHERE id = ?", token, account.id);
+ }
+}
+
+export async function getAllAccounts(db) {
+ const accounts = await db.getAllAsync("SELECT * FROM accounts WHERE is_deleted = 0");
+ return accounts.map(account => {
+ const mappedAccount = {
+ ...account,
+ accountName: account.account_name,
+ secretKey: account.secret,
+ };
+ return mappedAccount;
+ });
+}
+
+async function getLocalAccounts(db) {
+ const accounts = await db.getAllAsync("SELECT * FROM accounts");
+ return accounts.map(account => ({
+ id: account.id,
+ issuer: account.issuer,
+ accountName: account.account_name,
+ oldAccountName: account.old_account_name,
+ secretKey: account.secret,
+ isDeleted: account.is_deleted === 1,
+ lastChangeTime: account.last_change_time,
+ lastSyncTime: account.last_sync_time,
+ }));
+}
+
+async function updateSyncTimeForAll(db) {
+ const currentTime = Math.floor(Date.now() / 1000);
+ await db.runAsync("UPDATE accounts SET last_sync_time = ?", currentTime);
+}
+
+export function calculateCountdown() {
+ const now = Math.floor(Date.now() / 1000);
+ return 30 - (now % 30);
+}
+
+async function updateLocalDatabase(db, mergedAccounts) {
+ for (const account of mergedAccounts) {
+ if (account.id) {
+ if (account.isDeleted) {
+ await db.runAsync("DELETE FROM accounts WHERE id = ?", account.id);
+ } else {
+ await updateAccount(db, account, account.id);
+ }
+ } else {
+ await insertAccount(db, account);
+ }
+ }
+}
+
+function getAccountKey(account) {
+ return `${account.issuer}:${account.accountName}`;
+}
+
+function mergeAccounts(localAccounts, serverAccounts, serverTimestamp) {
+ const mergedAccounts = new Map();
+ const localAccountKeys = new Map();
+
+ // Process local accounts
+ for (const local of localAccounts) {
+ const key = getAccountKey(local);
+ mergedAccounts.set(key, {
+ ...local,
+ synced: false,
+ });
+
+ // Store both current and old account keys for local accounts
+ localAccountKeys.set(key, local);
+ if (local.oldAccountName) {
+ const oldKey = getAccountKey({...local, accountName: local.oldAccountName});
+ localAccountKeys.set(oldKey, local);
+ }
+ }
+
+ const processedLocalKeys = new Set();
+
+ // Merge with server accounts
+ for (const server of serverAccounts) {
+ const serverKey = getAccountKey(server);
+ const localAccount = localAccountKeys.get(serverKey);
+
+ if (!localAccount) {
+ // New account from server
+ mergedAccounts.set(serverKey, {...server, synced: true});
+ } else {
+ const localKey = getAccountKey(localAccount);
+ const local = mergedAccounts.get(localKey);
+
+ if (serverTimestamp > local.lastChangeTime) {
+ // Server has newer changes
+ mergedAccounts.set(localKey, {
+ ...server,
+ id: local.id,
+ oldAccountName: local.accountName !== server.accountName ? local.accountName : local.oldAccountName,
+ synced: true,
+ });
+ } else if (local.accountName !== server.accountName) {
+ // Local name change is newer, update the server account name
+ mergedAccounts.set(localKey, {
+ ...local,
+ oldAccountName: server.accountName,
+ synced: false,
+ });
+ }
+ // If local is newer or deleted, keep the local version (already in mergedAccounts)
+ processedLocalKeys.add(localKey);
+ }
+ }
+ // Handle server-side deletions
+ for (const [key, local] of mergedAccounts) {
+ if (!processedLocalKeys.has(key) && local.lastSyncTime && local.lastSyncTime < serverTimestamp) {
+ // This account was not found on the server and was previously synced
+ // Mark it as deleted
+ mergedAccounts.set(key, {...local, isDeleted: true, synced: true});
+ }
+ }
+
+ return Array.from(mergedAccounts.values());
+}
+
+export async function syncWithCloud(db, userInfo, serverUrl, token) {
+ const localAccounts = await getLocalAccounts(db);
+ const {updatedTime, mfaAccounts: serverAccounts} = await api.getMfaAccounts(
+ serverUrl,
+ userInfo.owner,
+ userInfo.name,
+ token
+ );
+
+ const serverTimestamp = Math.floor(new Date(updatedTime).getTime() / 1000);
+
+ const mergedAccounts = mergeAccounts(localAccounts, serverAccounts, serverTimestamp);
+ await updateLocalDatabase(db, mergedAccounts);
+
+ const accountsToSync = mergedAccounts.filter(account => !account.isDeleted).map(account => ({
+ issuer: account.issuer,
+ accountName: account.accountName,
+ secretKey: account.secretKey,
+ }));
+
+ const {status} = await api.updateMfaAccounts(
+ serverUrl,
+ userInfo.owner,
+ userInfo.name,
+ accountsToSync,
+ token
+ );
+
+ if (status !== "ok") {
+ throw new Error("Sync failed");
+ }
+
+ await updateSyncTimeForAll(db);
+ await updateTokenForAll(db);
+}
diff --git a/UserContext.js b/UserContext.js
deleted file mode 100644
index 79faa5d..0000000
--- a/UserContext.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2023 The Casdoor Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import React from "react";
-
-const UserContext = React.createContext();
-export const UserProvider = UserContext.Provider;
-export const UserConsumer = UserContext.Consumer;
-export default UserContext;
diff --git a/package-lock.json b/package-lock.json
index b130c7d..1d9af7c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,31 +13,35 @@
"@react-native-community/netinfo": "11.3.1",
"@react-navigation/bottom-tabs": "^6.5.8",
"@react-navigation/native": "^6.1.7",
+ "@shopify/flash-list": "1.6.4",
"casdoor-react-native-sdk": "1.1.0",
"eslint-plugin-import": "^2.28.1",
- "expo": "~51.0.24",
+ "expo": "~51.0.26",
"expo-camera": "~15.0.14",
- "expo-dev-client": "^4.0.21",
+ "expo-dev-client": "~4.0.22",
"expo-image": "^1.12.13",
+ "expo-sqlite": "~14.0.6",
"expo-status-bar": "~1.12.1",
"expo-system-ui": "~3.0.7",
- "expo-updates": "~0.25.21",
+ "expo-updates": "~0.25.22",
"hotp-totp": "^1.0.6",
"prop-types": "^15.8.1",
"react": "18.2.0",
+ "react-content-loader": "^7.0.2",
"react-dom": "18.2.0",
- "react-native": "0.74.3",
+ "react-native": "0.74.5",
"react-native-countdown-circle-timer": "^3.2.1",
"react-native-gesture-handler": "~2.16.1",
"react-native-paper": "^5.10.3",
"react-native-reanimated": "~3.10.1",
- "react-native-root-toast": "^3.6.0",
"react-native-safe-area-context": "4.10.5",
- "react-native-screens": "^3.31.1",
+ "react-native-screens": "3.31.1",
"react-native-svg": "15.2.0",
+ "react-native-toast-message": "^2.2.0",
"react-native-web": "~0.19.6",
"react-native-webview": "13.8.6",
- "totp-generator": "^0.0.14"
+ "totp-generator": "^0.0.14",
+ "zustand": "^4.5.4"
},
"devDependencies": {
"@babel/core": "^7.24.0",
@@ -2363,24 +2367,20 @@
}
},
"node_modules/@expo/bunyan": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@expo/bunyan/-/bunyan-4.0.0.tgz",
- "integrity": "sha512-Ydf4LidRB/EBI+YrB+cVLqIseiRfjUI/AeHBgjGMtq3GroraDu81OV7zqophRgupngoL3iS3JUMDMnxO7g39qA==",
- "engines": [
- "node >=0.10.0"
- ],
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@expo/bunyan/-/bunyan-4.0.1.tgz",
+ "integrity": "sha512-+Lla7nYSiHZirgK+U/uYzsLv/X+HaJienbD5AKX1UQZHYfWaP+9uuQluRB4GrEVWF0GZ7vEVp/jzaOT9k/SQlg==",
"dependencies": {
"uuid": "^8.0.0"
},
- "optionalDependencies": {
- "mv": "~2",
- "safe-json-stringify": "~1"
+ "engines": {
+ "node": ">=0.10.0"
}
},
"node_modules/@expo/cli": {
- "version": "0.18.26",
- "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.18.26.tgz",
- "integrity": "sha512-u9bTTXgcjaTloE9CHwxgrb8Me/Al4jiPykbVQpJydakH3GsIZfHy1zaLc7O39CoLjRz37WWi6Y5ZdgtQw9dCPQ==",
+ "version": "0.18.28",
+ "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.18.28.tgz",
+ "integrity": "sha512-fvbVPId6s6etindzP6Nzos/CS1NurMVy4JKozjebArHr63tBid5i/UY5Pp+4wTCAM20gB2SjRdwcwoL6HFC4Iw==",
"dependencies": {
"@babel/runtime": "^7.20.0",
"@expo/code-signing-certificates": "0.0.5",
@@ -2390,7 +2390,7 @@
"@expo/env": "~0.3.0",
"@expo/image-utils": "^0.5.0",
"@expo/json-file": "^8.3.0",
- "@expo/metro-config": "~0.18.6",
+ "@expo/metro-config": "0.18.11",
"@expo/osascript": "^2.0.31",
"@expo/package-manager": "^1.5.0",
"@expo/plist": "^0.1.0",
@@ -2792,25 +2792,32 @@
}
},
"node_modules/@expo/devcert": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@expo/devcert/-/devcert-1.1.2.tgz",
- "integrity": "sha512-FyWghLu7rUaZEZSTLt/XNRukm0c9GFfwP0iFaswoDWpV6alvVg+zRAfCLdIVQEz1SVcQ3zo1hMZFDrnKGvkCuQ==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@expo/devcert/-/devcert-1.1.4.tgz",
+ "integrity": "sha512-fqBODr8c72+gBSX5Ty3SIzaY4bXainlpab78+vEYEKL3fXmsOswMLf0+KE36mUEAa36BYabX7K3EiXOXX5OPMw==",
"dependencies": {
"application-config-path": "^0.1.0",
"command-exists": "^1.2.4",
"debug": "^3.1.0",
"eol": "^0.9.1",
"get-port": "^3.2.0",
- "glob": "^7.1.2",
+ "glob": "^10.4.2",
"lodash": "^4.17.21",
"mkdirp": "^0.5.1",
"password-prompt": "^1.0.4",
- "rimraf": "^2.6.2",
"sudo-prompt": "^8.2.0",
"tmp": "^0.0.33",
"tslib": "^2.4.0"
}
},
+ "node_modules/@expo/devcert/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
"node_modules/@expo/devcert/node_modules/debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
@@ -2820,20 +2827,33 @@
}
},
"node_modules/@expo/devcert/node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "deprecated": "Glob versions prior to v9 are no longer supported",
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
"dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@expo/devcert/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
},
"engines": {
- "node": "*"
+ "node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@@ -3208,9 +3228,9 @@
}
},
"node_modules/@expo/metro-config": {
- "version": "0.18.10",
- "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-0.18.10.tgz",
- "integrity": "sha512-HTYQqKfV0JSuRp5aDvrPHezj5udXOWoXqHOjfTSnce2m13j6D0yYXTJNaKRhlgpPBrkg5DL7z1fL3zwDUpLM4w==",
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-0.18.11.tgz",
+ "integrity": "sha512-/uOq55VbSf9yMbUO1BudkUM2SsGW1c5hr9BnhIqYqcsFv0Jp5D3DtJ4rljDKaUeNLbwr6m7pqIrkSMq5NrYf4Q==",
"dependencies": {
"@babel/core": "^7.20.0",
"@babel/generator": "^7.20.5",
@@ -3585,6 +3605,18 @@
"prop-types": "^15.8.1"
}
},
+ "node_modules/@expo/websql": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@expo/websql/-/websql-1.0.1.tgz",
+ "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"
+ }
+ },
"node_modules/@expo/xcpretty": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.3.1.tgz",
@@ -3978,12 +4010,12 @@
}
},
"node_modules/@jridgewell/source-map": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
- "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
+ "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
"dependencies": {
- "@jridgewell/gen-mapping": "^0.3.0",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
@@ -5591,28 +5623,28 @@
}
},
"node_modules/@react-native/assets-registry": {
- "version": "0.74.85",
- "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.74.85.tgz",
- "integrity": "sha512-59YmIQxfGDw4aP9S/nAM+sjSFdW8fUP6fsqczCcXgL2YVEjyER9XCaUT0J1K+PdHep8pi05KUgIKUds8P3jbmA==",
+ "version": "0.74.87",
+ "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.74.87.tgz",
+ "integrity": "sha512-1XmRhqQchN+pXPKEKYdpJlwESxVomJOxtEnIkbo7GAlaN2sym84fHEGDXAjLilih5GVPpcpSmFzTy8jx3LtaFg==",
"engines": {
"node": ">=18"
}
},
"node_modules/@react-native/babel-plugin-codegen": {
- "version": "0.74.85",
- "resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.74.85.tgz",
- "integrity": "sha512-48TSDclRB5OMXiImiJkLxyCfRyLsqkCgI8buugCZzvXcYslfV7gCvcyFyQldtcOmerV+CK4RAj7QS4hmB5Mr8Q==",
+ "version": "0.74.87",
+ "resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.74.87.tgz",
+ "integrity": "sha512-+vJYpMnENFrwtgvDfUj+CtVJRJuUnzAUYT0/Pb68Sq9RfcZ5xdcCuUgyf7JO+akW2VTBoJY427wkcxU30qrWWw==",
"dependencies": {
- "@react-native/codegen": "0.74.85"
+ "@react-native/codegen": "0.74.87"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@react-native/babel-preset": {
- "version": "0.74.85",
- "resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.74.85.tgz",
- "integrity": "sha512-yMHUlN8INbK5BBwiBuQMftdWkpm1IgCsoJTKcGD2OpSgZhwwm8RUSvGhdRMzB2w7bsqqBmaEMleGtW6aCR7B9w==",
+ "version": "0.74.87",
+ "resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.74.87.tgz",
+ "integrity": "sha512-hyKpfqzN2nxZmYYJ0tQIHG99FQO0OWXp/gVggAfEUgiT+yNKas1C60LuofUsK7cd+2o9jrpqgqW4WzEDZoBlTg==",
"dependencies": {
"@babel/core": "^7.20.0",
"@babel/plugin-proposal-async-generator-functions": "^7.0.0",
@@ -5654,7 +5686,7 @@
"@babel/plugin-transform-typescript": "^7.5.0",
"@babel/plugin-transform-unicode-regex": "^7.0.0",
"@babel/template": "^7.0.0",
- "@react-native/babel-plugin-codegen": "0.74.85",
+ "@react-native/babel-plugin-codegen": "0.74.87",
"babel-plugin-transform-flow-enums": "^0.0.2",
"react-refresh": "^0.14.0"
},
@@ -5666,9 +5698,9 @@
}
},
"node_modules/@react-native/codegen": {
- "version": "0.74.85",
- "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.74.85.tgz",
- "integrity": "sha512-N7QwoS4Hq/uQmoH83Ewedy6D0M7xbQsOU3OMcQf0eY3ltQ7S2hd9/R4UTalQWRn1OUJfXR6OG12QJ4FStKgV6Q==",
+ "version": "0.74.87",
+ "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.74.87.tgz",
+ "integrity": "sha512-GMSYDiD+86zLKgMMgz9z0k6FxmRn+z6cimYZKkucW4soGbxWsbjUAZoZ56sJwt2FJ3XVRgXCrnOCgXoH/Bkhcg==",
"dependencies": {
"@babel/parser": "^7.20.0",
"glob": "^7.1.1",
@@ -5706,14 +5738,14 @@
}
},
"node_modules/@react-native/community-cli-plugin": {
- "version": "0.74.85",
- "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.74.85.tgz",
- "integrity": "sha512-ODzND33eA2owAY3g9jgCdqB+BjAh8qJ7dvmSotXgrgDYr3MJMpd8gvHTIPe2fg4Kab+wk8uipRhrE0i0RYMwtQ==",
+ "version": "0.74.87",
+ "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.74.87.tgz",
+ "integrity": "sha512-EgJG9lSr8x3X67dHQKQvU6EkO+3ksVlJHYIVv6U/AmW9dN80BEFxgYbSJ7icXS4wri7m4kHdgeq2PQ7/3vvrTQ==",
"dependencies": {
"@react-native-community/cli-server-api": "13.6.9",
"@react-native-community/cli-tools": "13.6.9",
- "@react-native/dev-middleware": "0.74.85",
- "@react-native/metro-babel-transformer": "0.74.85",
+ "@react-native/dev-middleware": "0.74.87",
+ "@react-native/metro-babel-transformer": "0.74.87",
"chalk": "^4.0.0",
"execa": "^5.1.1",
"metro": "^0.80.3",
@@ -5727,6 +5759,37 @@
"node": ">=18"
}
},
+ "node_modules/@react-native/community-cli-plugin/node_modules/@react-native/debugger-frontend": {
+ "version": "0.74.87",
+ "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.74.87.tgz",
+ "integrity": "sha512-MN95DJLYTv4EqJc+9JajA3AJZSBYJz2QEJ3uWlHrOky2vKrbbRVaW1ityTmaZa2OXIvNc6CZwSRSE7xCoHbXhQ==",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@react-native/community-cli-plugin/node_modules/@react-native/dev-middleware": {
+ "version": "0.74.87",
+ "resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.74.87.tgz",
+ "integrity": "sha512-7TmZ3hTHwooYgIHqc/z87BMe1ryrIqAUi+AF7vsD+EHCGxHFdMjSpf1BZ2SUPXuLnF2cTiTfV2RwhbPzx0tYIA==",
+ "dependencies": {
+ "@isaacs/ttlcache": "^1.4.1",
+ "@react-native/debugger-frontend": "0.74.87",
+ "@rnx-kit/chromium-edge-launcher": "^1.0.0",
+ "chrome-launcher": "^0.15.2",
+ "connect": "^3.6.5",
+ "debug": "^2.2.0",
+ "node-fetch": "^2.2.0",
+ "nullthrows": "^1.1.1",
+ "open": "^7.0.3",
+ "selfsigned": "^2.4.1",
+ "serve-static": "^1.13.1",
+ "temp-dir": "^2.0.0",
+ "ws": "^6.2.2"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/@react-native/community-cli-plugin/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
@@ -5772,6 +5835,14 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
+ "node_modules/@react-native/community-cli-plugin/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
"node_modules/@react-native/community-cli-plugin/node_modules/execa": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
@@ -5832,6 +5903,11 @@
"node": ">=6"
}
},
+ "node_modules/@react-native/community-cli-plugin/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
"node_modules/@react-native/community-cli-plugin/node_modules/npm-run-path": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
@@ -5857,6 +5933,21 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/@react-native/community-cli-plugin/node_modules/open": {
+ "version": "7.4.2",
+ "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz",
+ "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==",
+ "dependencies": {
+ "is-docker": "^2.0.0",
+ "is-wsl": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/@react-native/community-cli-plugin/node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -5868,6 +5959,14 @@
"node": ">=8"
}
},
+ "node_modules/@react-native/community-cli-plugin/node_modules/ws": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz",
+ "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==",
+ "dependencies": {
+ "async-limiter": "~1.0.0"
+ }
+ },
"node_modules/@react-native/debugger-frontend": {
"version": "0.74.85",
"resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.74.85.tgz",
@@ -5936,28 +6035,28 @@
}
},
"node_modules/@react-native/gradle-plugin": {
- "version": "0.74.85",
- "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.74.85.tgz",
- "integrity": "sha512-1VQSLukJzaVMn1MYcs8Weo1nUW8xCas2XU1KuoV7OJPk6xPnEBFJmapmEGP5mWeEy7kcTXJmddEgy1wwW0tcig==",
+ "version": "0.74.87",
+ "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.74.87.tgz",
+ "integrity": "sha512-T+VX0N1qP+U9V4oAtn7FTX7pfsoVkd1ocyw9swYXgJqU2fK7hC9famW7b3s3ZiufPGPr1VPJe2TVGtSopBjL6A==",
"engines": {
"node": ">=18"
}
},
"node_modules/@react-native/js-polyfills": {
- "version": "0.74.85",
- "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.74.85.tgz",
- "integrity": "sha512-gp4Rg9le3lVZeW7Cie6qLfekvRKZuhJ3LKgi1SFB4N154z1wIclypAJXVXgWBsy8JKJfTwRI+sffC4qZDlvzrg==",
+ "version": "0.74.87",
+ "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.74.87.tgz",
+ "integrity": "sha512-M5Evdn76CuVEF0GsaXiGi95CBZ4IWubHqwXxV9vG9CC9kq0PSkoM2Pn7Lx7dgyp4vT7ccJ8a3IwHbe+5KJRnpw==",
"engines": {
"node": ">=18"
}
},
"node_modules/@react-native/metro-babel-transformer": {
- "version": "0.74.85",
- "resolved": "https://registry.npmjs.org/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.74.85.tgz",
- "integrity": "sha512-JIrXqEwhTvWPtGArgMptIPGstMdXQIkwSjKVYt+7VC4a9Pw1GurIWanIJheEW6ZuCVvTc0VZkwglFz9JVjzDjA==",
+ "version": "0.74.87",
+ "resolved": "https://registry.npmjs.org/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.74.87.tgz",
+ "integrity": "sha512-UsJCO24sNax2NSPBmV1zLEVVNkS88kcgAiYrZHtYSwSjpl4WZ656tIeedBfiySdJ94Hr3kQmBYLipV5zk0NI1A==",
"dependencies": {
"@babel/core": "^7.20.0",
- "@react-native/babel-preset": "0.74.85",
+ "@react-native/babel-preset": "0.74.87",
"hermes-parser": "0.19.1",
"nullthrows": "^1.1.1"
},
@@ -5968,16 +6067,33 @@
"@babel/core": "*"
}
},
- "node_modules/@react-native/normalize-color": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@react-native/normalize-color/-/normalize-color-2.1.0.tgz",
- "integrity": "sha512-Z1jQI2NpdFJCVgpY+8Dq/Bt3d+YUi1928Q+/CZm/oh66fzM0RUl54vvuXlPJKybH4pdCZey1eDTPaLHkMPNgWA=="
- },
"node_modules/@react-native/normalize-colors": {
"version": "0.74.85",
"resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.74.85.tgz",
"integrity": "sha512-pcE4i0X7y3hsAE0SpIl7t6dUc0B0NZLd1yv7ssm4FrLhWG+CGyIq4eFDXpmPU1XHmL5PPySxTAjEMiwv6tAmOw=="
},
+ "node_modules/@react-native/virtualized-lists": {
+ "version": "0.74.87",
+ "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.74.87.tgz",
+ "integrity": "sha512-lsGxoFMb0lyK/MiplNKJpD+A1EoEUumkLrCjH4Ht+ZlG8S0BfCxmskLZ6qXn3BiDSkLjfjI/qyZ3pnxNBvkXpQ==",
+ "dependencies": {
+ "invariant": "^2.2.4",
+ "nullthrows": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@types/react": "^18.2.6",
+ "react": "*",
+ "react-native": "*"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@react-navigation/bottom-tabs": {
"version": "6.5.9",
"resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.5.9.tgz",
@@ -6069,26 +6185,6 @@
"undici-types": "~5.26.4"
}
},
- "node_modules/@rnx-kit/chromium-edge-launcher/node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "deprecated": "Glob versions prior to v9 are no longer supported",
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/@rnx-kit/chromium-edge-launcher/node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
@@ -6100,21 +6196,6 @@
"node": ">=10"
}
},
- "node_modules/@rnx-kit/chromium-edge-launcher/node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "deprecated": "Rimraf versions prior to v4 are no longer supported",
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/@segment/loosely-validate-event": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@segment/loosely-validate-event/-/loosely-validate-event-2.0.0.tgz",
@@ -6124,6 +6205,25 @@
"join-component": "^1.1.0"
}
},
+ "node_modules/@shopify/flash-list": {
+ "version": "1.6.4",
+ "resolved": "https://registry.npmjs.org/@shopify/flash-list/-/flash-list-1.6.4.tgz",
+ "integrity": "sha512-M2momcnY7swsvmpHIFDVbdOaFw4aQocJXA/lFP0Gpz+alQjFylqVKvszxl4atYO2SNbjxlb2L6hEP9WEcAknGQ==",
+ "dependencies": {
+ "recyclerlistview": "4.2.0",
+ "tslib": "2.4.0"
+ },
+ "peerDependencies": {
+ "@babel/runtime": "*",
+ "react": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/@shopify/flash-list/node_modules/tslib": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
+ "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
+ },
"node_modules/@sideway/address": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
@@ -6769,6 +6869,11 @@
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
+ "node_modules/argsarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/argsarray/-/argsarray-0.0.1.tgz",
+ "integrity": "sha512-u96dg2GcAKtpTrBdDoFIM7PjcBA+6rSP0OR94MOReNRyUECL6MtQt5XXmRr4qrftYaef9+l5hcpO5te7sML1Cg=="
+ },
"node_modules/array-buffer-byte-length": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
@@ -7023,236 +7128,91 @@
}
},
"node_modules/babel-plugin-react-compiler": {
- "version": "0.0.0-experimental-696af53-20240625",
- "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-0.0.0-experimental-696af53-20240625.tgz",
- "integrity": "sha512-OUDKms8qmcm5bX0D+sJWC1YcKcd7AZ2aJ7eY6gkR+Xr7PDfkXLbqAld4Qs9B0ntjVbUMEtW/PjlQrxDtY4raHg==",
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-0.0.0.tgz",
+ "integrity": "sha512-Kigl0V36a/6hLVH7+CCe1CCtU3mFBqBd829V//VtuG7I/pyq+B2QZJqOefd63snQmdfCryNhO9XW1FbGPBvYDA=="
+ },
+ "node_modules/babel-plugin-react-native-web": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/babel-plugin-react-native-web/-/babel-plugin-react-native-web-0.19.12.tgz",
+ "integrity": "sha512-eYZ4+P6jNcB37lObWIg0pUbi7+3PKoU1Oie2j0C8UF3cXyXoR74tO2NBjI/FORb2LJyItJZEAmjU5pSaJYEL1w=="
+ },
+ "node_modules/babel-plugin-transform-flow-enums": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-enums/-/babel-plugin-transform-flow-enums-0.0.2.tgz",
+ "integrity": "sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ==",
"dependencies": {
- "@babel/generator": "7.2.0",
- "@babel/types": "^7.19.0",
- "chalk": "4",
- "invariant": "^2.2.4",
- "pretty-format": "^24",
- "zod": "^3.22.4",
- "zod-validation-error": "^2.1.0"
+ "@babel/plugin-syntax-flow": "^7.12.1"
}
},
- "node_modules/babel-plugin-react-compiler/node_modules/@babel/generator": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.2.0.tgz",
- "integrity": "sha512-BA75MVfRlFQG2EZgFYIwyT1r6xSkwfP2bdkY/kLZusEYWiJs4xCowab/alaEaT0wSvmVuXGqiefeBlP+7V1yKg==",
+ "node_modules/babel-preset-expo": {
+ "version": "11.0.13",
+ "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-11.0.13.tgz",
+ "integrity": "sha512-5oUXyxnIVyDUhG4a306PpT2c9HhKx0tG4LXjpSIA/dERzwGvU8LUxDSD6yCohhRSsPZIoR7u2mnH0PypqFqYnQ==",
"dependencies": {
- "@babel/types": "^7.2.0",
- "jsesc": "^2.5.1",
- "lodash": "^4.17.10",
- "source-map": "^0.5.0",
- "trim-right": "^1.0.1"
+ "@babel/plugin-proposal-decorators": "^7.12.9",
+ "@babel/plugin-transform-export-namespace-from": "^7.22.11",
+ "@babel/plugin-transform-object-rest-spread": "^7.12.13",
+ "@babel/plugin-transform-parameters": "^7.22.15",
+ "@babel/preset-react": "^7.22.15",
+ "@babel/preset-typescript": "^7.23.0",
+ "@react-native/babel-preset": "0.74.87",
+ "babel-plugin-react-compiler": "^0.0.0-experimental-592953e-20240517",
+ "babel-plugin-react-native-web": "~0.19.10",
+ "react-refresh": "^0.14.2"
}
},
- "node_modules/babel-plugin-react-compiler/node_modules/@jest/types": {
- "version": "24.9.0",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz",
- "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==",
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/better-opn": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz",
+ "integrity": "sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==",
"dependencies": {
- "@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
- "@types/yargs": "^13.0.0"
+ "open": "^8.0.4"
},
"engines": {
- "node": ">= 6"
+ "node": ">=12.0.0"
}
},
- "node_modules/babel-plugin-react-compiler/node_modules/@types/istanbul-reports": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz",
- "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==",
- "dependencies": {
- "@types/istanbul-lib-coverage": "*",
- "@types/istanbul-lib-report": "*"
+ "node_modules/big-integer": {
+ "version": "1.6.52",
+ "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz",
+ "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==",
+ "engines": {
+ "node": ">=0.6"
}
},
- "node_modules/babel-plugin-react-compiler/node_modules/@types/yargs": {
- "version": "13.0.12",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz",
- "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==",
+ "node_modules/bl": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
+ "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
"dependencies": {
- "@types/yargs-parser": "*"
- }
- },
- "node_modules/babel-plugin-react-compiler/node_modules/ansi-regex": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
- "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/babel-plugin-react-compiler/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/babel-plugin-react-compiler/node_modules/chalk/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/babel-plugin-react-compiler/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/babel-plugin-react-compiler/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
- },
- "node_modules/babel-plugin-react-compiler/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/babel-plugin-react-compiler/node_modules/pretty-format": {
- "version": "24.9.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz",
- "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==",
- "dependencies": {
- "@jest/types": "^24.9.0",
- "ansi-regex": "^4.0.0",
- "ansi-styles": "^3.2.0",
- "react-is": "^16.8.4"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/babel-plugin-react-compiler/node_modules/source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/babel-plugin-react-compiler/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/babel-plugin-react-native-web": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/babel-plugin-react-native-web/-/babel-plugin-react-native-web-0.19.12.tgz",
- "integrity": "sha512-eYZ4+P6jNcB37lObWIg0pUbi7+3PKoU1Oie2j0C8UF3cXyXoR74tO2NBjI/FORb2LJyItJZEAmjU5pSaJYEL1w=="
- },
- "node_modules/babel-plugin-transform-flow-enums": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-enums/-/babel-plugin-transform-flow-enums-0.0.2.tgz",
- "integrity": "sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ==",
- "dependencies": {
- "@babel/plugin-syntax-flow": "^7.12.1"
- }
- },
- "node_modules/babel-preset-expo": {
- "version": "11.0.12",
- "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-11.0.12.tgz",
- "integrity": "sha512-hUuKdzSo8+H1oXQvKvlHRMHTxl+nN6YhFGlKiIxPa0E+gYfMEp8FnnStc/2Hwmip5rgJzQs6KF63KKRUc75xAg==",
- "dependencies": {
- "@babel/plugin-proposal-decorators": "^7.12.9",
- "@babel/plugin-transform-export-namespace-from": "^7.22.11",
- "@babel/plugin-transform-object-rest-spread": "^7.12.13",
- "@babel/plugin-transform-parameters": "^7.22.15",
- "@babel/preset-react": "^7.22.15",
- "@babel/preset-typescript": "^7.23.0",
- "@react-native/babel-preset": "0.74.85",
- "babel-plugin-react-compiler": "^0.0.0-experimental-592953e-20240517",
- "babel-plugin-react-native-web": "~0.19.10",
- "react-refresh": "^0.14.2"
- }
- },
- "node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
- },
- "node_modules/base64-js": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
- "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ]
- },
- "node_modules/better-opn": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz",
- "integrity": "sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==",
- "dependencies": {
- "open": "^8.0.4"
- },
- "engines": {
- "node": ">=12.0.0"
- }
- },
- "node_modules/big-integer": {
- "version": "1.6.52",
- "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz",
- "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==",
- "engines": {
- "node": ">=0.6"
- }
- },
- "node_modules/bl": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
- "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
- "dependencies": {
- "buffer": "^5.5.0",
- "inherits": "^2.0.4",
- "readable-stream": "^3.4.0"
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
}
},
"node_modules/bl/node_modules/readable-stream": {
@@ -8225,41 +8185,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/del/node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "deprecated": "Glob versions prior to v9 are no longer supported",
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/del/node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "deprecated": "Rimraf versions prior to v4 are no longer supported",
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -8281,16 +8206,6 @@
"node": ">= 0.8"
}
},
- "node_modules/deprecated-react-native-prop-types": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-2.3.0.tgz",
- "integrity": "sha512-pWD0voFtNYxrVqvBMYf5gq3NA2GCpfodS1yNynTPc93AYA/KEMGeWDqqeUB6R2Z9ZofVhks2aeJXiuQqKNpesA==",
- "dependencies": {
- "@react-native/normalize-color": "*",
- "invariant": "*",
- "prop-types": "*"
- }
- },
"node_modules/destroy": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
@@ -9220,17 +9135,17 @@
}
},
"node_modules/expo": {
- "version": "51.0.24",
- "resolved": "https://registry.npmjs.org/expo/-/expo-51.0.24.tgz",
- "integrity": "sha512-HoOuNIWXzS6Gxifcb0N+qRt5K6iR9YitQaWIVNB8elyupvQdyI566IMgMBiO45NgpO5es0sfFNNBasxBHLkbUw==",
+ "version": "51.0.26",
+ "resolved": "https://registry.npmjs.org/expo/-/expo-51.0.26.tgz",
+ "integrity": "sha512-7ThQa6CVbiVtk4GNw0E9CewSzXYOeHkcRTCGorBZVcjAu6SuxbdWEtl0RI01/VpRKV+6I+yy/BmGnCl7lFRILg==",
"dependencies": {
"@babel/runtime": "^7.20.0",
- "@expo/cli": "0.18.26",
+ "@expo/cli": "0.18.28",
"@expo/config": "9.0.3",
"@expo/config-plugins": "8.0.8",
- "@expo/metro-config": "0.18.10",
+ "@expo/metro-config": "0.18.11",
"@expo/vector-icons": "^14.0.0",
- "babel-preset-expo": "~11.0.12",
+ "babel-preset-expo": "~11.0.13",
"expo-asset": "~10.0.10",
"expo-file-system": "~17.0.1",
"expo-font": "~12.0.9",
@@ -9281,12 +9196,12 @@
}
},
"node_modules/expo-dev-client": {
- "version": "4.0.21",
- "resolved": "https://registry.npmjs.org/expo-dev-client/-/expo-dev-client-4.0.21.tgz",
- "integrity": "sha512-+zuVsKyp5tXTQUwDnTjtaOLf3TdmZ483Il9slg/LO15EsEFpl0zwI42DrQpzYmv617cgvywmp6iybGXjV3eZbQ==",
+ "version": "4.0.22",
+ "resolved": "https://registry.npmjs.org/expo-dev-client/-/expo-dev-client-4.0.22.tgz",
+ "integrity": "sha512-tT/9kRqvN3r2MLJL70FdQIgv2ycstN17/vUnxeDVGunW1Q+OdNPupZqyVk0qMeI9Cy1H4ZFBllZ6I1nlOI+mlg==",
"dependencies": {
- "expo-dev-launcher": "4.0.23",
- "expo-dev-menu": "5.0.17",
+ "expo-dev-launcher": "4.0.24",
+ "expo-dev-menu": "5.0.18",
"expo-dev-menu-interface": "1.8.3",
"expo-manifests": "~0.14.0",
"expo-updates-interface": "~0.16.2"
@@ -9296,12 +9211,12 @@
}
},
"node_modules/expo-dev-launcher": {
- "version": "4.0.23",
- "resolved": "https://registry.npmjs.org/expo-dev-launcher/-/expo-dev-launcher-4.0.23.tgz",
- "integrity": "sha512-XG9VyFUoslBsBpJqtuOsen93u3hEw4rK7VSNqz8g+d8+AmHBv2rSuQheirPfxuSrLqGm49/ybWkHYqfs8CdlQw==",
+ "version": "4.0.24",
+ "resolved": "https://registry.npmjs.org/expo-dev-launcher/-/expo-dev-launcher-4.0.24.tgz",
+ "integrity": "sha512-s9j2lBK5Da/btYnwX1TRV1aXWh54Qnc+fFnH8bCzY/cImDcIxy49+GHVCyw2AQj3ZlUcPRuxj29bzi6vSN214Q==",
"dependencies": {
"ajv": "8.11.0",
- "expo-dev-menu": "5.0.17",
+ "expo-dev-menu": "5.0.18",
"expo-manifests": "~0.14.0",
"resolve-from": "^5.0.0",
"semver": "^7.6.0"
@@ -9342,9 +9257,9 @@
}
},
"node_modules/expo-dev-menu": {
- "version": "5.0.17",
- "resolved": "https://registry.npmjs.org/expo-dev-menu/-/expo-dev-menu-5.0.17.tgz",
- "integrity": "sha512-BnFSd6PKDaJenRKn2C4X50dWyqvvkVz9pE/6IKuUvGIsshkk9pCoZvsFOlJjM61/ojz1KXyY9O1FUPPI7B1A7w==",
+ "version": "5.0.18",
+ "resolved": "https://registry.npmjs.org/expo-dev-menu/-/expo-dev-menu-5.0.18.tgz",
+ "integrity": "sha512-6edBlagCbgastLTazLUNJLGlO29/K80VVkZ+Nxt66k34NKINhnSb/fsguQr8w8HeI+xh7N6l0C9rlzWQEJn0Wg==",
"dependencies": {
"expo-dev-menu-interface": "1.8.3",
"semver": "^7.5.4"
@@ -9549,6 +9464,17 @@
"invariant": "^2.2.4"
}
},
+ "node_modules/expo-sqlite": {
+ "version": "14.0.6",
+ "resolved": "https://registry.npmjs.org/expo-sqlite/-/expo-sqlite-14.0.6.tgz",
+ "integrity": "sha512-T3YNx7LT7lM4UQRgi8ml+cj0Wf3Ep09+B4CVaWtUCjdyYJIZjsHDT65hypKG+r6btTLLEd11hjlrstNQhzt5gQ==",
+ "dependencies": {
+ "@expo/websql": "^1.0.1"
+ },
+ "peerDependencies": {
+ "expo": "*"
+ }
+ },
"node_modules/expo-status-bar": {
"version": "1.12.1",
"resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-1.12.1.tgz",
@@ -9572,9 +9498,9 @@
}
},
"node_modules/expo-updates": {
- "version": "0.25.21",
- "resolved": "https://registry.npmjs.org/expo-updates/-/expo-updates-0.25.21.tgz",
- "integrity": "sha512-eNElrzLFHky2au0H8MqdAJdqh40412PHCdANdXtB/P/XIS1xVte74T9rUf053iPswnLLuQfCUpZYSfRKTcsDlg==",
+ "version": "0.25.22",
+ "resolved": "https://registry.npmjs.org/expo-updates/-/expo-updates-0.25.22.tgz",
+ "integrity": "sha512-ebu+wPnISzJ/H70CFAJAybS4ZZrACxRbgr9SMqOI/h84CwXGmdxzLmgxoNhy5q/Fa1u7JBmSr6x9a7psBDT4Cw==",
"dependencies": {
"@expo/code-signing-certificates": "0.0.5",
"@expo/config": "~9.0.0-beta.0",
@@ -9671,6 +9597,11 @@
"node": ">=8"
}
},
+ "node_modules/exponential-backoff": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz",
+ "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw=="
+ },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -9907,39 +9838,6 @@
"node": ">=12.0.0"
}
},
- "node_modules/flat-cache/node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/flat-cache/node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/flatted": {
"version": "3.2.9",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz",
@@ -9972,9 +9870,9 @@
}
},
"node_modules/foreground-child": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz",
- "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
+ "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
"dependencies": {
"cross-spawn": "^7.0.0",
"signal-exit": "^4.0.1"
@@ -10576,6 +10474,11 @@
"node": ">=16.x"
}
},
+ "node_modules/immediate": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz",
+ "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q=="
+ },
"node_modules/import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@@ -11536,6 +11439,42 @@
"node": ">=8"
}
},
+ "node_modules/jest-worker": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz",
+ "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==",
+ "dependencies": {
+ "@types/node": "*",
+ "jest-util": "^29.7.0",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-worker/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
"node_modules/jimp-compact": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/jimp-compact/-/jimp-compact-0.16.1.tgz",
@@ -12340,9 +12279,9 @@
}
},
"node_modules/metro": {
- "version": "0.80.9",
- "resolved": "https://registry.npmjs.org/metro/-/metro-0.80.9.tgz",
- "integrity": "sha512-Bc57Xf3GO2Xe4UWQsBj/oW6YfLPABEu8jfDVDiNmJvoQW4CO34oDPuYKe4KlXzXhcuNsqOtSxpbjCRRVjhhREg==",
+ "version": "0.80.10",
+ "resolved": "https://registry.npmjs.org/metro/-/metro-0.80.10.tgz",
+ "integrity": "sha512-FDPi0X7wpafmDREXe1lgg3WzETxtXh6Kpq8+IwsG35R2tMyp2kFIqDdshdohuvDt1J/qDARcEPq7V/jElTb1kA==",
"dependencies": {
"@babel/code-frame": "^7.0.0",
"@babel/core": "^7.20.0",
@@ -12358,34 +12297,34 @@
"debug": "^2.2.0",
"denodeify": "^1.2.1",
"error-stack-parser": "^2.0.6",
+ "flow-enums-runtime": "^0.0.6",
"graceful-fs": "^4.2.4",
- "hermes-parser": "0.20.1",
+ "hermes-parser": "0.23.0",
"image-size": "^1.0.2",
"invariant": "^2.2.4",
"jest-worker": "^29.6.3",
"jsc-safe-url": "^0.2.2",
"lodash.throttle": "^4.1.1",
- "metro-babel-transformer": "0.80.9",
- "metro-cache": "0.80.9",
- "metro-cache-key": "0.80.9",
- "metro-config": "0.80.9",
- "metro-core": "0.80.9",
- "metro-file-map": "0.80.9",
- "metro-resolver": "0.80.9",
- "metro-runtime": "0.80.9",
- "metro-source-map": "0.80.9",
- "metro-symbolicate": "0.80.9",
- "metro-transform-plugins": "0.80.9",
- "metro-transform-worker": "0.80.9",
+ "metro-babel-transformer": "0.80.10",
+ "metro-cache": "0.80.10",
+ "metro-cache-key": "0.80.10",
+ "metro-config": "0.80.10",
+ "metro-core": "0.80.10",
+ "metro-file-map": "0.80.10",
+ "metro-resolver": "0.80.10",
+ "metro-runtime": "0.80.10",
+ "metro-source-map": "0.80.10",
+ "metro-symbolicate": "0.80.10",
+ "metro-transform-plugins": "0.80.10",
+ "metro-transform-worker": "0.80.10",
"mime-types": "^2.1.27",
"node-fetch": "^2.2.0",
"nullthrows": "^1.1.1",
- "rimraf": "^3.0.2",
"serialize-error": "^2.1.0",
"source-map": "^0.5.6",
"strip-ansi": "^6.0.0",
"throat": "^5.0.0",
- "ws": "^7.5.1",
+ "ws": "^7.5.10",
"yargs": "^17.6.2"
},
"bin": {
@@ -12396,12 +12335,13 @@
}
},
"node_modules/metro-babel-transformer": {
- "version": "0.80.9",
- "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.80.9.tgz",
- "integrity": "sha512-d76BSm64KZam1nifRZlNJmtwIgAeZhZG3fi3K+EmPOlrR8rDtBxQHDSN3fSGeNB9CirdTyabTMQCkCup6BXFSQ==",
+ "version": "0.80.10",
+ "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.80.10.tgz",
+ "integrity": "sha512-GXHueUzgzcazfzORDxDzWS9jVVRV6u+cR6TGvHOfGdfLzJCj7/D0PretLfyq+MwN20twHxLW+BUXkoaB8sCQBg==",
"dependencies": {
"@babel/core": "^7.20.0",
- "hermes-parser": "0.20.1",
+ "flow-enums-runtime": "^0.0.6",
+ "hermes-parser": "0.23.0",
"nullthrows": "^1.1.1"
},
"engines": {
@@ -12409,110 +12349,82 @@
}
},
"node_modules/metro-babel-transformer/node_modules/hermes-estree": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.20.1.tgz",
- "integrity": "sha512-SQpZK4BzR48kuOg0v4pb3EAGNclzIlqMj3Opu/mu7bbAoFw6oig6cEt/RAi0zTFW/iW6Iz9X9ggGuZTAZ/yZHg=="
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.23.0.tgz",
+ "integrity": "sha512-Rkp0PNLGpORw4ktsttkVbpYJbrYKS3hAnkxu8D9nvQi6LvSbuPa+tYw/t2u3Gjc35lYd/k95YkjqyTcN4zspag=="
},
"node_modules/metro-babel-transformer/node_modules/hermes-parser": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.20.1.tgz",
- "integrity": "sha512-BL5P83cwCogI8D7rrDCgsFY0tdYUtmFP9XaXtl2IQjC+2Xo+4okjfXintlTxcIwl4qeGddEl28Z11kbVIw0aNA==",
- "dependencies": {
- "hermes-estree": "0.20.1"
- }
- },
- "node_modules/metro-cache": {
- "version": "0.80.9",
- "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.80.9.tgz",
- "integrity": "sha512-ujEdSI43QwI+Dj2xuNax8LMo8UgKuXJEdxJkzGPU6iIx42nYa1byQ+aADv/iPh5sh5a//h5FopraW5voXSgm2w==",
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.23.0.tgz",
+ "integrity": "sha512-xLwM4ylfHGwrm+2qXfO1JT/fnqEDGSnpS/9hQ4VLtqTexSviu2ZpBgz07U8jVtndq67qdb/ps0qvaWDZ3fkTyg==",
"dependencies": {
- "metro-core": "0.80.9",
- "rimraf": "^3.0.2"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/metro-cache-key": {
- "version": "0.80.9",
- "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.80.9.tgz",
- "integrity": "sha512-hRcYGhEiWIdM87hU0fBlcGr+tHDEAT+7LYNCW89p5JhErFt/QaAkVx4fb5bW3YtXGv5BTV7AspWPERoIb99CXg==",
- "engines": {
- "node": ">=18"
+ "hermes-estree": "0.23.0"
}
},
- "node_modules/metro-cache/node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "deprecated": "Glob versions prior to v9 are no longer supported",
+ "node_modules/metro-cache": {
+ "version": "0.80.10",
+ "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.80.10.tgz",
+ "integrity": "sha512-8CBtDJwMguIE5RvV3PU1QtxUG8oSSX54mIuAbRZmcQ0MYiOl9JdrMd4JCBvIyhiZLoSStph425SMyCSnjtJsdA==",
"dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
+ "exponential-backoff": "^3.1.1",
+ "flow-enums-runtime": "^0.0.6",
+ "metro-core": "0.80.10"
},
"engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
+ "node": ">=18"
}
},
- "node_modules/metro-cache/node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "node_modules/metro-cache-key": {
+ "version": "0.80.10",
+ "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.80.10.tgz",
+ "integrity": "sha512-57qBhO3zQfoU/hP4ZlLW5hVej2jVfBX6B4NcSfMj4LgDPL3YknWg80IJBxzQfjQY/m+fmMLmPy8aUMHzUp/guA==",
"dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
+ "flow-enums-runtime": "^0.0.6"
},
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
+ "engines": {
+ "node": ">=18"
}
},
"node_modules/metro-config": {
- "version": "0.80.9",
- "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.80.9.tgz",
- "integrity": "sha512-28wW7CqS3eJrunRGnsibWldqgwRP9ywBEf7kg+uzUHkSFJNKPM1K3UNSngHmH0EZjomizqQA2Zi6/y6VdZMolg==",
+ "version": "0.80.10",
+ "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.80.10.tgz",
+ "integrity": "sha512-0GYAw0LkmGbmA81FepKQepL1KU/85Cyv7sAiWm6QWeV6AcVCpsKg6jGLqGHJ0LLPL60rWzA4TV1DQAlzdJAEtA==",
"dependencies": {
"connect": "^3.6.5",
"cosmiconfig": "^5.0.5",
+ "flow-enums-runtime": "^0.0.6",
"jest-validate": "^29.6.3",
- "metro": "0.80.9",
- "metro-cache": "0.80.9",
- "metro-core": "0.80.9",
- "metro-runtime": "0.80.9"
+ "metro": "0.80.10",
+ "metro-cache": "0.80.10",
+ "metro-core": "0.80.10",
+ "metro-runtime": "0.80.10"
},
"engines": {
"node": ">=18"
}
},
"node_modules/metro-core": {
- "version": "0.80.9",
- "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.80.9.tgz",
- "integrity": "sha512-tbltWQn+XTdULkGdzHIxlxk4SdnKxttvQQV3wpqqFbHDteR4gwCyTR2RyYJvxgU7HELfHtrVbqgqAdlPByUSbg==",
+ "version": "0.80.10",
+ "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.80.10.tgz",
+ "integrity": "sha512-nwBB6HbpGlNsZMuzxVqxqGIOsn5F3JKpsp8PziS7Z4mV8a/jA1d44mVOgYmDa2q5WlH5iJfRIIhdz24XRNDlLA==",
"dependencies": {
+ "flow-enums-runtime": "^0.0.6",
"lodash.throttle": "^4.1.1",
- "metro-resolver": "0.80.9"
+ "metro-resolver": "0.80.10"
},
"engines": {
"node": ">=18"
}
},
"node_modules/metro-file-map": {
- "version": "0.80.9",
- "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.80.9.tgz",
- "integrity": "sha512-sBUjVtQMHagItJH/wGU9sn3k2u0nrCl0CdR4SFMO1tksXLKbkigyQx4cbpcyPVOAmGTVuy3jyvBlELaGCAhplQ==",
+ "version": "0.80.10",
+ "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.80.10.tgz",
+ "integrity": "sha512-ytsUq8coneaN7ZCVk1IogojcGhLIbzWyiI2dNmw2nnBgV/0A+M5WaTTgZ6dJEz3dzjObPryDnkqWPvIGLCPtiw==",
"dependencies": {
"anymatch": "^3.0.3",
"debug": "^2.2.0",
"fb-watchman": "^2.0.0",
+ "flow-enums-runtime": "^0.0.6",
"graceful-fs": "^4.2.4",
"invariant": "^2.2.4",
"jest-worker": "^29.6.3",
@@ -12536,52 +12448,17 @@
"ms": "2.0.0"
}
},
- "node_modules/metro-file-map/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/metro-file-map/node_modules/jest-worker": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz",
- "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==",
- "dependencies": {
- "@types/node": "*",
- "jest-util": "^29.7.0",
- "merge-stream": "^2.0.0",
- "supports-color": "^8.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
"node_modules/metro-file-map/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
- "node_modules/metro-file-map/node_modules/supports-color": {
- "version": "8.1.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
- "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/supports-color?sponsor=1"
- }
- },
"node_modules/metro-minify-terser": {
- "version": "0.80.9",
- "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.80.9.tgz",
- "integrity": "sha512-FEeCeFbkvvPuhjixZ1FYrXtO0araTpV6UbcnGgDUpH7s7eR5FG/PiJz3TsuuPP/HwCK19cZtQydcA2QrCw446A==",
+ "version": "0.80.10",
+ "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.80.10.tgz",
+ "integrity": "sha512-Xyv9pEYpOsAerrld7cSLIcnCCpv8ItwysOmTA+AKf1q4KyE9cxrH2O2SA0FzMCkPzwxzBWmXwHUr+A89BpEM6g==",
"dependencies": {
+ "flow-enums-runtime": "^0.0.6",
"terser": "^5.15.0"
},
"engines": {
@@ -12589,35 +12466,40 @@
}
},
"node_modules/metro-resolver": {
- "version": "0.80.9",
- "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.80.9.tgz",
- "integrity": "sha512-wAPIjkN59BQN6gocVsAvvpZ1+LQkkqUaswlT++cJafE/e54GoVkMNCmrR4BsgQHr9DknZ5Um/nKueeN7kaEz9w==",
+ "version": "0.80.10",
+ "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.80.10.tgz",
+ "integrity": "sha512-EYC5CL7f+bSzrqdk1bylKqFNGabfiI5PDctxoPx70jFt89Jz+ThcOscENog8Jb4LEQFG6GkOYlwmPpsi7kx3QA==",
+ "dependencies": {
+ "flow-enums-runtime": "^0.0.6"
+ },
"engines": {
"node": ">=18"
}
},
"node_modules/metro-runtime": {
- "version": "0.80.9",
- "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.80.9.tgz",
- "integrity": "sha512-8PTVIgrVcyU+X/rVCy/9yxNlvXsBCk5JwwkbAm/Dm+Abo6NBGtNjWF0M1Xo/NWCb4phamNWcD7cHdR91HhbJvg==",
+ "version": "0.80.10",
+ "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.80.10.tgz",
+ "integrity": "sha512-Xh0N589ZmSIgJYAM+oYwlzTXEHfASZac9TYPCNbvjNTn0EHKqpoJ/+Im5G3MZT4oZzYv4YnvzRtjqS5k0tK94A==",
"dependencies": {
- "@babel/runtime": "^7.0.0"
+ "@babel/runtime": "^7.0.0",
+ "flow-enums-runtime": "^0.0.6"
},
"engines": {
"node": ">=18"
}
},
"node_modules/metro-source-map": {
- "version": "0.80.9",
- "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.80.9.tgz",
- "integrity": "sha512-RMn+XS4VTJIwMPOUSj61xlxgBvPeY4G6s5uIn6kt6HB6A/k9ekhr65UkkDD7WzHYs3a9o869qU8tvOZvqeQzgw==",
+ "version": "0.80.10",
+ "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.80.10.tgz",
+ "integrity": "sha512-EyZswqJW8Uukv/HcQr6K19vkMXW1nzHAZPWJSEyJFKIbgp708QfRZ6vnZGmrtFxeJEaFdNup4bGnu8/mIOYlyA==",
"dependencies": {
"@babel/traverse": "^7.20.0",
"@babel/types": "^7.20.0",
+ "flow-enums-runtime": "^0.0.6",
"invariant": "^2.2.4",
- "metro-symbolicate": "0.80.9",
+ "metro-symbolicate": "0.80.10",
"nullthrows": "^1.1.1",
- "ob1": "0.80.9",
+ "ob1": "0.80.10",
"source-map": "^0.5.6",
"vlq": "^1.0.0"
},
@@ -12634,12 +12516,13 @@
}
},
"node_modules/metro-symbolicate": {
- "version": "0.80.9",
- "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.80.9.tgz",
- "integrity": "sha512-Ykae12rdqSs98hg41RKEToojuIW85wNdmSe/eHUgMkzbvCFNVgcC0w3dKZEhSsqQOXapXRlLtHkaHLil0UD/EA==",
+ "version": "0.80.10",
+ "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.80.10.tgz",
+ "integrity": "sha512-qAoVUoSxpfZ2DwZV7IdnQGXCSsf2cAUExUcZyuCqGlY5kaWBb0mx2BL/xbMFDJ4wBp3sVvSBPtK/rt4J7a0xBA==",
"dependencies": {
+ "flow-enums-runtime": "^0.0.6",
"invariant": "^2.2.4",
- "metro-source-map": "0.80.9",
+ "metro-source-map": "0.80.10",
"nullthrows": "^1.1.1",
"source-map": "^0.5.6",
"through2": "^2.0.1",
@@ -12661,14 +12544,15 @@
}
},
"node_modules/metro-transform-plugins": {
- "version": "0.80.9",
- "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.80.9.tgz",
- "integrity": "sha512-UlDk/uc8UdfLNJhPbF3tvwajyuuygBcyp+yBuS/q0z3QSuN/EbLllY3rK8OTD9n4h00qZ/qgxGv/lMFJkwP4vg==",
+ "version": "0.80.10",
+ "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.80.10.tgz",
+ "integrity": "sha512-leAx9gtA+2MHLsCeWK6XTLBbv2fBnNFu/QiYhWzMq8HsOAP4u1xQAU0tSgPs8+1vYO34Plyn79xTLUtQCRSSUQ==",
"dependencies": {
"@babel/core": "^7.20.0",
"@babel/generator": "^7.20.0",
"@babel/template": "^7.0.0",
"@babel/traverse": "^7.20.0",
+ "flow-enums-runtime": "^0.0.6",
"nullthrows": "^1.1.1"
},
"engines": {
@@ -12676,21 +12560,22 @@
}
},
"node_modules/metro-transform-worker": {
- "version": "0.80.9",
- "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.80.9.tgz",
- "integrity": "sha512-c/IrzMUVnI0hSVVit4TXzt3A1GiUltGVlzCmLJWxNrBGHGrJhvgePj38+GXl1Xf4Fd4vx6qLUkKMQ3ux73bFLQ==",
+ "version": "0.80.10",
+ "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.80.10.tgz",
+ "integrity": "sha512-zNfNLD8Rz99U+JdOTqtF2o7iTjcDMMYdVS90z6+81Tzd2D0lDWVpls7R1hadS6xwM+ymgXFQTjM6V6wFoZaC0g==",
"dependencies": {
"@babel/core": "^7.20.0",
"@babel/generator": "^7.20.0",
"@babel/parser": "^7.20.0",
"@babel/types": "^7.20.0",
- "metro": "0.80.9",
- "metro-babel-transformer": "0.80.9",
- "metro-cache": "0.80.9",
- "metro-cache-key": "0.80.9",
- "metro-minify-terser": "0.80.9",
- "metro-source-map": "0.80.9",
- "metro-transform-plugins": "0.80.9",
+ "flow-enums-runtime": "^0.0.6",
+ "metro": "0.80.10",
+ "metro-babel-transformer": "0.80.10",
+ "metro-cache": "0.80.10",
+ "metro-cache-key": "0.80.10",
+ "metro-minify-terser": "0.80.10",
+ "metro-source-map": "0.80.10",
+ "metro-transform-plugins": "0.80.10",
"nullthrows": "^1.1.1"
},
"engines": {
@@ -12755,26 +12640,6 @@
"ms": "2.0.0"
}
},
- "node_modules/metro/node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "deprecated": "Glob versions prior to v9 are no longer supported",
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/metro/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -12784,44 +12649,16 @@
}
},
"node_modules/metro/node_modules/hermes-estree": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.20.1.tgz",
- "integrity": "sha512-SQpZK4BzR48kuOg0v4pb3EAGNclzIlqMj3Opu/mu7bbAoFw6oig6cEt/RAi0zTFW/iW6Iz9X9ggGuZTAZ/yZHg=="
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.23.0.tgz",
+ "integrity": "sha512-Rkp0PNLGpORw4ktsttkVbpYJbrYKS3hAnkxu8D9nvQi6LvSbuPa+tYw/t2u3Gjc35lYd/k95YkjqyTcN4zspag=="
},
"node_modules/metro/node_modules/hermes-parser": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.20.1.tgz",
- "integrity": "sha512-BL5P83cwCogI8D7rrDCgsFY0tdYUtmFP9XaXtl2IQjC+2Xo+4okjfXintlTxcIwl4qeGddEl28Z11kbVIw0aNA==",
- "dependencies": {
- "hermes-estree": "0.20.1"
- }
- },
- "node_modules/metro/node_modules/jest-worker": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz",
- "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==",
- "dependencies": {
- "@types/node": "*",
- "jest-util": "^29.7.0",
- "merge-stream": "^2.0.0",
- "supports-color": "^8.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/metro/node_modules/jest-worker/node_modules/supports-color": {
- "version": "8.1.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
- "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.23.0.tgz",
+ "integrity": "sha512-xLwM4ylfHGwrm+2qXfO1JT/fnqEDGSnpS/9hQ4VLtqTexSviu2ZpBgz07U8jVtndq67qdb/ps0qvaWDZ3fkTyg==",
"dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/supports-color?sponsor=1"
+ "hermes-estree": "0.23.0"
}
},
"node_modules/metro/node_modules/ms": {
@@ -12829,21 +12666,6 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
- "node_modules/metro/node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "deprecated": "Rimraf versions prior to v4 are no longer supported",
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/metro/node_modules/source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
@@ -13069,50 +12891,6 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
- "node_modules/mv": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz",
- "integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==",
- "optional": true,
- "dependencies": {
- "mkdirp": "~0.5.1",
- "ncp": "~2.0.0",
- "rimraf": "~2.4.0"
- },
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/mv/node_modules/glob": {
- "version": "6.0.4",
- "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
- "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==",
- "deprecated": "Glob versions prior to v9 are no longer supported",
- "optional": true,
- "dependencies": {
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "2 || 3",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/mv/node_modules/rimraf": {
- "version": "2.4.5",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz",
- "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==",
- "deprecated": "Rimraf versions prior to v4 are no longer supported",
- "optional": true,
- "dependencies": {
- "glob": "^6.0.1"
- },
- "bin": {
- "rimraf": "bin.js"
- }
- },
"node_modules/mz": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
@@ -13151,15 +12929,6 @@
"integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
"dev": true
},
- "node_modules/ncp": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz",
- "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==",
- "optional": true,
- "bin": {
- "ncp": "bin/ncp"
- }
- },
"node_modules/negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
@@ -13256,6 +13025,11 @@
"url": "https://github.com/sponsors/antelle"
}
},
+ "node_modules/noop-fn": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/noop-fn/-/noop-fn-1.0.0.tgz",
+ "integrity": "sha512-pQ8vODlgXt2e7A3mIbFDlizkr46r75V+BJxVAyat8Jl7YmI513gG5cfyRL0FedKraoZ+VAouI1h4/IWpus5pcQ=="
+ },
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -13319,9 +13093,12 @@
"integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw=="
},
"node_modules/ob1": {
- "version": "0.80.9",
- "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.80.9.tgz",
- "integrity": "sha512-v9yOxowkZbxWhKOaaTyLjIm1aLy4ebMNcSn4NYJKOAI/Qv+SkfEfszpLr2GIxsccmb2Y2HA9qtsqiIJ80ucpVA==",
+ "version": "0.80.10",
+ "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.80.10.tgz",
+ "integrity": "sha512-dJHyB0S6JkMorUSfSGcYGkkg9kmq3qDUu3ygZUKIfkr47XOPuG35r2Sk6tbwtHXbdKIXmcMvM8DF2CwgdyaHfQ==",
+ "dependencies": {
+ "flow-enums-runtime": "^0.0.6"
+ },
"engines": {
"node": ">=18"
}
@@ -13893,9 +13670,9 @@
}
},
"node_modules/postcss": {
- "version": "8.4.40",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.40.tgz",
- "integrity": "sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==",
+ "version": "8.4.41",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz",
+ "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==",
"funding": [
{
"type": "opencollective",
@@ -13924,6 +13701,11 @@
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
},
+ "node_modules/pouchdb-collections": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/pouchdb-collections/-/pouchdb-collections-1.0.1.tgz",
+ "integrity": "sha512-31db6JRg4+4D5Yzc2nqsRqsA2oOkZS8DpFav3jf/qVNBxusKa2ClkEIZ2bJNpaDbMfWtnuSq59p6Bn+CipPMdg=="
+ },
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -14211,6 +13993,17 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-content-loader": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/react-content-loader/-/react-content-loader-7.0.2.tgz",
+ "integrity": "sha512-773S98JTyC8VB2nu7LXUhpHx8tZMieGxMcx3qTe7IkohT6Br7d9AXnIXs/wQ6IhlUdKQcw6JLKk1QKigYCWDRA==",
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "react": ">=16.0.0"
+ }
+ },
"node_modules/react-devtools-core": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-5.3.1.tgz",
@@ -14269,21 +14062,21 @@
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/react-native": {
- "version": "0.74.3",
- "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.74.3.tgz",
- "integrity": "sha512-UFutCC6WEw6HkxlcpQ2BemKqi0JkwrgDchYB5Svi8Sp4Xwt4HA6LGEjNQgZ+3KM44bjyFRpofQym0uh0jACGng==",
+ "version": "0.74.5",
+ "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.74.5.tgz",
+ "integrity": "sha512-Bgg2WvxaGODukJMTZFTZBNMKVaROHLwSb8VAGEdrlvKwfb1hHg/3aXTUICYk7dwgAnb+INbGMwnF8yeAgIUmqw==",
"dependencies": {
"@jest/create-cache-key-function": "^29.6.3",
"@react-native-community/cli": "13.6.9",
"@react-native-community/cli-platform-android": "13.6.9",
"@react-native-community/cli-platform-ios": "13.6.9",
- "@react-native/assets-registry": "0.74.85",
- "@react-native/codegen": "0.74.85",
- "@react-native/community-cli-plugin": "0.74.85",
- "@react-native/gradle-plugin": "0.74.85",
- "@react-native/js-polyfills": "0.74.85",
- "@react-native/normalize-colors": "0.74.85",
- "@react-native/virtualized-lists": "0.74.85",
+ "@react-native/assets-registry": "0.74.87",
+ "@react-native/codegen": "0.74.87",
+ "@react-native/community-cli-plugin": "0.74.87",
+ "@react-native/gradle-plugin": "0.74.87",
+ "@react-native/js-polyfills": "0.74.87",
+ "@react-native/normalize-colors": "0.74.87",
+ "@react-native/virtualized-lists": "0.74.87",
"abort-controller": "^3.0.0",
"anser": "^1.4.9",
"ansi-regex": "^5.0.0",
@@ -14415,24 +14208,6 @@
"react-native": "*"
}
},
- "node_modules/react-native-root-siblings": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/react-native-root-siblings/-/react-native-root-siblings-4.1.1.tgz",
- "integrity": "sha512-sdmLElNs5PDWqmZmj4/aNH4anyxreaPm61c4ZkRiR8SO/GzLg6KjAbb0e17RmMdnBdD0AIQbS38h/l55YKN4ZA=="
- },
- "node_modules/react-native-root-toast": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/react-native-root-toast/-/react-native-root-toast-3.6.0.tgz",
- "integrity": "sha512-HgZ2OS84ZbInJGuejGghBCPmBwoSBuJFO/bAJoR/NS6rCl9eiXSRegIG/gLEo7lH9BijeA63is1noUqR8Y1DpQ==",
- "dependencies": {
- "deprecated-react-native-prop-types": "^2.3.0",
- "prop-types": "^15.5.10",
- "react-native-root-siblings": "^4.0.0"
- },
- "peerDependencies": {
- "react-native": ">=0.47.0"
- }
- },
"node_modules/react-native-safe-area-context": {
"version": "4.10.5",
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.10.5.tgz",
@@ -14443,9 +14218,9 @@
}
},
"node_modules/react-native-screens": {
- "version": "3.33.0",
- "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.33.0.tgz",
- "integrity": "sha512-3bKeT/kS1g/6XqraBqjDtyyci35LDeDIHMoko74o+Z5p1oLEi697GWFVwsG272FF0iuOullUbuRNzCcEfRBASQ==",
+ "version": "3.31.1",
+ "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.31.1.tgz",
+ "integrity": "sha512-8fRW362pfZ9y4rS8KY5P3DFScrmwo/vu1RrRMMx0PNHbeC9TLq0Kw1ubD83591yz64gLNHFLTVkTJmWeWCXKtQ==",
"dependencies": {
"react-freeze": "^1.0.0",
"warn-once": "^0.1.0"
@@ -14534,6 +14309,15 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
+ "node_modules/react-native-toast-message": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/react-native-toast-message/-/react-native-toast-message-2.2.0.tgz",
+ "integrity": "sha512-AFti8VzUk6JvyGAlLm9/BknTNDXrrhqnUk7ak/pM7uCTxDPveAu2ekszU0on6vnUPFnG04H/QfYE2IlETqeaWw==",
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
"node_modules/react-native-vector-icons": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-10.0.0.tgz",
@@ -14633,27 +14417,10 @@
"node": ">=8"
}
},
- "node_modules/react-native/node_modules/@react-native/virtualized-lists": {
- "version": "0.74.85",
- "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.74.85.tgz",
- "integrity": "sha512-jx2Zw0qlZteoQ+0KxRc7s4drsljLBEP534FaNZ950e9+CN9nVkLsV6rigcTjDR8wjKMSBWhKf0C0C3egYz7Ehg==",
- "dependencies": {
- "invariant": "^2.2.4",
- "nullthrows": "^1.1.1"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@types/react": "^18.2.6",
- "react": "*",
- "react-native": "*"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
+ "node_modules/react-native/node_modules/@react-native/normalize-colors": {
+ "version": "0.74.87",
+ "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.74.87.tgz",
+ "integrity": "sha512-Xh7Nyk/MPefkb0Itl5Z+3oOobeG9lfLb7ZOY2DKpFnoCE1TzBmib9vMNdFaLdSxLIP+Ec6icgKtdzYg8QUPYzA=="
},
"node_modules/react-native/node_modules/ansi-styles": {
"version": "4.3.0",
@@ -14806,6 +14573,20 @@
"node": ">= 4"
}
},
+ "node_modules/recyclerlistview": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/recyclerlistview/-/recyclerlistview-4.2.0.tgz",
+ "integrity": "sha512-uuBCi0c+ggqHKwrzPX4Z/mJOzsBbjZEAwGGmlwpD/sD7raXixdAbdJ6BTcAmuWG50Cg4ru9p12M94Njwhr/27A==",
+ "dependencies": {
+ "lodash.debounce": "4.0.8",
+ "prop-types": "15.8.1",
+ "ts-object-utils": "0.0.5"
+ },
+ "peerDependencies": {
+ "react": ">= 15.2.1",
+ "react-native": ">= 0.30.0"
+ }
+ },
"node_modules/reflect.getprototypeof": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz",
@@ -15027,15 +14808,18 @@
}
},
"node_modules/rimraf": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
- "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"deprecated": "Rimraf versions prior to v4 are no longer supported",
"dependencies": {
"glob": "^7.1.3"
},
"bin": {
"rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/rimraf/node_modules/glob": {
@@ -15102,12 +14886,6 @@
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
- "node_modules/safe-json-stringify": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz",
- "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==",
- "optional": true
- },
"node_modules/safe-regex-test": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz",
@@ -16000,9 +15778,9 @@
}
},
"node_modules/terser": {
- "version": "5.20.0",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.20.0.tgz",
- "integrity": "sha512-e56ETryaQDyebBwJIWYB2TT6f2EZ0fL0sW/JRXNMN26zZdKi2u/E/5my5lG6jNxym6qsrVXfFRmOdV42zlAgLQ==",
+ "version": "5.31.5",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.5.tgz",
+ "integrity": "sha512-YPmas0L0rE1UyLL/llTWA0SiDOqIcAQYLeUj7cJYzXHlRTAnMSg9pPe4VJ5PlKvTrPQsdVFuiRiwyeNlYgwh2Q==",
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.8.2",
@@ -16072,6 +15850,11 @@
"xtend": "~4.0.1"
}
},
+ "node_modules/tiny-queue": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/tiny-queue/-/tiny-queue-0.2.1.tgz",
+ "integrity": "sha512-EijGsv7kzd9I9g0ByCl6h42BWNGUZrlCSejfrb3AKeHC33SGbASu1VDf5O3rRiiUOhAC9CHdZxFPbZu0HmR70A=="
+ },
"node_modules/tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
@@ -16144,19 +15927,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/trim-right": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
- "integrity": "sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/ts-interface-checker": {
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="
},
+ "node_modules/ts-object-utils": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/ts-object-utils/-/ts-object-utils-0.0.5.tgz",
+ "integrity": "sha512-iV0GvHqOmilbIKJsfyfJY9/dNHCs969z3so90dQWsO1eMMozvTpnB1MEaUbb3FYtZTGjv5sIy/xmslEz0Rg2TA=="
+ },
"node_modules/tsconfig-paths": {
"version": "3.14.2",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz",
@@ -16513,6 +16293,14 @@
"react": ">=16.8"
}
},
+ "node_modules/use-sync-external-store": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
+ "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -16957,23 +16745,31 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/zod": {
- "version": "3.23.8",
- "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz",
- "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==",
- "funding": {
- "url": "https://github.com/sponsors/colinhacks"
- }
- },
- "node_modules/zod-validation-error": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-2.1.0.tgz",
- "integrity": "sha512-VJh93e2wb4c3tWtGgTa0OF/dTt/zoPCPzXq4V11ZjxmEAFaPi/Zss1xIZdEB5RD8GD00U0/iVXgqkF77RV7pdQ==",
+ "node_modules/zustand": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.4.tgz",
+ "integrity": "sha512-/BPMyLKJPtFEvVL0E9E9BTUM63MNyhPGlvxk1XjrfWTUlV+BR8jufjsovHzrtR6YNcBEcL7cMHovL1n9xHawEg==",
+ "dependencies": {
+ "use-sync-external-store": "1.2.0"
+ },
"engines": {
- "node": ">=18.0.0"
+ "node": ">=12.7.0"
},
"peerDependencies": {
- "zod": "^3.18.0"
+ "@types/react": ">=16.8",
+ "immer": ">=9.0.6",
+ "react": ">=16.8"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "immer": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ }
}
}
}
diff --git a/package.json b/package.json
index 365c5c2..dc96b4b 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"version": "1.0.0",
"main": "node_modules/expo/AppEntry.js",
"scripts": {
- "start": "expo start",
+ "start": "expo start --tunnel",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
@@ -15,31 +15,35 @@
"@react-native-community/netinfo": "11.3.1",
"@react-navigation/bottom-tabs": "^6.5.8",
"@react-navigation/native": "^6.1.7",
+ "@shopify/flash-list": "1.6.4",
"casdoor-react-native-sdk": "1.1.0",
"eslint-plugin-import": "^2.28.1",
- "expo": "~51.0.24",
+ "expo": "~51.0.26",
"expo-camera": "~15.0.14",
- "expo-dev-client": "^4.0.21",
+ "expo-dev-client": "~4.0.22",
"expo-image": "^1.12.13",
+ "expo-sqlite": "~14.0.6",
"expo-status-bar": "~1.12.1",
"expo-system-ui": "~3.0.7",
- "expo-updates": "~0.25.21",
+ "expo-updates": "~0.25.22",
"hotp-totp": "^1.0.6",
"prop-types": "^15.8.1",
"react": "18.2.0",
+ "react-content-loader": "^7.0.2",
"react-dom": "18.2.0",
- "react-native": "0.74.3",
+ "react-native": "0.74.5",
"react-native-countdown-circle-timer": "^3.2.1",
"react-native-gesture-handler": "~2.16.1",
"react-native-paper": "^5.10.3",
"react-native-reanimated": "~3.10.1",
- "react-native-root-toast": "^3.6.0",
"react-native-safe-area-context": "4.10.5",
- "react-native-screens": "^3.31.1",
+ "react-native-screens": "3.31.1",
"react-native-svg": "15.2.0",
+ "react-native-toast-message": "^2.2.0",
"react-native-web": "~0.19.6",
"react-native-webview": "13.8.6",
- "totp-generator": "^0.0.14"
+ "totp-generator": "^0.0.14",
+ "zustand": "^4.5.4"
},
"verifyConditions": [
"semantic-release-expo",
diff --git a/useStorage.js b/useStorage.js
new file mode 100644
index 0000000..ae7cad2
--- /dev/null
+++ b/useStorage.js
@@ -0,0 +1,70 @@
+// Copyright 2024 The Casdoor Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {create} from "zustand";
+import {createJSONStorage, persist} from "zustand/middleware";
+import AsyncStorage from "@react-native-async-storage/async-storage";
+
+const asyncStoragePersistConfig = {
+ setItem: async(key, value) => await AsyncStorage.setItem(key, value),
+ getItem: async(key) => await AsyncStorage.getItem(key),
+ removeItem: async(key) => await AsyncStorage.removeItem(key),
+};
+
+const useStore = create(
+ persist(
+ (set, get) => ({
+ serverUrl: "",
+ clientId: "",
+ redirectPath: "http://casdoor-app",
+ appName: "",
+ organizationName: "",
+ signinPath: "/api/signin",
+ userInfo: null,
+ token: null,
+ setServerUrl: (url) => set({serverUrl: url}),
+ setClientId: (id) => set({clientId: id}),
+ setRedirectPath: (path) => set({redirectPath: path}),
+ setAppName: (name) => set({appName: name}),
+ setOrganizationName: (name) => set({organizationName: name}),
+ setSigninPath: (path) => set({signinPath: path}),
+ setUserInfo: (info) => set({userInfo: info}),
+ setToken: (token) => set({token: token}),
+ clearAll: () => set({userInfo: null, token: null}),
+
+ getCasdoorConfig: () => ({
+ serverUrl: get().serverUrl,
+ clientId: get().clientId,
+ appName: get().appName,
+ organizationName: get().organizationName,
+ redirectPath: get().redirectPath,
+ signinPath: get().signinPath,
+ }),
+ setCasdoorConfig: (config) => set({
+ serverUrl: config.serverUrl || get().serverUrl,
+ clientId: config.clientId || get().clientId,
+ appName: config.appName || get().appName,
+ organizationName: config.organizationName || get().organizationName,
+ redirectPath: config.redirectPath || get().redirectPath,
+ signinPath: config.signinPath || get().signinPath,
+ }),
+ }),
+ {
+ name: "casdoor-storage",
+ storage: createJSONStorage(() => asyncStoragePersistConfig),
+ }
+ )
+);
+
+export default useStore;
diff --git a/useSync.js b/useSync.js
deleted file mode 100644
index 812869c..0000000
--- a/useSync.js
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2024 The Casdoor Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import {useCallback, useEffect, useState} from "react";
-import * as api from "./api";
-import {useNetInfo} from "@react-native-community/netinfo";
-
-export const SYNC_STATUS = {
- ADD: "add",
- EDIT: "edit",
- DELETE: "delete",
-};
-
-const applySync = (serverAccountList, toSyncData) => {
- return toSyncData.reduce((acc, syncItem) => {
- switch (syncItem.status) {
- case SYNC_STATUS.ADD:
- if (!acc.some(account => account.accountName === syncItem.data.accountName && account.secretKey === syncItem.data.secretKey)) {
- acc.push(syncItem.data);
- }
- break;
- case SYNC_STATUS.EDIT:
- const indexToEdit = acc.findIndex(account => account.accountName === syncItem.data.accountName && account.secretKey === syncItem.data.secretKey);
- if (indexToEdit !== -1) {
- acc[indexToEdit] = {...acc[indexToEdit], ...syncItem.data, accountName: syncItem.newAccountName};
- }
- break;
- case SYNC_STATUS.DELETE:
- return acc.filter(account => !(account.accountName === syncItem.data.accountName && account.secretKey === syncItem.data.secretKey));
- default:
- break;
- }
- return acc;
- }, [...serverAccountList]);
-};
-
-const useSync = (userInfo, token, casdoorServer) => {
- const [toSyncData, setToSyncData] = useState([]);
- const [syncSignal, setSyncSignal] = useState(false);
- const {isConnected} = useNetInfo();
- const [canSync, setCanSync] = useState(false);
-
- useEffect(() => {
- setCanSync(userInfo && casdoorServer && isConnected);
- }, [userInfo, casdoorServer, isConnected]);
-
- const triggerSync = useCallback(() => {
- if (canSync) {
- setSyncSignal(true);
- }
- }, [canSync]);
-
- const resetSyncSignal = useCallback(() => {
- setSyncSignal(false);
- }, []);
-
- const addToSyncData = useCallback((toSyncAccount, status, newAccountName = null) => {
- setToSyncData([...toSyncData, {
- data: {
- accountName: toSyncAccount.accountName,
- issuer: toSyncAccount.issuer,
- secretKey: toSyncAccount.secretKey,
- },
- status,
- newAccountName: newAccountName || "",
- }]);
- }, []);
-
- const syncAccounts = useCallback(async() => {
- if (!canSync) {return {success: false, error: "Cannot sync"};}
-
- try {
- const {mfaAccounts: serverAccountList} = await api.getMfaAccounts(
- casdoorServer.serverUrl,
- userInfo.owner,
- userInfo.name,
- token
- );
-
- if (!serverAccountList) {
- return {success: false, error: "Failed to get accounts"};
- }
-
- if (toSyncData.length === 0) {
- return {success: true, accountList: serverAccountList};
- }
-
- const updatedServerAccountList = applySync(serverAccountList, toSyncData);
-
- const {status} = await api.updateMfaAccounts(
- casdoorServer.serverUrl,
- userInfo.owner,
- userInfo.name,
- updatedServerAccountList,
- token
- );
-
- if (status === "ok") {setToSyncData([]);}
- return {success: status === "ok", accountList: updatedServerAccountList};
-
- } catch (error) {
- return {success: false, error: error.message};
- }
- }, [canSync, casdoorServer, userInfo, token, toSyncData]);
-
- useEffect(() => {
- if (canSync) {triggerSync();}
- }, [canSync, toSyncData]);
-
- return {
- syncSignal,
- resetSyncSignal,
- syncAccounts,
- addToSyncData,
- };
-};
-
-export default useSync;
diff --git a/useSyncStore.js b/useSyncStore.js
new file mode 100644
index 0000000..513cb74
--- /dev/null
+++ b/useSyncStore.js
@@ -0,0 +1,38 @@
+// Copyright 2024 The Casdoor Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {create} from "zustand";
+import * as TotpDatabase from "./TotpDatabase";
+
+const useSyncStore = create((set, get) => ({
+ isSyncing: false,
+ syncError: null,
+
+ startSync: async(db, userInfo, casdoorServer, token) => {
+ if (!get().isSyncing) {
+ set({isSyncing: true, syncError: null});
+ try {
+ await TotpDatabase.syncWithCloud(db, userInfo, casdoorServer, token);
+ } catch (error) {
+ set({syncError: error.message});
+ } finally {
+ set({isSyncing: false});
+ }
+ }
+ },
+
+ clearSyncError: () => set({syncError: null}),
+}));
+
+export default useSyncStore;