Added biome for formatting, code formatted

This commit is contained in:
Filip Rojek 2024-05-08 16:50:25 +02:00
parent dc446fe8dc
commit e62ef8695b
15 changed files with 678 additions and 510 deletions

View File

@ -1,34 +1,30 @@
{ {
"expo": { "expo": {
"name": "deguapp", "name": "deguapp",
"slug": "deguapp", "slug": "deguapp",
"scheme": "deguapp", "scheme": "deguapp",
"version": "1.0.0", "version": "1.0.0",
"orientation": "portrait", "orientation": "portrait",
"icon": "./assets/icon.png", "icon": "./assets/icon.png",
"userInterfaceStyle": "light", "userInterfaceStyle": "light",
"splash": { "splash": {
"image": "./assets/splash.png", "image": "./assets/splash.png",
"resizeMode": "contain", "resizeMode": "contain",
"backgroundColor": "#ffffff" "backgroundColor": "#ffffff"
}, },
"assetBundlePatterns": [ "assetBundlePatterns": ["**/*"],
"**/*" "ios": {
], "supportsTablet": true
"ios": { },
"supportsTablet": true "android": {
}, "adaptiveIcon": {
"android": { "foregroundImage": "./assets/adaptive-icon.png",
"adaptiveIcon": { "backgroundColor": "#ffffff"
"foregroundImage": "./assets/adaptive-icon.png", }
"backgroundColor": "#ffffff" },
} "web": {
}, "favicon": "./assets/favicon.png"
"web": { },
"favicon": "./assets/favicon.png" "plugins": ["expo-router"]
}, }
"plugins": [
"expo-router"
]
}
} }

View File

@ -4,19 +4,19 @@ import { useAuth } from "../context/AuthContext";
import { View, Text } from "react-native"; import { View, Text } from "react-native";
export default function AppLayout() { export default function AppLayout() {
const { authState } = useAuth(); const { authState } = useAuth();
if (authState.authenticated === null) { if (authState.authenticated === null) {
// micro loading co neni skoro videt ale get the fuck out se uz neloguje // micro loading co neni skoro videt ale get the fuck out se uz neloguje
return ( return (
<View> <View>
<Text>Loading...</Text> <Text>Loading...</Text>
</View> </View>
); );
} }
if (!authState.authenticated) { if (!authState.authenticated) {
console.log("get the fuck out"); console.log("get the fuck out");
return <Redirect href="/login" />; return <Redirect href="/login" />;
} }
return <Stack />; return <Stack />;
} }

View File

@ -3,21 +3,21 @@ import { Text, View } from "react-native";
import { useAuth } from "../context/AuthContext"; import { useAuth } from "../context/AuthContext";
export default function Index() { export default function Index() {
const { onLogout, authState } = useAuth(); const { onLogout, authState } = useAuth();
const user = authState.user; const user = authState.user;
return ( return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}> <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Welcome {user.username}</Text> <Text>Welcome {user.username}</Text>
<Text <Text
onPress={() => { onPress={() => {
// The `app/(app)/_layout.tsx` will redirect to the sign-in screen. // The `app/(app)/_layout.tsx` will redirect to the sign-in screen.
onLogout(); onLogout();
}} }}
> >
Sign Out Sign Out
</Text> </Text>
</View> </View>
); );
} }

View File

@ -3,10 +3,10 @@ import { StatusBar } from "expo-status-bar";
import { AuthProvider } from "./context/AuthContext"; import { AuthProvider } from "./context/AuthContext";
export default function Root() { export default function Root() {
return ( return (
<AuthProvider> <AuthProvider>
<StatusBar style="light" /> <StatusBar style="light" />
<Slot /> <Slot />
</AuthProvider> </AuthProvider>
); );
} }

View File

@ -6,134 +6,134 @@ export const API_URL = "http://10.69.1.137:6060/api/v1";
const AuthContext = createContext(null); const AuthContext = createContext(null);
export function useAuth() { export function useAuth() {
const authContext = useContext(AuthContext); const authContext = useContext(AuthContext);
if (authContext === undefined) { if (authContext === undefined) {
throw new Error("Context is outside of provider"); throw new Error("Context is outside of provider");
} }
return authContext; return authContext;
} }
export function AuthProvider({ children }) { export function AuthProvider({ children }) {
const [authState, setAuthState] = useState({ const [authState, setAuthState] = useState({
token: null, token: null,
authenticated: null, authenticated: null,
}); });
useEffect(() => { useEffect(() => {
// tohle se zavola jen poprve pri startu appky // tohle se zavola jen poprve pri startu appky
async function loadToken() { async function loadToken() {
const token = await storageUtil.getItem(TOKEN_KEY); const token = await storageUtil.getItem(TOKEN_KEY);
console.log(`stored: ${token}`); console.log(`stored: ${token}`);
const resUser = await fetch(`${API_URL}/auth/status`, { const resUser = await fetch(`${API_URL}/auth/status`, {
credentials: "include", credentials: "include",
}); });
const userData = await resUser.json(); const userData = await resUser.json();
if (token && resUser.status == 200) { if (token && resUser.status == 200) {
setAuthState({ setAuthState({
token: token, token: token,
authenticated: true, authenticated: true,
user: userData.data, user: userData.data,
}); });
return; return;
} }
setAuthState({ setAuthState({
authenticated: false, authenticated: false,
token: null, token: null,
user: null, user: null,
}); });
} }
loadToken(); loadToken();
}, []); }, []);
async function register(username, email, password) { async function register(username, email, password) {
try { try {
const res = await fetch(`${API_URL}/auth/signup`, { const res = await fetch(`${API_URL}/auth/signup`, {
method: 'POST', method: "POST",
credentials: 'include', credentials: "include",
headers: { headers: {
"Content-Type": "application/json" "Content-Type": "application/json",
}, },
body: JSON.stringify({ body: JSON.stringify({
username, username,
email, email,
password password,
}) }),
}) });
return res; return res;
} catch (err) { } catch (err) {
return { error: true, msg: err.response.data }; return { error: true, msg: err.response.data };
} }
} }
async function login(email, password) { async function login(email, password) {
try { try {
const resLogin = await fetch(`${API_URL}/auth/signin`, { const resLogin = await fetch(`${API_URL}/auth/signin`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
body: JSON.stringify({ body: JSON.stringify({
email, email,
password, password,
}), }),
}); });
const loginData = await resLogin.json(); const loginData = await resLogin.json();
const resUser = await fetch(`${API_URL}/auth/status`, { const resUser = await fetch(`${API_URL}/auth/status`, {
credentials: "include", credentials: "include",
}); });
if (resUser.status != 200) { if (resUser.status != 200) {
throw Error("user does not have user data"); throw Error("user does not have user data");
} }
const userData = await resUser.json(); const userData = await resUser.json();
setAuthState({ setAuthState({
token: loginData.data.jwt, token: loginData.data.jwt,
authenticated: true, authenticated: true,
user: userData.data, user: userData.data,
}); });
await storageUtil.setItem(TOKEN_KEY, loginData.data.jwt); await storageUtil.setItem(TOKEN_KEY, loginData.data.jwt);
} catch (err) { } catch (err) {
console.error("Failed to log in", err) console.error("Failed to log in", err);
return { error: true, msg: err.res }; return { error: true, msg: err.res };
} }
} }
async function logout() { async function logout() {
let res = await fetch(`${API_URL}/auth/logout`, { let res = await fetch(`${API_URL}/auth/logout`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
body: JSON.stringify({}), body: JSON.stringify({}),
}); });
res = await res.json(); res = await res.json();
await storageUtil.delItem(TOKEN_KEY); await storageUtil.delItem(TOKEN_KEY);
setAuthState({ setAuthState({
token: null, token: null,
authenticated: false, authenticated: false,
user: null, user: null,
}); });
} }
const value = { const value = {
onSignin: register, onSignin: register,
onLogin: login, onLogin: login,
onLogout: logout, onLogout: logout,
authState, authState,
}; };
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>; return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
} }

View File

@ -3,32 +3,32 @@ import { Platform } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage"; import AsyncStorage from "@react-native-async-storage/async-storage";
const storageUtil = { const storageUtil = {
setItem: async (k, v) => { setItem: async (k, v) => {
if (Platform.OS === "web") { if (Platform.OS === "web") {
// web // web
await AsyncStorage.setItem(k, v); await AsyncStorage.setItem(k, v);
} else { } else {
// mobile // mobile
await SecureStore.setItemAsync(k, v.toString()); // v must be string, await SecureStore.setItemAsync(k, v.toString()); // v must be string,
} }
}, },
getItem: async (k) => { getItem: async (k) => {
if (Platform.OS === "web") { if (Platform.OS === "web") {
// web // web
return await AsyncStorage.getItem(k); return await AsyncStorage.getItem(k);
} else { } else {
// mobile // mobile
return await SecureStore.getItemAsync(k); return await SecureStore.getItemAsync(k);
} }
}, },
delItem: async (k) => { delItem: async (k) => {
if (Platform.OS === "web") { if (Platform.OS === "web") {
// web // web
await AsyncStorage.removeItem(k); await AsyncStorage.removeItem(k);
} else { } else {
// mobile // mobile
await SecureStore.deleteItemAsync(k); await SecureStore.deleteItemAsync(k);
} }
}, },
}; };
export default storageUtil; export default storageUtil;

View File

@ -1,6 +1,6 @@
import { useAuth } from "../context/AuthContext"; import { useAuth } from "../context/AuthContext";
export function useIsAutheticated() { export function useIsAutheticated() {
const { authState } = useAuth(); const { authState } = useAuth();
return authState.authenticated return authState.authenticated;
} }

View File

@ -7,111 +7,111 @@ import { colors } from "../components/style";
import { useAuth } from "./context/AuthContext"; import { useAuth } from "./context/AuthContext";
function LoginPage() { function LoginPage() {
const [pass, setPass] = useState(""); const [pass, setPass] = useState("");
const [email, setEmail] = useState(""); const [email, setEmail] = useState("");
const { onLogin, authState } = useAuth(); const { onLogin, authState } = useAuth();
useEffect(() => { useEffect(() => {
if (authState.authenticated) { if (authState.authenticated) {
router.replace("/"); router.replace("/");
} }
}, [authState.authenticated]); }, [authState.authenticated]);
function login() { function login() {
onLogin(email, pass); onLogin(email, pass);
} }
return ( return (
<View style={styles.container}> <View style={styles.container}>
<View style={styles.header}> <View style={styles.header}>
<Image <Image
source={require("../assets/deguapp_logo.png")} source={require("../assets/deguapp_logo.png")}
style={styles.logo} style={styles.logo}
/> />
<Text style={styles.h1}>Please Log In</Text> <Text style={styles.h1}>Please Log In</Text>
</View> </View>
<View style={styles.form}> <View style={styles.form}>
<TextInput <TextInput
style={styles.input} style={styles.input}
placeholder="Enter your email" placeholder="Enter your email"
autoCapitalize="none" autoCapitalize="none"
autoCompleteType="email" autoCompleteType="email"
textContentType="emailAddress" textContentType="emailAddress"
keyboardType="email-address" keyboardType="email-address"
placeholderTextColor={"#aaaaaa"} placeholderTextColor={"#aaaaaa"}
returnKeyType="next" returnKeyType="next"
value={email} value={email}
onChangeText={(text) => setEmail(text)} onChangeText={(text) => setEmail(text)}
/> />
<TextInput <TextInput
style={styles.input} style={styles.input}
secureTextEntry={true} secureTextEntry={true}
placeholder="Enter your password" placeholder="Enter your password"
placeholderTextColor={"#aaaaaa"} placeholderTextColor={"#aaaaaa"}
returnKeyType="done" returnKeyType="done"
value={pass} value={pass}
onChangeText={(text) => setPass(text)} onChangeText={(text) => setPass(text)}
/> />
<View style={styles.btnContainer}> <View style={styles.btnContainer}>
<Button <Button
style={styles.button} style={styles.button}
title="Sign Up" title="Sign Up"
color={colors.charcoal} color={colors.charcoal}
onPress={() => router.replace("/signup")} onPress={() => router.replace("/signup")}
/> />
<Button <Button
style={styles.button} style={styles.button}
title="Log In" title="Log In"
color={colors.gold} color={colors.gold}
onPress={login} onPress={login}
/> />
</View> </View>
</View> </View>
</View> </View>
); );
} }
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
width: "100%", width: "100%",
height: "100%", height: "100%",
backgroundColor: colors.dark, backgroundColor: colors.dark,
}, },
form: { form: {
flex: 1, flex: 1,
alignItems: "center", alignItems: "center",
paddingTop: "10%", paddingTop: "10%",
width: "100%", width: "100%",
gap: 15, gap: 15,
}, },
h1: { h1: {
color: "#FFF", color: "#FFF",
fontSize: 30, fontSize: 30,
textAlign: "center", textAlign: "center",
paddingTop: "20%", paddingTop: "20%",
}, },
logo: { logo: {
width: "80%", width: "80%",
resizeMode: "contain", resizeMode: "contain",
}, },
header: { header: {
width: "100%", width: "100%",
alignItems: "center", alignItems: "center",
paddingTop: "20%", paddingTop: "20%",
}, },
input: { input: {
height: "auto", height: "auto",
width: "60%", width: "60%",
borderColor: "gray", borderColor: "gray",
borderWidth: 1, borderWidth: 1,
borderRadius: 5, borderRadius: 5,
padding: 10, padding: 10,
color: "#fff", color: "#fff",
}, },
btnContainer: { btnContainer: {
flexDirection: "row", flexDirection: "row",
gap: 5, gap: 5,
}, },
}); });
export default LoginPage; export default LoginPage;

View File

@ -7,142 +7,142 @@ import { Link, router } from "expo-router";
import { useAuth } from "./context/AuthContext"; import { useAuth } from "./context/AuthContext";
function SignupPage() { function SignupPage() {
const [pass1, setPass1] = useState(""); const [pass1, setPass1] = useState("");
const [pass2, setPass2] = useState(""); const [pass2, setPass2] = useState("");
const [email, setEmail] = useState(""); const [email, setEmail] = useState("");
const [username, setUsername] = useState(""); const [username, setUsername] = useState("");
const { onSignin } = useAuth(); const { onSignin } = useAuth();
async function signin() { async function signin() {
if (pass1 == pass2) { if (pass1 == pass2) {
const res = await onSignin(username, email, pass1); const res = await onSignin(username, email, pass1);
if (res.error) { if (res.error) {
if(res.msg.message == "validation error") { if (res.msg.message == "validation error") {
alert(res.msg.data.message); alert(res.msg.data.message);
} else { } else {
alert(res.msg.message) alert(res.msg.message);
} }
} }
if (!res.error) { if (!res.error) {
alert("You have been successfully registered. Please Log In"); alert("You have been successfully registered. Please Log In");
router.replace("/login"); router.replace("/login");
} }
return; return;
} }
alert("Passwords are not same!"); alert("Passwords are not same!");
} }
return ( return (
<View style={styles.container}> <View style={styles.container}>
<View style={styles.header}> <View style={styles.header}>
<Image <Image
source={require("../assets/deguapp_logo.png")} source={require("../assets/deguapp_logo.png")}
style={styles.logo} style={styles.logo}
/> />
<Text style={styles.h1}>Please Sign Up</Text> <Text style={styles.h1}>Please Sign Up</Text>
</View> </View>
<View style={styles.form}> <View style={styles.form}>
<TextInput <TextInput
style={styles.input} style={styles.input}
placeholder="Enter your username" placeholder="Enter your username"
placeholderTextColor={"#aaaaaa"} placeholderTextColor={"#aaaaaa"}
returnKeyType="done" returnKeyType="done"
value={username} value={username}
onChangeText={(username) => setUsername(username)} onChangeText={(username) => setUsername(username)}
/> />
<TextInput <TextInput
style={styles.input} style={styles.input}
placeholder="Enter your email" placeholder="Enter your email"
autoCapitalize="none" autoCapitalize="none"
autoCompleteType="email" autoCompleteType="email"
textContentType="emailAddress" textContentType="emailAddress"
keyboardType="email-address" keyboardType="email-address"
placeholderTextColor={"#aaaaaa"} placeholderTextColor={"#aaaaaa"}
returnKeyType="next" returnKeyType="next"
value={email} value={email}
onChangeText={(email) => setEmail(email)} onChangeText={(email) => setEmail(email)}
/> />
<TextInput <TextInput
style={styles.input} style={styles.input}
secureTextEntry={true} secureTextEntry={true}
placeholder="Enter your password" placeholder="Enter your password"
placeholderTextColor={"#aaaaaa"} placeholderTextColor={"#aaaaaa"}
returnKeyType="done" returnKeyType="done"
value={pass1} value={pass1}
onChangeText={(pass1) => setPass1(pass1)} onChangeText={(pass1) => setPass1(pass1)}
/> />
<TextInput <TextInput
style={styles.input} style={styles.input}
secureTextEntry={true} secureTextEntry={true}
placeholder="Enter your password" placeholder="Enter your password"
placeholderTextColor={"#aaaaaa"} placeholderTextColor={"#aaaaaa"}
returnKeyType="done" returnKeyType="done"
value={pass2} value={pass2}
onChangeText={(pass2) => setPass2(pass2)} onChangeText={(pass2) => setPass2(pass2)}
/> />
<Button <Button
style={styles.button} style={styles.button}
title="Sign Up" title="Sign Up"
color={colors.gold} color={colors.gold}
onPress={signin} onPress={signin}
/> />
<Link href="/login" style={styles.a}> <Link href="/login" style={styles.a}>
Already have an account? Log In! Already have an account? Log In!
</Link> </Link>
</View> </View>
</View> </View>
); );
} }
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
width: "100%", width: "100%",
height: "100%", height: "100%",
backgroundColor: colors.dark, backgroundColor: colors.dark,
}, },
form: { form: {
flex: 1, flex: 1,
alignItems: "center", alignItems: "center",
paddingTop: "10%", paddingTop: "10%",
width: "100%", width: "100%",
gap: 15, gap: 15,
}, },
h1: { h1: {
color: "#FFF", color: "#FFF",
fontSize: 30, fontSize: 30,
textAlign: "center", textAlign: "center",
paddingTop: "20%", paddingTop: "20%",
}, },
a: { a: {
color: "#FFF", color: "#FFF",
fontSize: 12, fontSize: 12,
fontStyle: "italic", fontStyle: "italic",
textDecorationLine: "underline", textDecorationLine: "underline",
}, },
logo: { logo: {
width: "80%", width: "80%",
resizeMode: "contain", resizeMode: "contain",
}, },
header: { header: {
width: "100%", width: "100%",
alignItems: "center", alignItems: "center",
paddingTop: "20%", paddingTop: "20%",
}, },
input: { input: {
height: "auto", height: "auto",
width: "60%", width: "60%",
borderColor: "gray", borderColor: "gray",
borderWidth: 1, borderWidth: 1,
borderRadius: 5, borderRadius: 5,
padding: 10, padding: 10,
color: "#fff", color: "#fff",
}, },
btnContainer: { btnContainer: {
flexDirection: "row", flexDirection: "row",
gap: 5, gap: 5,
}, },
}); });
export default SignupPage; export default SignupPage;

View File

@ -1,6 +1,6 @@
module.exports = function(api) { module.exports = function (api) {
api.cache(true); api.cache(true);
return { return {
presets: ['babel-preset-expo'], presets: ["babel-preset-expo"],
}; };
}; };

15
frontend/biome.json Normal file
View File

@ -0,0 +1,15 @@
{
"$schema": "https://biomejs.dev/schemas/1.7.3/schema.json",
"files": {
"ignore": [".expo/", ".vscode/", "node_modules/"]
},
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": false,
"rules": {
"recommended": true
}
}
}

View File

@ -2,40 +2,40 @@ import React from "react";
import { Text, StyleSheet, Pressable } from "react-native"; import { Text, StyleSheet, Pressable } from "react-native";
export default function Button(props) { export default function Button(props) {
const { onPress, title = "Save", color = "black" } = props; const { onPress, title = "Save", color = "black" } = props;
return ( return (
<Pressable <Pressable
style={({ pressed }) => [ style={({ pressed }) => [
{ {
backgroundColor: pressed backgroundColor: pressed
? "rgb(210, 230, 255 )" ? "rgb(210, 230, 255 )"
: color : color
? color ? color
: "black", : "black",
}, },
styles.button, styles.button,
]} ]}
onPress={onPress} onPress={onPress}
> >
<Text style={styles.text}>{title}</Text> <Text style={styles.text}>{title}</Text>
</Pressable> </Pressable>
); );
} }
const styles = StyleSheet.create({ const styles = StyleSheet.create({
button: { button: {
alignItems: "center", alignItems: "center",
justifyContent: "center", justifyContent: "center",
paddingVertical: 12, paddingVertical: 12,
paddingHorizontal: 32, paddingHorizontal: 32,
borderRadius: 4, borderRadius: 4,
elevation: 3, elevation: 3,
}, },
text: { text: {
fontSize: 16, fontSize: 16,
lineHeight: 21, lineHeight: 21,
fontWeight: "bold", fontWeight: "bold",
letterSpacing: 0.25, letterSpacing: 0.25,
color: "white", color: "white",
}, },
}); });

View File

@ -1,9 +1,9 @@
export const colors = { export const colors = {
gold: "#FFD700ff", gold: "#FFD700ff",
gold: "#ffa500", gold: "#ffa500",
brown: "#8B4513ff", brown: "#8B4513ff",
green: "#228B22ff", green: "#228B22ff",
charcoal: "#2C3E50ff", charcoal: "#2C3E50ff",
black: "#020405ff", black: "#020405ff",
dark: "#010611", dark: "#010611",
}; };

View File

@ -26,7 +26,8 @@
"react-native-web": "~0.19.6" "react-native-web": "~0.19.6"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.20.0" "@babel/core": "^7.20.0",
"@biomejs/biome": "1.7.3"
} }
}, },
"node_modules/@ampproject/remapping": { "node_modules/@ampproject/remapping": {
@ -2051,6 +2052,161 @@
"node": ">=6.9.0" "node": ">=6.9.0"
} }
}, },
"node_modules/@biomejs/biome": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.7.3.tgz",
"integrity": "sha512-ogFQI+fpXftr+tiahA6bIXwZ7CSikygASdqMtH07J2cUzrpjyTMVc9Y97v23c7/tL1xCZhM+W9k4hYIBm7Q6cQ==",
"dev": true,
"hasInstallScript": true,
"bin": {
"biome": "bin/biome"
},
"engines": {
"node": ">=14.21.3"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/biome"
},
"optionalDependencies": {
"@biomejs/cli-darwin-arm64": "1.7.3",
"@biomejs/cli-darwin-x64": "1.7.3",
"@biomejs/cli-linux-arm64": "1.7.3",
"@biomejs/cli-linux-arm64-musl": "1.7.3",
"@biomejs/cli-linux-x64": "1.7.3",
"@biomejs/cli-linux-x64-musl": "1.7.3",
"@biomejs/cli-win32-arm64": "1.7.3",
"@biomejs/cli-win32-x64": "1.7.3"
}
},
"node_modules/@biomejs/cli-darwin-arm64": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.7.3.tgz",
"integrity": "sha512-eDvLQWmGRqrPIRY7AIrkPHkQ3visEItJKkPYSHCscSDdGvKzYjmBJwG1Gu8+QC5ed6R7eiU63LEC0APFBobmfQ==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-darwin-x64": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.7.3.tgz",
"integrity": "sha512-JXCaIseKRER7dIURsVlAJacnm8SG5I0RpxZ4ya3dudASYUc68WGl4+FEN03ABY3KMIq7hcK1tzsJiWlmXyosZg==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-linux-arm64": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.7.3.tgz",
"integrity": "sha512-phNTBpo7joDFastnmZsFjYcDYobLTx4qR4oPvc9tJ486Bd1SfEVPHEvJdNJrMwUQK56T+TRClOQd/8X1nnjA9w==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-linux-arm64-musl": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.7.3.tgz",
"integrity": "sha512-c8AlO45PNFZ1BYcwaKzdt46kYbuP6xPGuGQ6h4j3XiEDpyseRRUy/h+6gxj07XovmyxKnSX9GSZ6nVbZvcVUAw==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-linux-x64": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.7.3.tgz",
"integrity": "sha512-vnedYcd5p4keT3iD48oSKjOIRPYcjSNNbd8MO1bKo9ajg3GwQXZLAH+0Cvlr+eMsO67/HddWmscSQwTFrC/uPA==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-linux-x64-musl": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.7.3.tgz",
"integrity": "sha512-UdEHKtYGWEX3eDmVWvQeT+z05T9/Sdt2+F/7zmMOFQ7boANeX8pcO6EkJPK3wxMudrApsNEKT26rzqK6sZRTRA==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-win32-arm64": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.7.3.tgz",
"integrity": "sha512-unNCDqUKjujYkkSxs7gFIfdasttbDC4+z0kYmcqzRk6yWVoQBL4dNLcCbdnJS+qvVDNdI9rHp2NwpQ0WAdla4Q==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-win32-x64": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.7.3.tgz",
"integrity": "sha512-ZmByhbrnmz/UUFYB622CECwhKIPjJLLPr5zr3edhu04LzbfcOrz16VYeNq5dpO1ADG70FORhAJkaIGdaVBG00w==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@expo/bunyan": { "node_modules/@expo/bunyan": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/@expo/bunyan/-/bunyan-4.0.0.tgz", "resolved": "https://registry.npmjs.org/@expo/bunyan/-/bunyan-4.0.0.tgz",

View File

@ -1,33 +1,34 @@
{ {
"name": "deguapp", "name": "deguapp",
"version": "1.0.0", "version": "1.0.0",
"main": "expo-router/entry", "main": "expo-router/entry",
"scripts": { "scripts": {
"start": "expo start", "start": "expo start",
"android": "expo start --android", "android": "expo start --android",
"ios": "expo start --ios", "ios": "expo start --ios",
"web": "expo start --web" "web": "expo start --web"
}, },
"dependencies": { "dependencies": {
"@expo/metro-runtime": "~3.1.3", "@expo/metro-runtime": "~3.1.3",
"@react-native-async-storage/async-storage": "^1.23.1", "@react-native-async-storage/async-storage": "^1.23.1",
"@types/react": "~18.2.45", "@types/react": "~18.2.45",
"axios": "^1.6.8", "axios": "^1.6.8",
"expo": "~50.0.17", "expo": "~50.0.17",
"expo-constants": "~15.4.6", "expo-constants": "~15.4.6",
"expo-linking": "~6.2.2", "expo-linking": "~6.2.2",
"expo-router": "~3.4.10", "expo-router": "~3.4.10",
"expo-secure-store": "^12.8.1", "expo-secure-store": "^12.8.1",
"expo-status-bar": "~1.11.1", "expo-status-bar": "~1.11.1",
"react": "18.2.0", "react": "18.2.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"react-native": "0.73.6", "react-native": "0.73.6",
"react-native-safe-area-context": "4.8.2", "react-native-safe-area-context": "4.8.2",
"react-native-screens": "~3.29.0", "react-native-screens": "~3.29.0",
"react-native-web": "~0.19.6" "react-native-web": "~0.19.6"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.20.0" "@babel/core": "^7.20.0",
}, "@biomejs/biome": "1.7.3"
"private": true },
"private": true
} }