@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.
Files changed (109) hide show
  1. package/.env.example +18 -0
  2. package/.eslintrc.js +55 -0
  3. package/.github/workflows/ci.yml +184 -0
  4. package/.github/workflows/eas-build.yml +55 -0
  5. package/.github/workflows/eas-update.yml +50 -0
  6. package/.gitignore +62 -0
  7. package/.prettierrc +11 -0
  8. package/.storybook/main.ts +28 -0
  9. package/.storybook/preview.tsx +30 -0
  10. package/CHANGELOG.md +106 -0
  11. package/CONTRIBUTING.md +377 -0
  12. package/README.md +399 -0
  13. package/__tests__/components/Button.test.tsx +74 -0
  14. package/__tests__/hooks/useAuth.test.tsx +499 -0
  15. package/__tests__/services/api.test.ts +535 -0
  16. package/__tests__/utils/cn.test.ts +39 -0
  17. package/app/(auth)/_layout.tsx +36 -0
  18. package/app/(auth)/home.tsx +117 -0
  19. package/app/(auth)/profile.tsx +152 -0
  20. package/app/(auth)/settings.tsx +147 -0
  21. package/app/(public)/_layout.tsx +21 -0
  22. package/app/(public)/forgot-password.tsx +127 -0
  23. package/app/(public)/login.tsx +120 -0
  24. package/app/(public)/onboarding.tsx +5 -0
  25. package/app/(public)/register.tsx +139 -0
  26. package/app/_layout.tsx +97 -0
  27. package/app/index.tsx +21 -0
  28. package/app.config.ts +72 -0
  29. package/assets/images/.gitkeep +7 -0
  30. package/assets/images/adaptive-icon.png +0 -0
  31. package/assets/images/favicon.png +0 -0
  32. package/assets/images/icon.png +0 -0
  33. package/assets/images/notification-icon.png +0 -0
  34. package/assets/images/splash.png +0 -0
  35. package/babel.config.js +10 -0
  36. package/components/ErrorBoundary.tsx +169 -0
  37. package/components/forms/FormInput.tsx +78 -0
  38. package/components/forms/index.ts +1 -0
  39. package/components/onboarding/OnboardingScreen.tsx +370 -0
  40. package/components/onboarding/index.ts +2 -0
  41. package/components/ui/AnimatedButton.tsx +156 -0
  42. package/components/ui/AnimatedCard.tsx +108 -0
  43. package/components/ui/Avatar.tsx +316 -0
  44. package/components/ui/Badge.tsx +416 -0
  45. package/components/ui/BottomSheet.tsx +307 -0
  46. package/components/ui/Button.stories.tsx +115 -0
  47. package/components/ui/Button.tsx +104 -0
  48. package/components/ui/Card.stories.tsx +84 -0
  49. package/components/ui/Card.tsx +32 -0
  50. package/components/ui/Checkbox.tsx +261 -0
  51. package/components/ui/Input.stories.tsx +106 -0
  52. package/components/ui/Input.tsx +117 -0
  53. package/components/ui/Modal.tsx +98 -0
  54. package/components/ui/OptimizedImage.tsx +369 -0
  55. package/components/ui/Select.tsx +240 -0
  56. package/components/ui/Skeleton.tsx +180 -0
  57. package/components/ui/index.ts +18 -0
  58. package/constants/config.ts +54 -0
  59. package/docs/adr/001-state-management.md +79 -0
  60. package/docs/adr/002-styling-approach.md +130 -0
  61. package/docs/adr/003-data-fetching.md +155 -0
  62. package/docs/adr/004-auth-adapter-pattern.md +144 -0
  63. package/docs/adr/README.md +78 -0
  64. package/eas.json +47 -0
  65. package/global.css +10 -0
  66. package/hooks/index.ts +25 -0
  67. package/hooks/useApi.ts +236 -0
  68. package/hooks/useAuth.tsx +290 -0
  69. package/hooks/useBiometrics.ts +295 -0
  70. package/hooks/useDeepLinking.ts +256 -0
  71. package/hooks/useNotifications.ts +138 -0
  72. package/hooks/useOffline.ts +69 -0
  73. package/hooks/usePerformance.ts +434 -0
  74. package/hooks/useTheme.tsx +85 -0
  75. package/hooks/useUpdates.ts +358 -0
  76. package/i18n/index.ts +77 -0
  77. package/i18n/locales/en.json +101 -0
  78. package/i18n/locales/fr.json +101 -0
  79. package/jest.config.js +32 -0
  80. package/maestro/README.md +113 -0
  81. package/maestro/config.yaml +35 -0
  82. package/maestro/flows/login.yaml +62 -0
  83. package/maestro/flows/navigation.yaml +68 -0
  84. package/maestro/flows/offline.yaml +60 -0
  85. package/maestro/flows/register.yaml +94 -0
  86. package/metro.config.js +6 -0
  87. package/nativewind-env.d.ts +1 -0
  88. package/package.json +170 -0
  89. package/scripts/init.ps1 +162 -0
  90. package/scripts/init.sh +174 -0
  91. package/services/analytics.ts +428 -0
  92. package/services/api.ts +340 -0
  93. package/services/authAdapter.ts +333 -0
  94. package/services/index.ts +22 -0
  95. package/services/queryClient.ts +97 -0
  96. package/services/sentry.ts +131 -0
  97. package/services/storage.ts +82 -0
  98. package/stores/appStore.ts +54 -0
  99. package/stores/index.ts +2 -0
  100. package/stores/notificationStore.ts +40 -0
  101. package/tailwind.config.js +47 -0
  102. package/tsconfig.json +26 -0
  103. package/types/index.ts +42 -0
  104. package/types/user.ts +63 -0
  105. package/utils/accessibility.ts +446 -0
  106. package/utils/cn.ts +14 -0
  107. package/utils/index.ts +43 -0
  108. package/utils/toast.ts +113 -0
  109. 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
@@ -0,0 +1,6 @@
1
+ const { getDefaultConfig } = require("expo/metro-config");
2
+ const { withNativeWind } = require("nativewind/metro");
3
+
4
+ const config = getDefaultConfig(__dirname);
5
+
6
+ module.exports = withNativeWind(config, { input: "./global.css" });
@@ -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
+ }