@croacroa/react-native-template 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +18 -0
- package/.eslintrc.js +55 -0
- package/.github/workflows/ci.yml +184 -0
- package/.github/workflows/eas-build.yml +55 -0
- package/.github/workflows/eas-update.yml +50 -0
- package/.gitignore +62 -0
- package/.prettierrc +11 -0
- package/.storybook/main.ts +28 -0
- package/.storybook/preview.tsx +30 -0
- package/CHANGELOG.md +106 -0
- package/CONTRIBUTING.md +377 -0
- package/README.md +399 -0
- package/__tests__/components/Button.test.tsx +74 -0
- package/__tests__/hooks/useAuth.test.tsx +499 -0
- package/__tests__/services/api.test.ts +535 -0
- package/__tests__/utils/cn.test.ts +39 -0
- package/app/(auth)/_layout.tsx +36 -0
- package/app/(auth)/home.tsx +117 -0
- package/app/(auth)/profile.tsx +152 -0
- package/app/(auth)/settings.tsx +147 -0
- package/app/(public)/_layout.tsx +21 -0
- package/app/(public)/forgot-password.tsx +127 -0
- package/app/(public)/login.tsx +120 -0
- package/app/(public)/onboarding.tsx +5 -0
- package/app/(public)/register.tsx +139 -0
- package/app/_layout.tsx +97 -0
- package/app/index.tsx +21 -0
- package/app.config.ts +72 -0
- package/assets/images/.gitkeep +7 -0
- package/assets/images/adaptive-icon.png +0 -0
- package/assets/images/favicon.png +0 -0
- package/assets/images/icon.png +0 -0
- package/assets/images/notification-icon.png +0 -0
- package/assets/images/splash.png +0 -0
- package/babel.config.js +10 -0
- package/components/ErrorBoundary.tsx +169 -0
- package/components/forms/FormInput.tsx +78 -0
- package/components/forms/index.ts +1 -0
- package/components/onboarding/OnboardingScreen.tsx +370 -0
- package/components/onboarding/index.ts +2 -0
- package/components/ui/AnimatedButton.tsx +156 -0
- package/components/ui/AnimatedCard.tsx +108 -0
- package/components/ui/Avatar.tsx +316 -0
- package/components/ui/Badge.tsx +416 -0
- package/components/ui/BottomSheet.tsx +307 -0
- package/components/ui/Button.stories.tsx +115 -0
- package/components/ui/Button.tsx +104 -0
- package/components/ui/Card.stories.tsx +84 -0
- package/components/ui/Card.tsx +32 -0
- package/components/ui/Checkbox.tsx +261 -0
- package/components/ui/Input.stories.tsx +106 -0
- package/components/ui/Input.tsx +117 -0
- package/components/ui/Modal.tsx +98 -0
- package/components/ui/OptimizedImage.tsx +369 -0
- package/components/ui/Select.tsx +240 -0
- package/components/ui/Skeleton.tsx +180 -0
- package/components/ui/index.ts +18 -0
- package/constants/config.ts +54 -0
- package/docs/adr/001-state-management.md +79 -0
- package/docs/adr/002-styling-approach.md +130 -0
- package/docs/adr/003-data-fetching.md +155 -0
- package/docs/adr/004-auth-adapter-pattern.md +144 -0
- package/docs/adr/README.md +78 -0
- package/eas.json +47 -0
- package/global.css +10 -0
- package/hooks/index.ts +25 -0
- package/hooks/useApi.ts +236 -0
- package/hooks/useAuth.tsx +290 -0
- package/hooks/useBiometrics.ts +295 -0
- package/hooks/useDeepLinking.ts +256 -0
- package/hooks/useNotifications.ts +138 -0
- package/hooks/useOffline.ts +69 -0
- package/hooks/usePerformance.ts +434 -0
- package/hooks/useTheme.tsx +85 -0
- package/hooks/useUpdates.ts +358 -0
- package/i18n/index.ts +77 -0
- package/i18n/locales/en.json +101 -0
- package/i18n/locales/fr.json +101 -0
- package/jest.config.js +32 -0
- package/maestro/README.md +113 -0
- package/maestro/config.yaml +35 -0
- package/maestro/flows/login.yaml +62 -0
- package/maestro/flows/navigation.yaml +68 -0
- package/maestro/flows/offline.yaml +60 -0
- package/maestro/flows/register.yaml +94 -0
- package/metro.config.js +6 -0
- package/nativewind-env.d.ts +1 -0
- package/package.json +170 -0
- package/scripts/init.ps1 +162 -0
- package/scripts/init.sh +174 -0
- package/services/analytics.ts +428 -0
- package/services/api.ts +340 -0
- package/services/authAdapter.ts +333 -0
- package/services/index.ts +22 -0
- package/services/queryClient.ts +97 -0
- package/services/sentry.ts +131 -0
- package/services/storage.ts +82 -0
- package/stores/appStore.ts +54 -0
- package/stores/index.ts +2 -0
- package/stores/notificationStore.ts +40 -0
- package/tailwind.config.js +47 -0
- package/tsconfig.json +26 -0
- package/types/index.ts +42 -0
- package/types/user.ts +63 -0
- package/utils/accessibility.ts +446 -0
- package/utils/cn.ts +14 -0
- package/utils/index.ts +43 -0
- package/utils/toast.ts +113 -0
- package/utils/validation.ts +67 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Maestro E2E Tests
|
|
2
|
+
|
|
3
|
+
This directory contains end-to-end tests using [Maestro](https://maestro.mobile.dev/).
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
### Install Maestro
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# macOS
|
|
11
|
+
brew install maestro
|
|
12
|
+
|
|
13
|
+
# Or using curl
|
|
14
|
+
curl -Ls "https://get.maestro.mobile.dev" | bash
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Prerequisites
|
|
18
|
+
|
|
19
|
+
- iOS Simulator or Android Emulator running
|
|
20
|
+
- App built and installed on the device/emulator
|
|
21
|
+
|
|
22
|
+
## Running Tests
|
|
23
|
+
|
|
24
|
+
### Run all tests
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
maestro test maestro/flows/
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Run a specific test
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
maestro test maestro/flows/login.yaml
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Run with a specific app ID
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
APP_ID=com.yourcompany.app maestro test maestro/flows/
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Run in CI mode
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
maestro test --format junit --output results.xml maestro/flows/
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Test Structure
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
maestro/
|
|
52
|
+
├── config.yaml # Global configuration
|
|
53
|
+
├── README.md # This file
|
|
54
|
+
└── flows/
|
|
55
|
+
├── login.yaml # Login flow tests
|
|
56
|
+
├── register.yaml # Registration flow tests
|
|
57
|
+
├── navigation.yaml # Navigation tests
|
|
58
|
+
└── offline.yaml # Offline mode tests
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Writing Tests
|
|
62
|
+
|
|
63
|
+
### Basic test structure
|
|
64
|
+
|
|
65
|
+
```yaml
|
|
66
|
+
appId: ${APP_ID}
|
|
67
|
+
name: My Test
|
|
68
|
+
tags:
|
|
69
|
+
- smoke
|
|
70
|
+
---
|
|
71
|
+
- launchApp
|
|
72
|
+
- tapOn: "Button Text"
|
|
73
|
+
- assertVisible: "Expected Text"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Common commands
|
|
77
|
+
|
|
78
|
+
- `launchApp` - Launch the app
|
|
79
|
+
- `tapOn` - Tap on an element
|
|
80
|
+
- `inputText` - Enter text
|
|
81
|
+
- `assertVisible` - Assert element is visible
|
|
82
|
+
- `scrollUntilVisible` - Scroll until element is found
|
|
83
|
+
- `waitForAnimationToEnd` - Wait for animations
|
|
84
|
+
- `back` - Press back button
|
|
85
|
+
|
|
86
|
+
### Tips
|
|
87
|
+
|
|
88
|
+
1. Use `waitForAnimationToEnd` after navigation
|
|
89
|
+
2. Use `clearState: true` in `launchApp` for clean tests
|
|
90
|
+
3. Use `optional: true` for elements that may not always appear
|
|
91
|
+
4. Use tags to organize and filter tests
|
|
92
|
+
|
|
93
|
+
## CI Integration
|
|
94
|
+
|
|
95
|
+
### GitHub Actions example
|
|
96
|
+
|
|
97
|
+
```yaml
|
|
98
|
+
- name: Run E2E Tests
|
|
99
|
+
run: |
|
|
100
|
+
maestro test --format junit --output results.xml maestro/flows/
|
|
101
|
+
|
|
102
|
+
- name: Upload Test Results
|
|
103
|
+
uses: actions/upload-artifact@v3
|
|
104
|
+
with:
|
|
105
|
+
name: e2e-results
|
|
106
|
+
path: results.xml
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Resources
|
|
110
|
+
|
|
111
|
+
- [Maestro Documentation](https://maestro.mobile.dev/)
|
|
112
|
+
- [CLI Reference](https://maestro.mobile.dev/reference/cli)
|
|
113
|
+
- [Command Reference](https://maestro.mobile.dev/reference/commands)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Maestro Configuration
|
|
2
|
+
# https://maestro.mobile.dev/reference/configuration
|
|
3
|
+
|
|
4
|
+
# Default app ID (can be overridden with env vars)
|
|
5
|
+
appId: com.croacroa.app
|
|
6
|
+
|
|
7
|
+
# Environment variables
|
|
8
|
+
env:
|
|
9
|
+
APP_ID: ${APP_ID:-com.croacroa.app}
|
|
10
|
+
API_URL: ${API_URL:-http://localhost:3000}
|
|
11
|
+
|
|
12
|
+
# Test execution settings
|
|
13
|
+
executionOrder:
|
|
14
|
+
continueOnFailure: false
|
|
15
|
+
retryFailedTests: 1
|
|
16
|
+
|
|
17
|
+
# Screenshots
|
|
18
|
+
screenshots:
|
|
19
|
+
enabled: true
|
|
20
|
+
directory: ./maestro/screenshots
|
|
21
|
+
|
|
22
|
+
# Video recording
|
|
23
|
+
video:
|
|
24
|
+
enabled: true
|
|
25
|
+
directory: ./maestro/videos
|
|
26
|
+
|
|
27
|
+
# Timeouts
|
|
28
|
+
timeouts:
|
|
29
|
+
launchApp: 30000
|
|
30
|
+
waitForAnimationToEnd: 5000
|
|
31
|
+
|
|
32
|
+
# Device settings
|
|
33
|
+
device:
|
|
34
|
+
locale: en_US
|
|
35
|
+
orientation: portrait
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
appId: ${APP_ID}
|
|
2
|
+
name: Login Flow
|
|
3
|
+
tags:
|
|
4
|
+
- auth
|
|
5
|
+
- smoke
|
|
6
|
+
---
|
|
7
|
+
# Login Flow Test
|
|
8
|
+
# Tests the complete login experience
|
|
9
|
+
|
|
10
|
+
- launchApp:
|
|
11
|
+
clearState: true
|
|
12
|
+
|
|
13
|
+
# Wait for app to load
|
|
14
|
+
- waitForAnimationToEnd
|
|
15
|
+
|
|
16
|
+
# Verify we're on the login screen
|
|
17
|
+
- assertVisible: "Sign In"
|
|
18
|
+
- assertVisible: "Sign in to continue"
|
|
19
|
+
|
|
20
|
+
# Test empty form submission
|
|
21
|
+
- tapOn: "Sign In"
|
|
22
|
+
- assertVisible: "required"
|
|
23
|
+
|
|
24
|
+
# Enter invalid email
|
|
25
|
+
- tapOn:
|
|
26
|
+
text: "Email"
|
|
27
|
+
- inputText: "invalid-email"
|
|
28
|
+
- tapOn: "Sign In"
|
|
29
|
+
- assertVisible: "valid email"
|
|
30
|
+
|
|
31
|
+
# Clear and enter valid credentials
|
|
32
|
+
- clearText
|
|
33
|
+
- inputText: "test@example.com"
|
|
34
|
+
|
|
35
|
+
# Enter password
|
|
36
|
+
- tapOn:
|
|
37
|
+
text: "Password"
|
|
38
|
+
- inputText: "password123"
|
|
39
|
+
|
|
40
|
+
# Toggle password visibility
|
|
41
|
+
- tapOn:
|
|
42
|
+
id: "password-toggle"
|
|
43
|
+
- assertVisible: "password123"
|
|
44
|
+
- tapOn:
|
|
45
|
+
id: "password-toggle"
|
|
46
|
+
|
|
47
|
+
# Submit the form
|
|
48
|
+
- tapOn:
|
|
49
|
+
text: "Sign In"
|
|
50
|
+
index: 1
|
|
51
|
+
|
|
52
|
+
# Wait for loading
|
|
53
|
+
- waitForAnimationToEnd:
|
|
54
|
+
timeout: 5000
|
|
55
|
+
|
|
56
|
+
# Verify successful login (should see home screen)
|
|
57
|
+
- assertVisible: "Welcome back"
|
|
58
|
+
|
|
59
|
+
# Verify we're on the authenticated section
|
|
60
|
+
- assertVisible:
|
|
61
|
+
text: "Home"
|
|
62
|
+
optional: true
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
appId: ${APP_ID}
|
|
2
|
+
name: Navigation Flow
|
|
3
|
+
tags:
|
|
4
|
+
- navigation
|
|
5
|
+
- smoke
|
|
6
|
+
---
|
|
7
|
+
# Navigation Flow Test
|
|
8
|
+
# Tests navigation between main screens
|
|
9
|
+
|
|
10
|
+
- launchApp:
|
|
11
|
+
clearState: true
|
|
12
|
+
|
|
13
|
+
# Login first
|
|
14
|
+
- tapOn:
|
|
15
|
+
text: "Email"
|
|
16
|
+
- inputText: "test@example.com"
|
|
17
|
+
- tapOn:
|
|
18
|
+
text: "Password"
|
|
19
|
+
- inputText: "password123"
|
|
20
|
+
- tapOn:
|
|
21
|
+
text: "Sign In"
|
|
22
|
+
index: 1
|
|
23
|
+
- waitForAnimationToEnd:
|
|
24
|
+
timeout: 5000
|
|
25
|
+
|
|
26
|
+
# Verify we're on home
|
|
27
|
+
- assertVisible: "Home"
|
|
28
|
+
|
|
29
|
+
# Navigate to Profile
|
|
30
|
+
- tapOn: "Profile"
|
|
31
|
+
- waitForAnimationToEnd
|
|
32
|
+
- assertVisible: "Profile"
|
|
33
|
+
- assertVisible: "test@example.com"
|
|
34
|
+
|
|
35
|
+
# Navigate to Settings
|
|
36
|
+
- tapOn: "Settings"
|
|
37
|
+
- waitForAnimationToEnd
|
|
38
|
+
- assertVisible: "Settings"
|
|
39
|
+
- assertVisible: "Appearance"
|
|
40
|
+
- assertVisible: "Theme"
|
|
41
|
+
|
|
42
|
+
# Test theme toggle
|
|
43
|
+
- tapOn: "Theme"
|
|
44
|
+
- waitForAnimationToEnd
|
|
45
|
+
- assertVisible: "Dark"
|
|
46
|
+
- tapOn: "Dark"
|
|
47
|
+
- waitForAnimationToEnd
|
|
48
|
+
|
|
49
|
+
# Go back
|
|
50
|
+
- back
|
|
51
|
+
- assertVisible: "Settings"
|
|
52
|
+
|
|
53
|
+
# Navigate back to Home
|
|
54
|
+
- tapOn: "Home"
|
|
55
|
+
- waitForAnimationToEnd
|
|
56
|
+
- assertVisible: "Home"
|
|
57
|
+
|
|
58
|
+
# Test sign out
|
|
59
|
+
- tapOn: "Profile"
|
|
60
|
+
- waitForAnimationToEnd
|
|
61
|
+
- scrollUntilVisible:
|
|
62
|
+
element: "Sign Out"
|
|
63
|
+
direction: DOWN
|
|
64
|
+
- tapOn: "Sign Out"
|
|
65
|
+
- waitForAnimationToEnd
|
|
66
|
+
|
|
67
|
+
# Verify we're back on login
|
|
68
|
+
- assertVisible: "Sign In"
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
appId: ${APP_ID}
|
|
2
|
+
name: Offline Mode Flow
|
|
3
|
+
tags:
|
|
4
|
+
- offline
|
|
5
|
+
- edge-case
|
|
6
|
+
---
|
|
7
|
+
# Offline Mode Test
|
|
8
|
+
# Tests app behavior when offline
|
|
9
|
+
|
|
10
|
+
- launchApp:
|
|
11
|
+
clearState: true
|
|
12
|
+
|
|
13
|
+
# Login while online
|
|
14
|
+
- tapOn:
|
|
15
|
+
text: "Email"
|
|
16
|
+
- inputText: "test@example.com"
|
|
17
|
+
- tapOn:
|
|
18
|
+
text: "Password"
|
|
19
|
+
- inputText: "password123"
|
|
20
|
+
- tapOn:
|
|
21
|
+
text: "Sign In"
|
|
22
|
+
index: 1
|
|
23
|
+
- waitForAnimationToEnd:
|
|
24
|
+
timeout: 5000
|
|
25
|
+
|
|
26
|
+
# Verify login successful
|
|
27
|
+
- assertVisible: "Home"
|
|
28
|
+
|
|
29
|
+
# Enable airplane mode (simulates offline)
|
|
30
|
+
- setAirplaneMode:
|
|
31
|
+
enabled: true
|
|
32
|
+
|
|
33
|
+
# Wait for offline detection
|
|
34
|
+
- waitForAnimationToEnd:
|
|
35
|
+
timeout: 3000
|
|
36
|
+
|
|
37
|
+
# Verify offline indicator appears
|
|
38
|
+
- assertVisible:
|
|
39
|
+
text: "offline"
|
|
40
|
+
optional: true
|
|
41
|
+
|
|
42
|
+
# Try to perform an action that requires network
|
|
43
|
+
- tapOn: "Profile"
|
|
44
|
+
- waitForAnimationToEnd
|
|
45
|
+
|
|
46
|
+
# The cached data should still be visible
|
|
47
|
+
- assertVisible: "Profile"
|
|
48
|
+
|
|
49
|
+
# Disable airplane mode
|
|
50
|
+
- setAirplaneMode:
|
|
51
|
+
enabled: false
|
|
52
|
+
|
|
53
|
+
# Wait for reconnection
|
|
54
|
+
- waitForAnimationToEnd:
|
|
55
|
+
timeout: 5000
|
|
56
|
+
|
|
57
|
+
# Verify back online
|
|
58
|
+
- assertVisible:
|
|
59
|
+
text: "online"
|
|
60
|
+
optional: true
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
appId: ${APP_ID}
|
|
2
|
+
name: Registration Flow
|
|
3
|
+
tags:
|
|
4
|
+
- auth
|
|
5
|
+
- smoke
|
|
6
|
+
---
|
|
7
|
+
# Registration Flow Test
|
|
8
|
+
# Tests the complete signup experience
|
|
9
|
+
|
|
10
|
+
- launchApp:
|
|
11
|
+
clearState: true
|
|
12
|
+
|
|
13
|
+
# Navigate to registration
|
|
14
|
+
- tapOn: "Sign Up"
|
|
15
|
+
- waitForAnimationToEnd
|
|
16
|
+
|
|
17
|
+
# Verify we're on register screen
|
|
18
|
+
- assertVisible: "Create Account"
|
|
19
|
+
- assertVisible: "Join us today"
|
|
20
|
+
|
|
21
|
+
# Test validation - empty form
|
|
22
|
+
- scrollUntilVisible:
|
|
23
|
+
element: "Sign Up"
|
|
24
|
+
direction: DOWN
|
|
25
|
+
- tapOn:
|
|
26
|
+
text: "Sign Up"
|
|
27
|
+
index: 1
|
|
28
|
+
- assertVisible: "required"
|
|
29
|
+
|
|
30
|
+
# Enter name
|
|
31
|
+
- tapOn:
|
|
32
|
+
text: "Name"
|
|
33
|
+
- inputText: "Test User"
|
|
34
|
+
|
|
35
|
+
# Enter email
|
|
36
|
+
- tapOn:
|
|
37
|
+
text: "Email"
|
|
38
|
+
- inputText: "newuser@example.com"
|
|
39
|
+
|
|
40
|
+
# Enter password (too short)
|
|
41
|
+
- tapOn:
|
|
42
|
+
text: "Password"
|
|
43
|
+
index: 0
|
|
44
|
+
- inputText: "short"
|
|
45
|
+
- tapOn:
|
|
46
|
+
text: "Confirm Password"
|
|
47
|
+
- inputText: "short"
|
|
48
|
+
|
|
49
|
+
# Try to submit - should show password length error
|
|
50
|
+
- tapOn:
|
|
51
|
+
text: "Sign Up"
|
|
52
|
+
index: 1
|
|
53
|
+
- assertVisible: "8 characters"
|
|
54
|
+
|
|
55
|
+
# Fix password
|
|
56
|
+
- tapOn:
|
|
57
|
+
text: "Password"
|
|
58
|
+
index: 0
|
|
59
|
+
- clearText
|
|
60
|
+
- inputText: "SecurePass123"
|
|
61
|
+
|
|
62
|
+
# Enter mismatched confirm password
|
|
63
|
+
- tapOn:
|
|
64
|
+
text: "Confirm Password"
|
|
65
|
+
- clearText
|
|
66
|
+
- inputText: "DifferentPass123"
|
|
67
|
+
|
|
68
|
+
- tapOn:
|
|
69
|
+
text: "Sign Up"
|
|
70
|
+
index: 1
|
|
71
|
+
- assertVisible: "match"
|
|
72
|
+
|
|
73
|
+
# Fix confirm password
|
|
74
|
+
- tapOn:
|
|
75
|
+
text: "Confirm Password"
|
|
76
|
+
- clearText
|
|
77
|
+
- inputText: "SecurePass123"
|
|
78
|
+
|
|
79
|
+
# Submit the form
|
|
80
|
+
- tapOn:
|
|
81
|
+
text: "Sign Up"
|
|
82
|
+
index: 1
|
|
83
|
+
|
|
84
|
+
# Wait for registration
|
|
85
|
+
- waitForAnimationToEnd:
|
|
86
|
+
timeout: 5000
|
|
87
|
+
|
|
88
|
+
# Verify successful registration
|
|
89
|
+
- assertVisible: "Account created"
|
|
90
|
+
|
|
91
|
+
# Verify we're logged in
|
|
92
|
+
- assertVisible:
|
|
93
|
+
text: "Home"
|
|
94
|
+
optional: true
|
package/metro.config.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="nativewind/types" />
|
package/package.json
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@croacroa/react-native-template",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Production-ready React Native template with Expo, authentication, i18n, offline support, and more",
|
|
5
|
+
"main": "expo-router/entry",
|
|
6
|
+
"author": "Croacroa <contact@croacroa.dev>",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"homepage": "https://github.com/croacroa-dev-team/template-react-native#readme",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/croacroa-dev-team/template-react-native.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/croacroa-dev-team/template-react-native/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"react-native",
|
|
18
|
+
"expo",
|
|
19
|
+
"template",
|
|
20
|
+
"typescript",
|
|
21
|
+
"nativewind",
|
|
22
|
+
"tailwind",
|
|
23
|
+
"zustand",
|
|
24
|
+
"react-query",
|
|
25
|
+
"authentication",
|
|
26
|
+
"i18n",
|
|
27
|
+
"offline",
|
|
28
|
+
"biometrics",
|
|
29
|
+
"push-notifications",
|
|
30
|
+
"sentry",
|
|
31
|
+
"production-ready"
|
|
32
|
+
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"start": "expo start",
|
|
35
|
+
"dev": "expo start --dev-client",
|
|
36
|
+
"android": "expo run:android",
|
|
37
|
+
"ios": "expo run:ios",
|
|
38
|
+
"web": "expo start --web",
|
|
39
|
+
"build:dev": "eas build --profile development",
|
|
40
|
+
"build:preview": "eas build --profile preview",
|
|
41
|
+
"build:prod": "eas build --profile production",
|
|
42
|
+
"submit:ios": "eas submit --platform ios",
|
|
43
|
+
"submit:android": "eas submit --platform android",
|
|
44
|
+
"test": "jest",
|
|
45
|
+
"test:watch": "jest --watch",
|
|
46
|
+
"test:coverage": "jest --coverage",
|
|
47
|
+
"storybook": "storybook dev -p 6006",
|
|
48
|
+
"storybook:build": "storybook build",
|
|
49
|
+
"lint": "eslint . --ext .ts,.tsx",
|
|
50
|
+
"lint:fix": "eslint . --ext .ts,.tsx --fix",
|
|
51
|
+
"format": "prettier --write \"**/*.{ts,tsx,json,md}\"",
|
|
52
|
+
"typecheck": "tsc --noEmit",
|
|
53
|
+
"prepare": "husky"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@expo/vector-icons": "^14.0.0",
|
|
57
|
+
"@gorhom/bottom-sheet": "^4.6.0",
|
|
58
|
+
"@hookform/resolvers": "^3.6.0",
|
|
59
|
+
"@react-native-async-storage/async-storage": "^1.23.1",
|
|
60
|
+
"@react-native-community/netinfo": "^11.3.2",
|
|
61
|
+
"@sentry/react-native": "^7.8.0",
|
|
62
|
+
"@tanstack/query-async-storage-persister": "^5.51.1",
|
|
63
|
+
"@tanstack/react-query": "^5.51.1",
|
|
64
|
+
"@tanstack/react-query-persist-client": "^5.51.1",
|
|
65
|
+
"bottleneck": "^2.19.5",
|
|
66
|
+
"burnt": "^0.12.2",
|
|
67
|
+
"clsx": "^2.1.1",
|
|
68
|
+
"expo": "~52.0.0",
|
|
69
|
+
"expo-constants": "~17.0.0",
|
|
70
|
+
"expo-dev-client": "~5.0.0",
|
|
71
|
+
"expo-device": "~7.0.0",
|
|
72
|
+
"expo-font": "~13.0.0",
|
|
73
|
+
"expo-image": "~2.0.0",
|
|
74
|
+
"expo-linking": "~7.0.0",
|
|
75
|
+
"expo-local-authentication": "~15.0.0",
|
|
76
|
+
"expo-localization": "~15.0.0",
|
|
77
|
+
"expo-notifications": "~0.29.0",
|
|
78
|
+
"expo-router": "~4.0.0",
|
|
79
|
+
"expo-secure-store": "~14.0.0",
|
|
80
|
+
"expo-splash-screen": "~0.29.0",
|
|
81
|
+
"expo-status-bar": "~2.0.0",
|
|
82
|
+
"expo-system-ui": "~4.0.0",
|
|
83
|
+
"expo-updates": "~0.26.0",
|
|
84
|
+
"i18next": "^23.0.0",
|
|
85
|
+
"nativewind": "^4.0.1",
|
|
86
|
+
"react": "18.3.1",
|
|
87
|
+
"react-hook-form": "^7.52.1",
|
|
88
|
+
"react-i18next": "^14.0.0",
|
|
89
|
+
"react-native": "0.76.0",
|
|
90
|
+
"react-native-gesture-handler": "~2.20.0",
|
|
91
|
+
"react-native-reanimated": "~3.16.0",
|
|
92
|
+
"react-native-safe-area-context": "^4.12.0",
|
|
93
|
+
"react-native-screens": "~4.0.0",
|
|
94
|
+
"react-native-worklets": "^0.7.1",
|
|
95
|
+
"tailwind-merge": "^2.3.0",
|
|
96
|
+
"tailwindcss": "^3.4.4",
|
|
97
|
+
"zod": "^3.23.8",
|
|
98
|
+
"zustand": "^4.5.4"
|
|
99
|
+
},
|
|
100
|
+
"devDependencies": {
|
|
101
|
+
"@babel/core": "^7.24.0",
|
|
102
|
+
"@storybook/addon-essentials": "^8.1.0",
|
|
103
|
+
"@storybook/addon-react-native-web": "^0.0.24",
|
|
104
|
+
"@storybook/react": "^8.1.0",
|
|
105
|
+
"@storybook/react-webpack5": "^8.1.0",
|
|
106
|
+
"@testing-library/jest-native": "^5.4.3",
|
|
107
|
+
"@testing-library/react-native": "^12.5.1",
|
|
108
|
+
"@types/jest": "^29.5.12",
|
|
109
|
+
"@types/react": "~18.3.0",
|
|
110
|
+
"@typescript-eslint/eslint-plugin": "^7.0.0",
|
|
111
|
+
"@typescript-eslint/parser": "^7.0.0",
|
|
112
|
+
"eslint": "^8.57.0",
|
|
113
|
+
"eslint-config-expo": "^8.0.0",
|
|
114
|
+
"eslint-config-prettier": "^9.1.0",
|
|
115
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
116
|
+
"husky": "^9.0.11",
|
|
117
|
+
"jest": "^29.7.0",
|
|
118
|
+
"jest-expo": "~52.0.0",
|
|
119
|
+
"lint-staged": "^15.2.7",
|
|
120
|
+
"prettier": "^3.3.2",
|
|
121
|
+
"storybook": "^8.1.0",
|
|
122
|
+
"typescript": "^5.3.0"
|
|
123
|
+
},
|
|
124
|
+
"lint-staged": {
|
|
125
|
+
"*.{ts,tsx}": [
|
|
126
|
+
"eslint --fix",
|
|
127
|
+
"prettier --write"
|
|
128
|
+
],
|
|
129
|
+
"*.{json,md}": [
|
|
130
|
+
"prettier --write"
|
|
131
|
+
]
|
|
132
|
+
},
|
|
133
|
+
"files": [
|
|
134
|
+
"app",
|
|
135
|
+
"assets",
|
|
136
|
+
"components",
|
|
137
|
+
"constants",
|
|
138
|
+
"hooks",
|
|
139
|
+
"i18n",
|
|
140
|
+
"services",
|
|
141
|
+
"stores",
|
|
142
|
+
"types",
|
|
143
|
+
"utils",
|
|
144
|
+
"scripts",
|
|
145
|
+
"maestro",
|
|
146
|
+
"docs",
|
|
147
|
+
".storybook",
|
|
148
|
+
".github",
|
|
149
|
+
"__tests__",
|
|
150
|
+
"app.config.ts",
|
|
151
|
+
"babel.config.js",
|
|
152
|
+
"eas.json",
|
|
153
|
+
"global.css",
|
|
154
|
+
"jest.config.js",
|
|
155
|
+
"metro.config.js",
|
|
156
|
+
"nativewind-env.d.ts",
|
|
157
|
+
"tailwind.config.js",
|
|
158
|
+
"tsconfig.json",
|
|
159
|
+
".env.example",
|
|
160
|
+
".eslintrc.js",
|
|
161
|
+
".prettierrc",
|
|
162
|
+
".gitignore",
|
|
163
|
+
"CHANGELOG.md",
|
|
164
|
+
"CONTRIBUTING.md",
|
|
165
|
+
"README.md"
|
|
166
|
+
],
|
|
167
|
+
"publishConfig": {
|
|
168
|
+
"access": "public"
|
|
169
|
+
}
|
|
170
|
+
}
|