From 7ae2711e4ba6c8b653c9a05672f95bb6a5eb0bdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zo=C3=AB?= Date: Sat, 8 Aug 2026 15:10:12 +0200 Subject: [PATCH] feat: add Sentry error tracking and Expo Updates --- .env.example | 8 + .gitignore | 7 +- App.tsx | 11 +- app.json | 10 +- eas.json | 8 + metro.config.js | 5 +- package-lock.json | 782 ++++++++++++++++++ package.json | 13 +- scripts/build-wearos.sh | 12 +- targets/watch/expo-target.config.js | 9 + targets/watch/index.swift | 8 + targets/wearos/app/build.gradle.kts | 15 + .../wearos/app/src/main/AndroidManifest.xml | 16 + targets/wearos/build.gradle.kts | 1 + 14 files changed, 898 insertions(+), 7 deletions(-) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..2523f64 --- /dev/null +++ b/.env.example @@ -0,0 +1,8 @@ +# Sentry +SENTRY_DSN=https://6197bcf085d63727d829aa89ede8e973@o4507430203293696.ingest.de.sentry.io/4511875297706064 +SENTRY_ORG=your-org-slug +SENTRY_PROJECT=swimbuddy +SENTRY_AUTH_TOKEN=your-auth-token + +# Firebase App Distribution (WearOS) +FIREBASE_WEAR_APP_ID=1:xxxxx:android:xxxxx diff --git a/.gitignore b/.gitignore index d914c32..158de0b 100644 --- a/.gitignore +++ b/.gitignore @@ -31,7 +31,12 @@ yarn-error.* *.pem # local env files -.env*.local +.env +.env.local +.env.*.local + +# Sentry +sentry.properties # typescript *.tsbuildinfo diff --git a/App.tsx b/App.tsx index f993db9..5d3941f 100644 --- a/App.tsx +++ b/App.tsx @@ -7,6 +7,13 @@ import { DatabaseProvider } from "./src/providers/DatabaseProvider"; import { SettingsProvider } from "./src/providers/WatchProvider"; import { useWatchWorkoutSync } from "./src/features/watch-connectivity/hooks/useWatchWorkoutSync"; import { useSystemLanguageListener } from "./src/i18n"; +import * as Sentry from "@sentry/react-native"; + +Sentry.init({ + dsn: "https://6197bcf085d63727d829aa89ede8e973@o4507430203293696.ingest.de.sentry.io/4511875297706064", + tracesSampleRate: 1.0, + environment: __DEV__ ? "development" : "production", +}); function WatchSync() { useWatchWorkoutSync(); @@ -18,7 +25,7 @@ function SystemLanguageListener() { return null; } -export default function App() { +function App() { return ( @@ -32,3 +39,5 @@ export default function App() { ); } + +export default Sentry.wrap(App); diff --git a/app.json b/app.json index c7faf64..7807872 100644 --- a/app.json +++ b/app.json @@ -6,6 +6,12 @@ "orientation": "portrait", "icon": "./assets/icon.png", "userInterfaceStyle": "light", + "runtimeVersion": "1.0.0", + "updates": { + "url": "https://u.expo.dev/7b88af8c-86a3-4c08-b186-09a90e2bdfcc", + "fallbackToCacheTimeout": 0, + "checkAutomatically": "ON_LOAD" + }, "ios": { "supportsTablet": true, "bundleIdentifier": "nl.guido-it.swimbuddy", @@ -37,7 +43,9 @@ ["expo-localization", { "supportedLocales": ["en", "nl", "de", "fr", "it", "es", "pl", "pt", "dk"] }], - "./modules/wear-connectivity" + "./modules/wear-connectivity", + "@sentry/react-native/expo", + "expo-updates" ], "extra": { "eas": { diff --git a/eas.json b/eas.json index 18bb302..f3603d0 100644 --- a/eas.json +++ b/eas.json @@ -18,5 +18,13 @@ }, "submit": { "production": {} + }, + "update": { + "preview": { + "channel": "preview" + }, + "production": { + "channel": "production" + } } } diff --git a/metro.config.js b/metro.config.js index fbfd512..5389f51 100644 --- a/metro.config.js +++ b/metro.config.js @@ -1,5 +1,6 @@ const { getDefaultConfig } = require("expo/metro-config"); const { withNativewind } = require("nativewind/metro"); +const { withSentry } = require("@sentry/react-native/metro"); /** @type {import('expo/metro-config').MetroConfig} */ const config = getDefaultConfig(__dirname); @@ -14,7 +15,7 @@ config.transformer.getTransformOptions = async () => ({ }, }); -module.exports = withNativewind(config, { +module.exports = withSentry(withNativewind(config, { // Ensure .sql files are not processed as CSS inlineRem: false, -}); +})); diff --git a/package-lock.json b/package-lock.json index af3cfbc..84d6029 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@react-navigation/bottom-tabs": "^7.18.14", "@react-navigation/native": "^7.3.14", "@react-navigation/native-stack": "^7.18.6", + "@sentry/react-native": "^8.22.0", "@tailwindcss/postcss": "^4.3.3", "drizzle-orm": "^0.45.2", "expo": "~57.0.10", @@ -21,6 +22,7 @@ "expo-sqlite": "~57.0.1", "expo-status-bar": "~57.0.1", "expo-system-ui": "~57.0.2", + "expo-updates": "^57.0.12", "i18next": "^26.3.6", "nativewind": "^5.0.0-preview.4", "react": "19.2.3", @@ -3507,6 +3509,553 @@ "nanoid": "^3.3.11" } }, + "node_modules/@sentry/browser": { + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-10.69.0.tgz", + "integrity": "sha512-8391tnm96YbR7b8SYfEA/NEIZuyb2r3SZrtAT0bhZtjlujcYWjo7gugQvk8sWLU9cAa/euD00eJoIoJvNfpd7Q==", + "license": "MIT", + "dependencies": { + "@sentry/browser-utils": "10.69.0", + "@sentry/conventions": "^0.16.0", + "@sentry/core": "10.69.0", + "@sentry/feedback": "10.69.0", + "@sentry/replay": "10.69.0", + "@sentry/replay-canvas": "10.69.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/browser-utils": { + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/browser-utils/-/browser-utils-10.69.0.tgz", + "integrity": "sha512-e/u1Abj0zRPwR/deGZAP3GOULrsx67/XXnM5Skniqs4uxTsdNtPek1Nef0tpxwaQJYxwh6pWdhswLPPbbPOgBQ==", + "license": "MIT", + "dependencies": { + "@sentry/conventions": "^0.16.0", + "@sentry/core": "10.69.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/bundler-plugins": { + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/bundler-plugins/-/bundler-plugins-10.69.0.tgz", + "integrity": "sha512-I1otnSJIH4IOugLp+kcBbT0Kcex+J8xnHuUyzMAwCYSpZ0FMVvA723uNmkMdW0PxRRw0oEhe0qDB+t+ZjHxUiA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.18.5", + "@sentry/cli": "^2.58.6", + "@sentry/core": "10.69.0", + "dotenv": "^17.4.2", + "find-up": "^5.0.0", + "glob": "^13.0.6", + "magic-string": "~0.30.8" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "rollup": ">=3.2.0", + "webpack": ">=5.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/@sentry/bundler-plugins/node_modules/@sentry/cli": { + "version": "2.58.6", + "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.58.6.tgz", + "integrity": "sha512-baBcNPLLfUi9WuL+Tpri9BFaAdvugZIKelC5X0tt0Zdy+K0K+PCVSrnNmwMWU/HyaF/SEv6b6UHnXIdqanBlcg==", + "hasInstallScript": true, + "license": "FSL-1.1-MIT", + "dependencies": { + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.7", + "progress": "^2.0.3", + "proxy-from-env": "^1.1.0", + "which": "^2.0.2" + }, + "bin": { + "sentry-cli": "bin/sentry-cli" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@sentry/cli-darwin": "2.58.6", + "@sentry/cli-linux-arm": "2.58.6", + "@sentry/cli-linux-arm64": "2.58.6", + "@sentry/cli-linux-i686": "2.58.6", + "@sentry/cli-linux-x64": "2.58.6", + "@sentry/cli-win32-arm64": "2.58.6", + "@sentry/cli-win32-i686": "2.58.6", + "@sentry/cli-win32-x64": "2.58.6" + } + }, + "node_modules/@sentry/bundler-plugins/node_modules/@sentry/cli-darwin": { + "version": "2.58.6", + "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.58.6.tgz", + "integrity": "sha512-udAVvcyfNa0R+95GvPz/+43/N3TC0TYKdkQ7D7jhPSzbcMc7l2fxRNN5yB3UpCA5fWFnW4toeaqwDBhb/Wh3LA==", + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/bundler-plugins/node_modules/@sentry/cli-linux-arm": { + "version": "2.58.6", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.58.6.tgz", + "integrity": "sha512-pD0LAt5PcUzAinBwvDqc66x9+2CabHEv486yP0gRjWO7SakbaxmfVq/EXd8VLq/Tzi39LAu422UYK1lpW3MILw==", + "cpu": [ + "arm" + ], + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "linux", + "freebsd", + "android" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/bundler-plugins/node_modules/@sentry/cli-linux-arm64": { + "version": "2.58.6", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.58.6.tgz", + "integrity": "sha512-q8mEcNNmeXMy5i+jWT30TVpH7LcP4HD21CD5XRSPAd/a912HF6EpK0ybf/1USO14WOhoXbAGi9txwaWabSe33g==", + "cpu": [ + "arm64" + ], + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "linux", + "freebsd", + "android" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/bundler-plugins/node_modules/@sentry/cli-linux-i686": { + "version": "2.58.6", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.58.6.tgz", + "integrity": "sha512-q8vNJi1eOV/4vxAFWBsEwLHoSYapaZHIf4j76KJGJXFKTkEbsjCOOsKbwUIBTQQhRgV4DFWh3ryfsPS/que4Kg==", + "cpu": [ + "x86", + "ia32" + ], + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "linux", + "freebsd", + "android" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/bundler-plugins/node_modules/@sentry/cli-linux-x64": { + "version": "2.58.6", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.58.6.tgz", + "integrity": "sha512-DZu956Mhi3ZRjTBe1WdbGV46ldVbA8d2rgp/fh51GsI25zjBHah4wZnPTSzpc+YqxU6pJpg579B/r3jrIK530Q==", + "cpu": [ + "x64" + ], + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "linux", + "freebsd", + "android" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/bundler-plugins/node_modules/@sentry/cli-win32-arm64": { + "version": "2.58.6", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-arm64/-/cli-win32-arm64-2.58.6.tgz", + "integrity": "sha512-nj0Ff/kmAB73EPDhR8B4O9r+NUHK5GkPCkGWC+kXVemqAJWL5jcJ5KdxG0l/S0z6RoEoltID8/43/B+TaMlT7A==", + "cpu": [ + "arm64" + ], + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/bundler-plugins/node_modules/@sentry/cli-win32-i686": { + "version": "2.58.6", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.58.6.tgz", + "integrity": "sha512-WNZiDzPbgsEMQWq4avsQ391v/xWKJDIWWWo9GYl+N/w5qcYKkoDW7wQG7T9FasI6ENn68phChTOAPXXxbfAdOg==", + "cpu": [ + "x86", + "ia32" + ], + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/bundler-plugins/node_modules/@sentry/cli-win32-x64": { + "version": "2.58.6", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.58.6.tgz", + "integrity": "sha512-R35WJ17oF4D2eqI1DR2sQQqr0fjRTt5xoP16WrTu91XM2lndRMFsnjh+/GttbxapLCBNlrjzia99MJ0PZHZpgA==", + "cpu": [ + "x64" + ], + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/bundler-plugins/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/@sentry/bundler-plugins/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@sentry/cli": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-3.6.2.tgz", + "integrity": "sha512-/OcDsuz005C1tuauNhTd8/XNBHCfHiy46Wru4hAKBaziywgSA52lMSEznh6mWmHjPe/FoaDLpYt3Zd9qk3G0RA==", + "hasInstallScript": true, + "license": "FSL-1.1-MIT", + "dependencies": { + "progress": "^2.0.3", + "proxy-from-env": "^1.1.0", + "undici": "^6.22.0", + "which": "^2.0.2" + }, + "bin": { + "sentry-cli": "bin/sentry-cli" + }, + "engines": { + "node": ">= 18" + }, + "optionalDependencies": { + "@sentry/cli-darwin": "3.6.2", + "@sentry/cli-linux-arm": "3.6.2", + "@sentry/cli-linux-arm64": "3.6.2", + "@sentry/cli-linux-i686": "3.6.2", + "@sentry/cli-linux-x64": "3.6.2", + "@sentry/cli-win32-arm64": "3.6.2", + "@sentry/cli-win32-i686": "3.6.2", + "@sentry/cli-win32-x64": "3.6.2" + } + }, + "node_modules/@sentry/cli-darwin": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-3.6.2.tgz", + "integrity": "sha512-/ZIMLblj6ncwguhOPw5YL9018iaD2RBhxhbHBxjaowy1vrmnzoCurGe4n5Vv7PaS21ldAHtHNqJwNqHJS4XHUw==", + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/cli-linux-arm": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-3.6.2.tgz", + "integrity": "sha512-b2M+1ujgf7jHig9r88T2l2HEkg0XR/1Tmo1LCiPg4dsPKtTMC2Rb/f0Mto83//zkVijAA2WDBhznOz9a9Ouo7Q==", + "cpu": [ + "arm" + ], + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "linux", + "freebsd", + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/cli-linux-arm64": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-3.6.2.tgz", + "integrity": "sha512-KMHW+CIT5H046I1hIYJ6vZmwlbBELZDOTt9Bgue3kqpW5CuvviMeMuuIKXM2oKHr/l4Q1Xnj07oTbVNb1opTsg==", + "cpu": [ + "arm64" + ], + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "linux", + "freebsd", + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/cli-linux-i686": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-3.6.2.tgz", + "integrity": "sha512-tsLTOfJBoUkHfcCjUKxb/w1/WGLU00WJUO5zJztgLHKlebrjGAEiKM+8EPexb2hiW4F/P6UXL+4xXPKANk5JXQ==", + "cpu": [ + "x86", + "ia32" + ], + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "linux", + "freebsd", + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/cli-linux-x64": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-3.6.2.tgz", + "integrity": "sha512-CHwfSJYkPe4w96EovIY/iWfxHnf5gvRYh0BGHCPcQ9knhrgWUJqbHqi3lNfEDZmzCxJ76RqPrnLMW6syoSqXow==", + "cpu": [ + "x64" + ], + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "linux", + "freebsd", + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/cli-win32-arm64": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-arm64/-/cli-win32-arm64-3.6.2.tgz", + "integrity": "sha512-lTqOPbLexkKnXmuIK8qszv+trpX8fQiZAJoeClVA1+hOerVyrLP9eU2tUqTm/8YW8G/M+mu3ZxAtDvS3OpHvZw==", + "cpu": [ + "arm64" + ], + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/cli-win32-i686": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-3.6.2.tgz", + "integrity": "sha512-niUPoxN8p7jWrkvC0ekgpcIYEJNb5YxmuXRjUnOJrArwQs+4OPzRM+3e6JIYRXe7RDoUP63j1voYakEncuxioQ==", + "cpu": [ + "x86", + "ia32" + ], + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/cli-win32-x64": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-3.6.2.tgz", + "integrity": "sha512-Xg6ieuJr/1Ewtdpm9Kudb029lJxnfs3Ae/fLZNAOnvWOie/V4V/X+tgZ+lETC3lU+7yz7Gb0f25gKnU6sPBKVg==", + "cpu": [ + "x64" + ], + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/conventions": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@sentry/conventions/-/conventions-0.16.0.tgz", + "integrity": "sha512-fO9PLmHdVURcSPUpWCItWAtgKiMwGdJHbovoSEyLplX5sxs2ugvI4CBPTrkkgqhObnZOD0CnWBKDzSVQYBKEyQ==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@sentry/core": { + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.69.0.tgz", + "integrity": "sha512-+uuqVEeiDzYuAKjZLqsROKXvRTbl/QeH0gfGRtpYib1cud4rAFWRIkFmcR7Jb7JGFYwmReyQotiTj/hcDszTZg==", + "license": "MIT", + "dependencies": { + "@sentry/conventions": "^0.16.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/expo-upload-sourcemaps": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@sentry/expo-upload-sourcemaps/-/expo-upload-sourcemaps-8.22.0.tgz", + "integrity": "sha512-lLN3noVtKWWq3NwenYhsFixJt60EeE9ITfrE582IUK8nVuBY/X7RFE/oyaL99YXLVXKS71I0Kxd+E6NDiySFRA==", + "license": "MIT", + "dependencies": { + "@sentry/cli": "3.6.2" + }, + "bin": { + "expo-upload-sourcemaps": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@expo/env": "*", + "dotenv": "*" + }, + "peerDependenciesMeta": { + "@expo/env": { + "optional": true + }, + "dotenv": { + "optional": true + } + } + }, + "node_modules/@sentry/feedback": { + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/feedback/-/feedback-10.69.0.tgz", + "integrity": "sha512-qrGz5Qaw93/IhMjlFN6uIaXeHwgHDaKGa6FkTAP6PonpkvSbGGqan6xfsENxzj9HUVoli1lZ6tMRDnt2qtSPhg==", + "license": "MIT", + "dependencies": { + "@sentry/core": "10.69.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/react": { + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/react/-/react-10.69.0.tgz", + "integrity": "sha512-f0Il/JMteHjdWPNZQB3rtp1Pcj2Leb3p0KSZuv3rh0EUril9CbWtQVy5zJhoAppi+MWWmgRWa+6BpHbQf+ABQA==", + "license": "MIT", + "dependencies": { + "@sentry/browser": "10.69.0", + "@sentry/conventions": "^0.16.0", + "@sentry/core": "10.69.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react": "^16.14.0 || 17.x || 18.x || 19.x" + } + }, + "node_modules/@sentry/react-native": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@sentry/react-native/-/react-native-8.22.0.tgz", + "integrity": "sha512-jAtcVqJkRdesioH/zdjNkDz+CU5YMQJiOkmn4PlvC9dfotp2Uc+zOMBiFEC5uipkaOSl2kk9so6bxPGFymlMow==", + "license": "MIT", + "dependencies": { + "@sentry/browser": "10.69.0", + "@sentry/bundler-plugins": "10.69.0", + "@sentry/cli": "3.6.2", + "@sentry/core": "10.69.0", + "@sentry/expo-upload-sourcemaps": "8.22.0", + "@sentry/react": "10.69.0" + }, + "bin": { + "sentry-eas-build-on-complete": "scripts/eas-build-hook.js", + "sentry-eas-build-on-error": "scripts/eas-build-hook.js", + "sentry-eas-build-on-success": "scripts/eas-build-hook.js", + "sentry-expo-upload-sourcemaps": "scripts/expo-upload-sourcemaps.js" + }, + "peerDependencies": { + "expo": ">=49.0.0", + "react": ">=17.0.0", + "react-native": ">=0.65.0" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + } + } + }, + "node_modules/@sentry/replay": { + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-10.69.0.tgz", + "integrity": "sha512-uRhmNhtFGPOlM0iniVmWKAX3KVXI0le41yYK/iKdPjinT9jA3ZrmykO/Fv1v/KI5znOtwa9D6eHRnDTTMRxFrg==", + "license": "MIT", + "dependencies": { + "@sentry/browser-utils": "10.69.0", + "@sentry/core": "10.69.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/replay-canvas": { + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/replay-canvas/-/replay-canvas-10.69.0.tgz", + "integrity": "sha512-VF6nXvSninHcc7dC1Zme0RjkC7VgRMCixs6jKaQX5zTNeqTW3dZGSefSOVv+ZteRi3hJvVORq985VjUC9Z/0+A==", + "license": "MIT", + "dependencies": { + "@sentry/core": "10.69.0", + "@sentry/replay": "10.69.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@sinclair/typebox": { "version": "0.27.12", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", @@ -4770,6 +5319,18 @@ "integrity": "sha512-Ndrrf6BMPalkQPd/zubL+4YghH2J9NspapQ09uDXwYbvOPkP0oaqf5CkcwJ0b50kS2O3ul6yVu+jz+RY62Cejg==", "license": "MIT" }, + "node_modules/dotenv": { + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", + "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/drizzle-kit": { "version": "0.31.10", "resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.31.10.tgz", @@ -5175,6 +5736,12 @@ } } }, + "node_modules/expo-eas-client": { + "version": "57.0.1", + "resolved": "https://registry.npmjs.org/expo-eas-client/-/expo-eas-client-57.0.1.tgz", + "integrity": "sha512-4w51+zsl/ziUHQMJgLgUdgsNhRPAwHBfySpPB1hpWU21X74QS9T4SqDftaRnrDagn/DfcrXUMJvHbDQUxLPJNA==", + "license": "MIT" + }, "node_modules/expo-font": { "version": "57.0.1", "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-57.0.1.tgz", @@ -5189,6 +5756,12 @@ "react-native": "*" } }, + "node_modules/expo-json-utils": { + "version": "57.0.1", + "resolved": "https://registry.npmjs.org/expo-json-utils/-/expo-json-utils-57.0.1.tgz", + "integrity": "sha512-cgTe1NqzQdYs/WN+3nIY5IZg8s0pb0xaTUbhYvxQDn137GbwRfHoGM2se3m3Vsl4Qu+B9G4RPEK5WJDEU2Do7g==", + "license": "MIT" + }, "node_modules/expo-localization": { "version": "57.0.1", "resolved": "https://registry.npmjs.org/expo-localization/-/expo-localization-57.0.1.tgz", @@ -5202,6 +5775,18 @@ "react": "*" } }, + "node_modules/expo-manifests": { + "version": "57.0.1", + "resolved": "https://registry.npmjs.org/expo-manifests/-/expo-manifests-57.0.1.tgz", + "integrity": "sha512-qB/mDG2dYdl+EvUeQuqP8KFYCFgFCQjJYdWIHo8SFBgDzMYmdF286DFY2M1M9Okr99wkb5M4tgA3aCcwv3aEQA==", + "license": "MIT", + "dependencies": { + "expo-json-utils": "~57.0.1" + }, + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-modules-autolinking": { "version": "57.0.9", "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-57.0.9.tgz", @@ -5281,6 +5866,12 @@ "react-native": "*" } }, + "node_modules/expo-structured-headers": { + "version": "57.0.0", + "resolved": "https://registry.npmjs.org/expo-structured-headers/-/expo-structured-headers-57.0.0.tgz", + "integrity": "sha512-//t9UNPbJSEysc2x4VKJG/u7Osvv5DYJWsET5bqt/B+qcD1by/JXvSQzX3Q/YAgA96xFPontrz6OAPLbO4JKEA==", + "license": "MIT" + }, "node_modules/expo-system-ui": { "version": "57.0.2", "resolved": "https://registry.npmjs.org/expo-system-ui/-/expo-system-ui-57.0.2.tgz", @@ -5301,6 +5892,58 @@ } } }, + "node_modules/expo-updates": { + "version": "57.0.12", + "resolved": "https://registry.npmjs.org/expo-updates/-/expo-updates-57.0.12.tgz", + "integrity": "sha512-ZFsW8Mi9qFrrYPSXF++1FXejjflRdgbVPzaSJJATuHelVmIIb3D98gCO9sIsaLPHO1RCQVj1ltkj51VnwVL+4g==", + "license": "MIT", + "dependencies": { + "@expo/code-signing-certificates": "^0.0.6", + "@expo/plist": "^0.8.1", + "@expo/spawn-async": "^1.8.0", + "arg": "^4.1.0", + "chalk": "^4.1.2", + "debug": "^4.3.4", + "expo-eas-client": "~57.0.1", + "expo-manifests": "~57.0.1", + "expo-structured-headers": "~57.0.0", + "expo-updates-interface": "~57.0.1", + "getenv": "^2.0.0", + "glob": "^13.0.0", + "ignore": "^5.3.1", + "nullthrows": "^1.1.1", + "resolve-from": "^5.0.0" + }, + "bin": { + "expo-updates": "bin/cli.js" + }, + "peerDependencies": { + "expo": "*", + "expo-dev-client": "*", + "react": "*", + "react-native": "*" + }, + "peerDependenciesMeta": { + "expo-dev-client": { + "optional": true + } + } + }, + "node_modules/expo-updates-interface": { + "version": "57.0.1", + "resolved": "https://registry.npmjs.org/expo-updates-interface/-/expo-updates-interface-57.0.1.tgz", + "integrity": "sha512-+LUWwJ0gf/TEKMVdQAw/Gjih4dvrk+URgy24X9qEGKuuMDZqjBRm9T4yQyBVALGL5TTdPUaB6ILxx3lshm3pwQ==", + "license": "MIT", + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-updates/node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "license": "MIT" + }, "node_modules/expo/node_modules/@expo/cli": { "version": "57.0.12", "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-57.0.12.tgz", @@ -5753,6 +6396,22 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/find-yarn-workspace-root": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", @@ -6785,6 +7444,21 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -7378,6 +8052,26 @@ "node": ">= 0.6" } }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/node-forge": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", @@ -7603,6 +8297,36 @@ "node": ">=4" } }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -7676,6 +8400,15 @@ "node": ">=8" } }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/path-extra": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/path-extra/-/path-extra-1.0.3.tgz", @@ -7867,6 +8600,12 @@ "node": ">= 6" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, "node_modules/query-string": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", @@ -8965,6 +9704,12 @@ "integrity": "sha512-FWAPzCIHZHnrE/5/w9MPk0kK25hSQSH2IKhYh9PyjS3SG/+IEMvlwIHbhz+oF7xl54I+ueZlVnMjyzdSwLmAwA==", "license": "MIT" }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, "node_modules/tsx": { "version": "4.23.5", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.5.tgz", @@ -9491,6 +10236,15 @@ "node": ">=14.17" } }, + "node_modules/undici": { + "version": "6.28.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.28.0.tgz", + "integrity": "sha512-LIY910g9TI13YS95lrMFrs8Rm/u/irgHeTWoKCoteeJ04CUJ92eEfj0rVn+7VKMPBpUPiUoBKfhNyLI23EE/KA==", + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, "node_modules/undici-types": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", @@ -9671,12 +10425,28 @@ "defaults": "^1.0.3" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, "node_modules/whatwg-fetch": { "version": "3.6.20", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", "license": "MIT" }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/whatwg-url-minimum": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/whatwg-url-minimum/-/whatwg-url-minimum-0.1.2.tgz", @@ -9865,6 +10635,18 @@ "node": ">=12" } }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zod": { "version": "3.25.76", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", diff --git a/package.json b/package.json index fadf8b8..1bbb754 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "@react-navigation/bottom-tabs": "^7.18.14", "@react-navigation/native": "^7.3.14", "@react-navigation/native-stack": "^7.18.6", + "@sentry/react-native": "^8.22.0", "@tailwindcss/postcss": "^4.3.3", "drizzle-orm": "^0.45.2", "expo": "~57.0.10", @@ -15,6 +16,7 @@ "expo-sqlite": "~57.0.1", "expo-status-bar": "~57.0.1", "expo-system-ui": "~57.0.2", + "expo-updates": "^57.0.12", "i18next": "^26.3.6", "nativewind": "^5.0.0-preview.4", "react": "19.2.3", @@ -41,7 +43,16 @@ "android": "expo run:android", "ios": "expo run:ios", "web": "expo start --web", - "db:generate": "drizzle-kit generate" + "db:generate": "drizzle-kit generate", + "prebuild": "expo prebuild", + "prebuild:clean": "expo prebuild --clean", + "build:wearos:debug": "./scripts/build-wearos.sh debug", + "build:wearos:release": "./scripts/build-wearos.sh release", + "deploy:ios": "eas build --platform ios --profile ${1:-preview} && eas submit --platform ios --profile ${1:-preview}", + "deploy:android": "eas build --platform android --profile ${1:-preview} && eas submit --platform android --profile ${1:-preview}", + "deploy:wearos": "./scripts/build-wearos.sh release ${2:-}", + "update": "eas update --branch ${1:-preview}", + "update:production": "eas update --branch production" }, "private": true, "overrides": { diff --git a/scripts/build-wearos.sh b/scripts/build-wearos.sh index 7769a77..e8ac9d3 100755 --- a/scripts/build-wearos.sh +++ b/scripts/build-wearos.sh @@ -1,8 +1,18 @@ #!/bin/bash set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" + +# Load .env file +if [ -f "$PROJECT_ROOT/.env" ]; then + set -a + source "$PROJECT_ROOT/.env" + set +a +fi + PROFILE="${1:-debug}" -WEAR_DIR="targets/wearos" +WEAR_DIR="$PROJECT_ROOT/targets/wearos" FIREBASE_APP_ID="${FIREBASE_WEAR_APP_ID:-}" cd "$WEAR_DIR" diff --git a/targets/watch/expo-target.config.js b/targets/watch/expo-target.config.js index bed00f8..070af9b 100644 --- a/targets/watch/expo-target.config.js +++ b/targets/watch/expo-target.config.js @@ -4,6 +4,15 @@ module.exports = (config) => ({ type: "watch", icon: "../../assets/icon.png", deploymentTarget: "10.0", + frameworks: ["SwiftUI"], + swiftPackages: [ + { + name: "SentrySPM", + repositoryURL: "https://github.com/getsentry/sentry-cocoa.git", + kind: "upToNextMajorVersion", + minimumVersion: "9.25.0", + }, + ], entitlements: { "com.apple.security.application-groups": config.ios?.entitlements?.[ diff --git a/targets/watch/index.swift b/targets/watch/index.swift index 7c425ab..aa5fbd9 100644 --- a/targets/watch/index.swift +++ b/targets/watch/index.swift @@ -1,11 +1,19 @@ import SwiftUI import WatchConnectivity +import Sentry @main struct SwimTrackerWatchApp: App { @StateObject private var workoutManager = WorkoutManager() init() { + SentrySDK.start { options in + options.dsn = "https://6197bcf085d63727d829aa89ede8e973@o4507430203293696.ingest.de.sentry.io/4511875297706064" + options.debug = false + options.tracesSampleRate = 1.0 + options.enableLogs = true + } + if WCSession.isSupported() { let session = WCSession.default session.delegate = PhoneConnector.shared diff --git a/targets/wearos/app/build.gradle.kts b/targets/wearos/app/build.gradle.kts index f6cfd61..9e819ff 100644 --- a/targets/wearos/app/build.gradle.kts +++ b/targets/wearos/app/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.application") id("org.jetbrains.kotlin.android") id("org.jetbrains.kotlin.plugin.compose") + id("io.sentry.android.gradle") version "6.17.0" } android { @@ -14,6 +15,9 @@ android { targetSdk = 35 versionCode = 1 versionName = "1.0.0" + + val sentryDsn = System.getenv("SENTRY_DSN") ?: "" + manifestPlaceholders["sentryDsn"] = sentryDsn } buildTypes { @@ -68,4 +72,15 @@ dependencies { // Gson for JSON implementation("com.google.code.gson:gson:2.11.0") + + // Sentry + implementation("io.sentry:sentry-android:8.52.0") +} + +sentry { + uploadNativeSymbols = true + includeNativeSources = true + autoInstallation { + enabled = false + } } diff --git a/targets/wearos/app/src/main/AndroidManifest.xml b/targets/wearos/app/src/main/AndroidManifest.xml index b970622..ab9d56f 100644 --- a/targets/wearos/app/src/main/AndroidManifest.xml +++ b/targets/wearos/app/src/main/AndroidManifest.xml @@ -18,6 +18,22 @@ android:supportsRtl="true" android:theme="@android:style/Theme.Material.Light.NoActionBar"> + + + + + + + +