create-rn-clean-architecture 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/LICENSE +21 -0
- package/README.md +369 -0
- package/bin/cli.js +8 -0
- package/package.json +42 -0
- package/src/checkDependencies.js +108 -0
- package/src/createDirectories.js +38 -0
- package/src/generateFiles.js +114 -0
- package/src/index.js +125 -0
- package/templates/PROJECT_ARCHITECTURE.md +385 -0
- package/templates/constants/COLORS.ts.template +36 -0
- package/templates/constants/SIZINGS.ts.template +51 -0
- package/templates/constants/splash.constants.ts.template +1 -0
- package/templates/hooks/useSplashNavigation.ts.template +16 -0
- package/templates/navigation/BottomTabNavigation.tsx.template +17 -0
- package/templates/navigation/StackNavigation.tsx.template +18 -0
- package/templates/root/App.tsx.template +13 -0
- package/templates/screens/HomeScreen.tsx.template +18 -0
- package/templates/screens/ProfileScreen.tsx.template +18 -0
- package/templates/screens/SettingsScreen.tsx.template +18 -0
- package/templates/screens/SplashScreen.tsx.template +21 -0
- package/templates/styles/home.styles.ts.template +26 -0
- package/templates/styles/profile.styles.ts.template +26 -0
- package/templates/styles/settings.styles.ts.template +26 -0
- package/templates/styles/splash.styles.ts.template +25 -0
- package/templates/types/Type.ts.template +15 -0
- package/templates/utils/Util.ts.template +6 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Khizar
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
# create-rn-clean-architecture
|
|
2
|
+
|
|
3
|
+
🏗️ **Instantly create a complete, production-ready React Native app with Clean Architecture**
|
|
4
|
+
|
|
5
|
+
Transform your empty React Native project into a fully functional app with navigation, sample screens, and clean architecture patterns - all in under a minute!
|
|
6
|
+
|
|
7
|
+
## ✨ Features
|
|
8
|
+
|
|
9
|
+
- 🚀 **Complete Working App**: Creates a fully functional app with 4 screens ready to run
|
|
10
|
+
- 📱 **Full Navigation Setup**: Stack navigation + Bottom tabs pre-configured
|
|
11
|
+
- 📁 **Clean Architecture**: Organized directory structure with proper separation of concerns
|
|
12
|
+
- 🎨 **Design System**: Pre-configured colors, sizings, and styling constants
|
|
13
|
+
- 📝 **Sample Screens**: Splash, Home, Profile, and Settings screens with clean patterns
|
|
14
|
+
- 🔧 **Automatic Dependencies**: Checks and installs required navigation packages
|
|
15
|
+
- 📖 **Comprehensive Guide**: Detailed PROJECT_ARCHITECTURE.md with best practices
|
|
16
|
+
- ✅ **Type-Safe**: Full TypeScript support with proper navigation types
|
|
17
|
+
- 🎯 **Zero Configuration**: Works immediately after scaffolding
|
|
18
|
+
|
|
19
|
+
## 🚀 Quick Start
|
|
20
|
+
|
|
21
|
+
### Prerequisites
|
|
22
|
+
|
|
23
|
+
- Node.js >= 14.0.0
|
|
24
|
+
- A React Native project created with `npx react-native init MyApp`
|
|
25
|
+
|
|
26
|
+
### Usage
|
|
27
|
+
|
|
28
|
+
Navigate to your React Native project directory and run:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx create-rn-clean-architecture
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Or install globally:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install -g create-rn-clean-architecture
|
|
38
|
+
create-rn-clean-architecture
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### What Happens Next?
|
|
42
|
+
|
|
43
|
+
1. ✅ Validates your React Native project
|
|
44
|
+
2. ✅ Creates complete directory structure
|
|
45
|
+
3. ✅ Generates 4 working screens with navigation
|
|
46
|
+
4. ✅ Sets up hooks, styles, and constants
|
|
47
|
+
5. ✅ Updates your App.tsx
|
|
48
|
+
6. ✅ Checks and installs navigation dependencies
|
|
49
|
+
7. ✅ Copies architecture documentation
|
|
50
|
+
8. 🎉 **Your app is ready to run!**
|
|
51
|
+
|
|
52
|
+
## 📦 What Gets Created
|
|
53
|
+
|
|
54
|
+
### Complete Directory Structure
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
src/
|
|
58
|
+
├── assets/
|
|
59
|
+
│ ├── images/
|
|
60
|
+
│ ├── fonts/
|
|
61
|
+
│ └── icons/
|
|
62
|
+
├── components/
|
|
63
|
+
│ └── common/
|
|
64
|
+
├── constants/
|
|
65
|
+
│ ├── sizings/
|
|
66
|
+
│ │ └── SIZINGS.ts ✓ Generated
|
|
67
|
+
│ ├── styles/
|
|
68
|
+
│ │ └── COLORS.ts ✓ Generated
|
|
69
|
+
│ └── splash/
|
|
70
|
+
│ └── splash.constants.ts ✓ Generated
|
|
71
|
+
├── hooks/
|
|
72
|
+
│ └── splash/
|
|
73
|
+
│ └── useSplashNavigation.ts ✓ Generated
|
|
74
|
+
├── navigation/
|
|
75
|
+
│ ├── stack/
|
|
76
|
+
│ │ └── StackNavigation.tsx ✓ Generated
|
|
77
|
+
│ └── bottom/
|
|
78
|
+
│ └── BottomTabNavigation.tsx ✓ Generated
|
|
79
|
+
├── screens/
|
|
80
|
+
│ ├── splash/
|
|
81
|
+
│ │ └── SplashScreen.tsx ✓ Generated
|
|
82
|
+
│ ├── home/
|
|
83
|
+
│ │ └── HomeScreen.tsx ✓ Generated
|
|
84
|
+
│ ├── profile/
|
|
85
|
+
│ │ └── ProfileScreen.tsx ✓ Generated
|
|
86
|
+
│ └── settings/
|
|
87
|
+
│ └── SettingsScreen.tsx ✓ Generated
|
|
88
|
+
├── state/
|
|
89
|
+
│ ├── zustand/
|
|
90
|
+
│ └── context/
|
|
91
|
+
├── styles/
|
|
92
|
+
│ ├── splash/
|
|
93
|
+
│ │ └── splash.styles.ts ✓ Generated
|
|
94
|
+
│ ├── home/
|
|
95
|
+
│ │ └── home.styles.ts ✓ Generated
|
|
96
|
+
│ ├── profile/
|
|
97
|
+
│ │ └── profile.styles.ts ✓ Generated
|
|
98
|
+
│ └── settings/
|
|
99
|
+
│ └── settings.styles.ts ✓ Generated
|
|
100
|
+
├── types/
|
|
101
|
+
│ └── Type.ts ✓ Generated
|
|
102
|
+
└── utils/
|
|
103
|
+
└── Util.ts ✓ Generated
|
|
104
|
+
|
|
105
|
+
Root Level:
|
|
106
|
+
├── App.tsx ✓ Updated
|
|
107
|
+
└── PROJECT_ARCHITECTURE.md ✓ Generated
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 🎯 4 Ready-to-Use Screens
|
|
111
|
+
|
|
112
|
+
#### 1. Splash Screen
|
|
113
|
+
- Auto-navigates to main app after 2 seconds
|
|
114
|
+
- Uses custom hook for navigation logic
|
|
115
|
+
- Demonstrates proper hook usage pattern
|
|
116
|
+
|
|
117
|
+
#### 2. Home Screen
|
|
118
|
+
- Part of bottom tab navigation
|
|
119
|
+
- Example of presentation-only component
|
|
120
|
+
- Uses centralized styles and constants
|
|
121
|
+
|
|
122
|
+
#### 3. Profile Screen
|
|
123
|
+
- Part of bottom tab navigation
|
|
124
|
+
- Ready for user profile implementation
|
|
125
|
+
- Follows clean architecture patterns
|
|
126
|
+
|
|
127
|
+
#### 4. Settings Screen
|
|
128
|
+
- Part of bottom tab navigation
|
|
129
|
+
- Prepared for app configuration
|
|
130
|
+
- Demonstrates consistent structure
|
|
131
|
+
|
|
132
|
+
### 📝 Generated Core Files
|
|
133
|
+
|
|
134
|
+
#### `src/utils/Util.ts`
|
|
135
|
+
```typescript
|
|
136
|
+
// Pre-configured navigator creators
|
|
137
|
+
export const Stack = createNativeStackNavigator<STACK_NAVIGATOR_PARAMS>();
|
|
138
|
+
export const Tab = createBottomTabNavigator<BOTTOM_TAB_NAVIGATOR_PARAMS>();
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
#### `src/types/Type.ts`
|
|
142
|
+
```typescript
|
|
143
|
+
// Complete navigation types
|
|
144
|
+
export type STACK_NAVIGATOR_PARAMS = {
|
|
145
|
+
Splash: undefined;
|
|
146
|
+
Home: undefined;
|
|
147
|
+
BottomTab: undefined;
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
export type BOTTOM_TAB_NAVIGATOR_PARAMS = {
|
|
151
|
+
Home: undefined;
|
|
152
|
+
Profile: undefined;
|
|
153
|
+
Settings: undefined;
|
|
154
|
+
};
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
#### `src/constants/sizings/SIZINGS.ts`
|
|
158
|
+
- Border sizings (1-13px)
|
|
159
|
+
- Font sizings (12-28px)
|
|
160
|
+
- Spacing scale (4-48px)
|
|
161
|
+
- Border radius values
|
|
162
|
+
|
|
163
|
+
#### `src/constants/styles/COLORS.ts`
|
|
164
|
+
- Primary and secondary colors
|
|
165
|
+
- Gray scale (9 shades)
|
|
166
|
+
- Status colors (success, warning, error, info)
|
|
167
|
+
- Semantic colors (background, surface, text, border)
|
|
168
|
+
|
|
169
|
+
### 🔗 Complete Navigation Setup
|
|
170
|
+
|
|
171
|
+
The package creates a fully configured navigation system:
|
|
172
|
+
|
|
173
|
+
**Stack Navigator** (Root):
|
|
174
|
+
- Splash Screen → Bottom Tab Navigator
|
|
175
|
+
|
|
176
|
+
**Bottom Tab Navigator**:
|
|
177
|
+
- Home Tab
|
|
178
|
+
- Profile Tab
|
|
179
|
+
- Settings Tab
|
|
180
|
+
|
|
181
|
+
**App.tsx** automatically wired up and ready to run!
|
|
182
|
+
|
|
183
|
+
## 🎯 Architecture Principles
|
|
184
|
+
|
|
185
|
+
All generated code follows clean architecture patterns:
|
|
186
|
+
|
|
187
|
+
1. **Screens = Presentation Only**
|
|
188
|
+
- No business logic in screen components
|
|
189
|
+
- Only UI rendering and event handling
|
|
190
|
+
|
|
191
|
+
2. **Hooks = Business Logic**
|
|
192
|
+
- All logic extracted to custom hooks
|
|
193
|
+
- Reusable and testable
|
|
194
|
+
|
|
195
|
+
3. **Styles = Separate Files**
|
|
196
|
+
- StyleSheets in dedicated files
|
|
197
|
+
- Uses centralized constants
|
|
198
|
+
|
|
199
|
+
4. **Constants = Centralized**
|
|
200
|
+
- Colors, sizes, and config in one place
|
|
201
|
+
- Easy to maintain and update
|
|
202
|
+
|
|
203
|
+
5. **No Barrel Exports**
|
|
204
|
+
- Direct imports only
|
|
205
|
+
- Better tree-shaking and clarity
|
|
206
|
+
|
|
207
|
+
## 📚 Example: Clean Architecture Pattern
|
|
208
|
+
|
|
209
|
+
### Screen Component (Presentation)
|
|
210
|
+
```typescript
|
|
211
|
+
// src/screens/home/HomeScreen.tsx
|
|
212
|
+
import React from 'react';
|
|
213
|
+
import { Text, View } from 'react-native';
|
|
214
|
+
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
215
|
+
import { styles } from '../../styles/home/home.styles';
|
|
216
|
+
|
|
217
|
+
const HomeScreen = () => {
|
|
218
|
+
return (
|
|
219
|
+
<SafeAreaView style={styles.container}>
|
|
220
|
+
<View style={styles.content}>
|
|
221
|
+
<Text style={styles.title}>Home Screen</Text>
|
|
222
|
+
</View>
|
|
223
|
+
</SafeAreaView>
|
|
224
|
+
);
|
|
225
|
+
};
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Styles (Separate File)
|
|
229
|
+
```typescript
|
|
230
|
+
// src/styles/home/home.styles.ts
|
|
231
|
+
import { StyleSheet } from 'react-native';
|
|
232
|
+
import { COLORS } from '../../constants/styles/COLORS';
|
|
233
|
+
import { SIZINGS } from '../../constants/sizings/SIZINGS';
|
|
234
|
+
|
|
235
|
+
export const styles = StyleSheet.create({
|
|
236
|
+
container: {
|
|
237
|
+
flex: 1,
|
|
238
|
+
backgroundColor: COLORS.colors.background,
|
|
239
|
+
},
|
|
240
|
+
title: {
|
|
241
|
+
fontSize: SIZINGS.fontSizings.large_4,
|
|
242
|
+
color: COLORS.colors.text,
|
|
243
|
+
},
|
|
244
|
+
});
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## 🔧 Automatic Dependency Management
|
|
248
|
+
|
|
249
|
+
The CLI automatically detects and offers to install required packages:
|
|
250
|
+
|
|
251
|
+
**Installed Automatically:**
|
|
252
|
+
- `@react-navigation/native`
|
|
253
|
+
- `@react-navigation/native-stack`
|
|
254
|
+
- `@react-navigation/bottom-tabs`
|
|
255
|
+
- `react-native-safe-area-context`
|
|
256
|
+
- `react-native-screens`
|
|
257
|
+
|
|
258
|
+
**iOS Note**: After installation, remember to run:
|
|
259
|
+
```bash
|
|
260
|
+
cd ios && pod install && cd ..
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## 🎨 Customization
|
|
264
|
+
|
|
265
|
+
### Changing Colors
|
|
266
|
+
Edit `src/constants/styles/COLORS.ts`:
|
|
267
|
+
```typescript
|
|
268
|
+
export const COLORS = {
|
|
269
|
+
colors: {
|
|
270
|
+
primary: '#YOUR_COLOR', // Change primary color
|
|
271
|
+
secondary: '#YOUR_COLOR', // Change secondary color
|
|
272
|
+
// ... customize all colors
|
|
273
|
+
},
|
|
274
|
+
};
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Adding New Screens
|
|
278
|
+
1. Create screen directory: `src/screens/newscreen/`
|
|
279
|
+
2. Create screen file: `NewScreen.tsx`
|
|
280
|
+
3. Create styles: `src/styles/newscreen/newscreen.styles.ts`
|
|
281
|
+
4. Add to navigation types in `src/types/Type.ts`
|
|
282
|
+
5. Add to navigator in `src/navigation/`
|
|
283
|
+
|
|
284
|
+
### Adding Business Logic
|
|
285
|
+
1. Create hook directory: `src/hooks/feature/`
|
|
286
|
+
2. Create hook file: `useFeatureLogic.ts`
|
|
287
|
+
3. Import and use in screen component
|
|
288
|
+
|
|
289
|
+
## 📖 Documentation
|
|
290
|
+
|
|
291
|
+
The package includes `PROJECT_ARCHITECTURE.md` with:
|
|
292
|
+
- Complete architecture guidelines
|
|
293
|
+
- Best practices and patterns
|
|
294
|
+
- Code examples for common scenarios
|
|
295
|
+
- Naming conventions
|
|
296
|
+
- Testing strategies
|
|
297
|
+
- State management patterns
|
|
298
|
+
|
|
299
|
+
## ✅ Success Criteria
|
|
300
|
+
|
|
301
|
+
After running the tool:
|
|
302
|
+
- ✅ App runs immediately with `npm start`
|
|
303
|
+
- ✅ Navigation works between all screens
|
|
304
|
+
- ✅ Splash screen auto-navigates after 2 seconds
|
|
305
|
+
- ✅ Bottom tabs switch between Home, Profile, Settings
|
|
306
|
+
- ✅ All TypeScript types are properly configured
|
|
307
|
+
- ✅ No errors or warnings in console
|
|
308
|
+
- ✅ Ready to customize and build upon
|
|
309
|
+
|
|
310
|
+
## 🎯 CLI Output Example
|
|
311
|
+
|
|
312
|
+
```
|
|
313
|
+
🏗️ React Native Clean Architecture Scaffold
|
|
314
|
+
|
|
315
|
+
? This will create a complete React Native app with navigation and sample screens. Continue? Yes
|
|
316
|
+
|
|
317
|
+
📁 Creating directories...
|
|
318
|
+
✓ Created src/assets/images
|
|
319
|
+
✓ Created src/constants/sizings
|
|
320
|
+
... (all directories)
|
|
321
|
+
|
|
322
|
+
📝 Generating files...
|
|
323
|
+
✓ Created src/constants/sizings/SIZINGS.ts
|
|
324
|
+
✓ Created src/constants/styles/COLORS.ts
|
|
325
|
+
✓ Created src/navigation/stack/StackNavigation.tsx
|
|
326
|
+
✓ Created src/screens/splash/SplashScreen.tsx
|
|
327
|
+
... (all files)
|
|
328
|
+
|
|
329
|
+
📦 Checking dependencies...
|
|
330
|
+
⚠ Missing required navigation dependencies
|
|
331
|
+
? Would you like to install them now? Yes
|
|
332
|
+
Installing dependencies...
|
|
333
|
+
✓ Dependencies installed successfully!
|
|
334
|
+
|
|
335
|
+
✅ Clean architecture structure created successfully!
|
|
336
|
+
🎉 Your app is ready to run!
|
|
337
|
+
|
|
338
|
+
📂 What was created:
|
|
339
|
+
✓ Complete directory structure
|
|
340
|
+
✓ 4 sample screens (Splash, Home, Profile, Settings)
|
|
341
|
+
✓ Navigation setup (Stack + Bottom Tabs)
|
|
342
|
+
✓ Hooks, styles, and constants
|
|
343
|
+
✓ Updated App.tsx ready to run
|
|
344
|
+
|
|
345
|
+
📋 Next steps:
|
|
346
|
+
1. Review PROJECT_ARCHITECTURE.md for complete guidelines
|
|
347
|
+
2. Run: npm start (or yarn start)
|
|
348
|
+
3. Your app now has complete navigation and sample screens!
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
## 🤝 Contributing
|
|
352
|
+
|
|
353
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
354
|
+
|
|
355
|
+
## 📝 License
|
|
356
|
+
|
|
357
|
+
MIT © Khizar
|
|
358
|
+
|
|
359
|
+
## 🐛 Issues
|
|
360
|
+
|
|
361
|
+
Found a bug or have a suggestion? Please [open an issue](https://github.com/yourusername/create-rn-clean-architecture/issues).
|
|
362
|
+
|
|
363
|
+
## 🌟 Show Your Support
|
|
364
|
+
|
|
365
|
+
Give a ⭐️ if this project helped you build better React Native apps!
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
**Made with ❤️ for the React Native community**
|
package/bin/cli.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-rn-clean-architecture",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Scaffold a clean architecture structure for React Native projects",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"create-rn-clean-architecture": "bin/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"react-native",
|
|
11
|
+
"clean-architecture",
|
|
12
|
+
"scaffold",
|
|
13
|
+
"cli",
|
|
14
|
+
"boilerplate",
|
|
15
|
+
"template",
|
|
16
|
+
"generator"
|
|
17
|
+
],
|
|
18
|
+
"author": "Khizar",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/yourusername/create-rn-clean-architecture.git"
|
|
23
|
+
},
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/yourusername/create-rn-clean-architecture/issues"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://github.com/yourusername/create-rn-clean-architecture#readme",
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=14.0.0"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"chalk": "^4.1.2",
|
|
33
|
+
"fs-extra": "^11.1.1",
|
|
34
|
+
"inquirer": "^8.2.5"
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"bin",
|
|
38
|
+
"src",
|
|
39
|
+
"templates",
|
|
40
|
+
"README.md"
|
|
41
|
+
]
|
|
42
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
const inquirer = require('inquirer');
|
|
5
|
+
const { execSync } = require('child_process');
|
|
6
|
+
|
|
7
|
+
const REQUIRED_DEPENDENCIES = [
|
|
8
|
+
'@react-navigation/native',
|
|
9
|
+
'@react-navigation/native-stack',
|
|
10
|
+
'@react-navigation/bottom-tabs',
|
|
11
|
+
'react-native-safe-area-context',
|
|
12
|
+
'react-native-screens',
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
async function checkAndInstallDependencies() {
|
|
16
|
+
console.log(chalk.cyan('\n📦 Checking dependencies...'));
|
|
17
|
+
|
|
18
|
+
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
|
19
|
+
const packageJson = await fs.readJson(packageJsonPath);
|
|
20
|
+
|
|
21
|
+
const dependencies = {
|
|
22
|
+
...packageJson.dependencies,
|
|
23
|
+
...packageJson.devDependencies,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const missingDeps = REQUIRED_DEPENDENCIES.filter((dep) => !dependencies[dep]);
|
|
27
|
+
|
|
28
|
+
if (missingDeps.length === 0) {
|
|
29
|
+
console.log(chalk.green(' ✓ All required dependencies are already installed!'));
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
console.log(chalk.yellow(' ⚠ Missing required navigation dependencies:'));
|
|
34
|
+
missingDeps.forEach((dep) => {
|
|
35
|
+
console.log(chalk.gray(` - ${dep}`));
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const { install } = await inquirer.prompt([
|
|
39
|
+
{
|
|
40
|
+
type: 'confirm',
|
|
41
|
+
name: 'install',
|
|
42
|
+
message: 'Would you like to install them now?',
|
|
43
|
+
default: true,
|
|
44
|
+
},
|
|
45
|
+
]);
|
|
46
|
+
|
|
47
|
+
if (!install) {
|
|
48
|
+
const isExpo = dependencies['expo'];
|
|
49
|
+
console.log(
|
|
50
|
+
chalk.yellow(
|
|
51
|
+
'\n ⚠ Skipping installation. You will need to install them manually later.'
|
|
52
|
+
)
|
|
53
|
+
);
|
|
54
|
+
console.log(chalk.gray('\n Run this command to install:'));
|
|
55
|
+
if (isExpo) {
|
|
56
|
+
console.log(chalk.cyan(` npx expo install ${REQUIRED_DEPENDENCIES.join(' ')}\n`));
|
|
57
|
+
} else {
|
|
58
|
+
console.log(chalk.cyan(` npm install ${REQUIRED_DEPENDENCIES.join(' ')}\n`));
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
console.log(chalk.cyan('\n Installing dependencies... (this may take a minute)'));
|
|
65
|
+
|
|
66
|
+
// Check if it's an Expo project
|
|
67
|
+
const isExpo = dependencies['expo'];
|
|
68
|
+
|
|
69
|
+
// Check if yarn.lock exists
|
|
70
|
+
const useYarn = await fs.pathExists(path.join(process.cwd(), 'yarn.lock'));
|
|
71
|
+
const packageManager = useYarn ? 'yarn' : 'npm';
|
|
72
|
+
const installCmd = useYarn
|
|
73
|
+
? `yarn add ${REQUIRED_DEPENDENCIES.join(' ')}`
|
|
74
|
+
: `npm install ${REQUIRED_DEPENDENCIES.join(' ')}`;
|
|
75
|
+
|
|
76
|
+
execSync(installCmd, { stdio: 'inherit', cwd: process.cwd() });
|
|
77
|
+
|
|
78
|
+
console.log(chalk.green('\n ✓ Dependencies installed successfully!'));
|
|
79
|
+
|
|
80
|
+
// Check if iOS folder exists and remind about pod install (skip for Expo)
|
|
81
|
+
if (!isExpo) {
|
|
82
|
+
const iosExists = await fs.pathExists(path.join(process.cwd(), 'ios'));
|
|
83
|
+
if (iosExists) {
|
|
84
|
+
console.log(
|
|
85
|
+
chalk.yellow('\n 📱 iOS detected - Remember to run:')
|
|
86
|
+
);
|
|
87
|
+
console.log(chalk.cyan(' cd ios && pod install && cd ..\n'));
|
|
88
|
+
}
|
|
89
|
+
} else {
|
|
90
|
+
console.log(chalk.green('\n ℹ️ Expo project - native dependencies handled automatically!\n'));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return true;
|
|
94
|
+
} catch (error) {
|
|
95
|
+
const isExpo = dependencies['expo'];
|
|
96
|
+
console.log(chalk.red('\n ❌ Failed to install dependencies'));
|
|
97
|
+
console.log(chalk.gray(` Error: ${error.message}`));
|
|
98
|
+
console.log(chalk.yellow('\n Please install them manually:'));
|
|
99
|
+
if (isExpo) {
|
|
100
|
+
console.log(chalk.cyan(` npx expo install ${REQUIRED_DEPENDENCIES.join(' ')}\n`));
|
|
101
|
+
} else {
|
|
102
|
+
console.log(chalk.cyan(` npm install ${REQUIRED_DEPENDENCIES.join(' ')}\n`));
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
module.exports = { checkAndInstallDependencies };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
|
|
5
|
+
const directories = [
|
|
6
|
+
'src/assets/images',
|
|
7
|
+
'src/assets/fonts',
|
|
8
|
+
'src/assets/icons',
|
|
9
|
+
'src/components/common',
|
|
10
|
+
'src/constants/sizings',
|
|
11
|
+
'src/constants/styles',
|
|
12
|
+
'src/constants/splash',
|
|
13
|
+
'src/hooks/splash',
|
|
14
|
+
'src/navigation/stack',
|
|
15
|
+
'src/navigation/bottom',
|
|
16
|
+
'src/screens/splash',
|
|
17
|
+
'src/screens/home',
|
|
18
|
+
'src/screens/profile',
|
|
19
|
+
'src/screens/settings',
|
|
20
|
+
'src/state/zustand',
|
|
21
|
+
'src/state/context',
|
|
22
|
+
'src/styles/splash',
|
|
23
|
+
'src/styles/home',
|
|
24
|
+
'src/styles/profile',
|
|
25
|
+
'src/styles/settings',
|
|
26
|
+
'src/types',
|
|
27
|
+
'src/utils',
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
async function createDirectories() {
|
|
31
|
+
for (const dir of directories) {
|
|
32
|
+
const dirPath = path.join(process.cwd(), dir);
|
|
33
|
+
await fs.ensureDir(dirPath);
|
|
34
|
+
console.log(chalk.gray(` ✓ Created ${dir}`));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = { createDirectories };
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
|
|
5
|
+
async function generateFiles() {
|
|
6
|
+
const templatesPath = path.join(__dirname, '../templates');
|
|
7
|
+
|
|
8
|
+
const files = [
|
|
9
|
+
// Constants
|
|
10
|
+
{
|
|
11
|
+
template: path.join(templatesPath, 'constants/SIZINGS.ts.template'),
|
|
12
|
+
destination: 'src/constants/sizings/SIZINGS.ts',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
template: path.join(templatesPath, 'constants/COLORS.ts.template'),
|
|
16
|
+
destination: 'src/constants/styles/COLORS.ts',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
template: path.join(templatesPath, 'constants/splash.constants.ts.template'),
|
|
20
|
+
destination: 'src/constants/splash/splash.constants.ts',
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
// Types
|
|
24
|
+
{
|
|
25
|
+
template: path.join(templatesPath, 'types/Type.ts.template'),
|
|
26
|
+
destination: 'src/types/Type.ts',
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
// Utils
|
|
30
|
+
{
|
|
31
|
+
template: path.join(templatesPath, 'utils/Util.ts.template'),
|
|
32
|
+
destination: 'src/utils/Util.ts',
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
// Navigation
|
|
36
|
+
{
|
|
37
|
+
template: path.join(templatesPath, 'navigation/StackNavigation.tsx.template'),
|
|
38
|
+
destination: 'src/navigation/stack/StackNavigation.tsx',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
template: path.join(templatesPath, 'navigation/BottomTabNavigation.tsx.template'),
|
|
42
|
+
destination: 'src/navigation/bottom/BottomTabNavigation.tsx',
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
// Screens
|
|
46
|
+
{
|
|
47
|
+
template: path.join(templatesPath, 'screens/SplashScreen.tsx.template'),
|
|
48
|
+
destination: 'src/screens/splash/SplashScreen.tsx',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
template: path.join(templatesPath, 'screens/HomeScreen.tsx.template'),
|
|
52
|
+
destination: 'src/screens/home/HomeScreen.tsx',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
template: path.join(templatesPath, 'screens/ProfileScreen.tsx.template'),
|
|
56
|
+
destination: 'src/screens/profile/ProfileScreen.tsx',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
template: path.join(templatesPath, 'screens/SettingsScreen.tsx.template'),
|
|
60
|
+
destination: 'src/screens/settings/SettingsScreen.tsx',
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
// Hooks
|
|
64
|
+
{
|
|
65
|
+
template: path.join(templatesPath, 'hooks/useSplashNavigation.ts.template'),
|
|
66
|
+
destination: 'src/hooks/splash/useSplashNavigation.ts',
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
// Styles
|
|
70
|
+
{
|
|
71
|
+
template: path.join(templatesPath, 'styles/splash.styles.ts.template'),
|
|
72
|
+
destination: 'src/styles/splash/splash.styles.ts',
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
template: path.join(templatesPath, 'styles/home.styles.ts.template'),
|
|
76
|
+
destination: 'src/styles/home/home.styles.ts',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
template: path.join(templatesPath, 'styles/profile.styles.ts.template'),
|
|
80
|
+
destination: 'src/styles/profile/profile.styles.ts',
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
template: path.join(templatesPath, 'styles/settings.styles.ts.template'),
|
|
84
|
+
destination: 'src/styles/settings/settings.styles.ts',
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
// Root level - App.tsx
|
|
88
|
+
{
|
|
89
|
+
template: path.join(templatesPath, 'root/App.tsx.template'),
|
|
90
|
+
destination: 'App.tsx',
|
|
91
|
+
},
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
// Generate all files
|
|
95
|
+
for (const file of files) {
|
|
96
|
+
const content = await fs.readFile(file.template, 'utf-8');
|
|
97
|
+
const destPath = path.join(process.cwd(), file.destination);
|
|
98
|
+
await fs.writeFile(destPath, content);
|
|
99
|
+
console.log(chalk.gray(` ✓ Created ${file.destination}`));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Copy PROJECT_ARCHITECTURE.md
|
|
103
|
+
const architectureMdSource = path.join(templatesPath, 'PROJECT_ARCHITECTURE.md');
|
|
104
|
+
const architectureMdDest = path.join(process.cwd(), 'PROJECT_ARCHITECTURE.md');
|
|
105
|
+
|
|
106
|
+
if (await fs.pathExists(architectureMdSource)) {
|
|
107
|
+
await fs.copy(architectureMdSource, architectureMdDest);
|
|
108
|
+
console.log(chalk.gray(' ✓ Created PROJECT_ARCHITECTURE.md'));
|
|
109
|
+
} else {
|
|
110
|
+
console.log(chalk.yellow(' ⚠ PROJECT_ARCHITECTURE.md template not found, skipping'));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
module.exports = { generateFiles };
|