rnsup 1.0.2 → 1.0.3
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/README.md +139 -229
- package/dist/commands/generateComponent.js +38 -24
- package/dist/commands/generateFolder.js +2 -1
- package/dist/commands/generateScreen.js +35 -10
- package/dist/commands/setup.js +1 -1
- package/dist/commands/viewStructure.js +91 -0
- package/dist/index.js +9 -0
- package/dist/templates/componentTemplates.js +99 -0
- package/dist/templates/screenTemplates.js +342 -0
- package/dist/utils/selectPrompt.js +13 -24
- package/dist/utils/treeGenerator.js +170 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,336 +1,246 @@
|
|
|
1
|
-
<img width="1536" height="1024" alt="
|
|
2
|
-
|
|
1
|
+
<img width="1536" height="1024" alt="RNSUP React Native Setup" src="https://github.com/user-attachments/assets/3a35bc32-3413-40e5-8355-5db4806923a4" />
|
|
3
2
|
|
|
4
3
|
# RNSUP — React Native Support CLI
|
|
5
4
|
|
|
6
|
-

|
|
7
|
-
|
|
8
|
-
**RNSUP** is a developer productivity CLI that converts a fresh React Native CLI project into a production-ready architecture.
|
|
9
|
-
|
|
10
|
-
Instead of spending 3–6 hours configuring navigation, alias paths, reanimated, gesture handler, axios setup and folder structure, you can do everything with **one command**.
|
|
11
|
-
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
## Why RNSUP?
|
|
15
|
-
|
|
16
|
-
Starting a React Native CLI project usually requires:
|
|
17
|
-
|
|
18
|
-
* Installing React Navigation dependencies
|
|
19
|
-
* Configuring Reanimated
|
|
20
|
-
* Adding Gesture Handler import
|
|
21
|
-
* Setting up TypeScript aliases
|
|
22
|
-
* Creating folder structure
|
|
23
|
-
* Writing axios interceptors
|
|
24
|
-
* Adding responsive utilities
|
|
25
|
-
* Supporting image imports in TypeScript
|
|
26
|
-
|
|
27
|
-
Most developers repeat this setup for every project.
|
|
28
|
-
|
|
29
|
-
**RNSUP automates all of it.**
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## What RNSUP Does
|
|
34
|
-
|
|
35
|
-
After running setup, your project automatically gets:
|
|
36
|
-
|
|
37
|
-
### Configuration
|
|
38
|
-
|
|
39
|
-
* React Navigation dependencies installed
|
|
40
|
-
* Reanimated + Worklets configured
|
|
41
|
-
* Gesture Handler patched
|
|
42
|
-
* Babel alias configuration
|
|
43
|
-
* TypeScript path aliases
|
|
44
|
-
* Lockfile conflict handled (npm/yarn)
|
|
45
|
-
|
|
46
|
-
### Architecture
|
|
47
|
-
|
|
48
|
-
```
|
|
49
|
-
src/
|
|
50
|
-
components/
|
|
51
|
-
screens/
|
|
52
|
-
services/
|
|
53
|
-
utils/
|
|
54
|
-
hooks/
|
|
55
|
-
store/
|
|
56
|
-
theme/
|
|
57
|
-
assets/
|
|
58
|
-
types/
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
### Utilities Added
|
|
5
|
+
  
|
|
62
6
|
|
|
63
|
-
|
|
64
|
-
* Responsive screen helpers
|
|
65
|
-
* Image import TypeScript support
|
|
66
|
-
* Clean folder structure
|
|
7
|
+
**RNSUP** helps you set up a production-ready React Native project in minutes instead of hours.
|
|
67
8
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
## Installed packages (default)
|
|
71
|
-
|
|
72
|
-
RNSUP installs a curated set of libraries into your project. These are added automatically when you run `npx rnsup setup` (some are optional via prompt):
|
|
73
|
-
|
|
74
|
-
- `@react-navigation/native`
|
|
75
|
-
- `react-native-screens`
|
|
76
|
-
- `react-native-gesture-handler`
|
|
77
|
-
- `react-native-reanimated`
|
|
78
|
-
- `react-native-worklets` (Babel plugin integration)
|
|
79
|
-
- `react-native-vector-icons`
|
|
80
|
-
- `zustand`
|
|
81
|
-
- `axios`
|
|
82
|
-
- `@tanstack/react-query`
|
|
83
|
-
- `react-native-mmkv`
|
|
84
|
-
- navigation extras (conditional): `@react-navigation/native-stack`, `@react-navigation/bottom-tabs`, `@react-navigation/drawer`
|
|
85
|
-
- optional (prompted): `react-native-svg`, `lucide-react-native`
|
|
86
|
-
|
|
87
|
-
<div style="background:#fff3cd;border-left:6px solid #ffeeba;padding:12px;border-radius:6px">
|
|
88
|
-
<strong>⚠️ Warning</strong>
|
|
89
|
-
<p style="margin:6px 0 0">Many of the packages above include native code. After installation you <strong>must</strong> verify and complete any required native configuration (for iOS and Android). Common steps include:</p>
|
|
90
|
-
<ul style="margin:6px 0 0;padding-left:20px">
|
|
91
|
-
<li>Run <code>cd ios && pod install</code> on macOS</li>
|
|
92
|
-
<li>Follow the official docs for Reanimated, MMKV, react-native-svg and React Navigation</li>
|
|
93
|
-
<li>Check Android Gradle / manifest changes for native modules</li>
|
|
94
|
-
</ul>
|
|
95
|
-
<p style="margin:6px 0 0">If something looks off (build errors, missing icons, or runtime crashes), consult the package docs first — RNSUP does not (and cannot) run platform-specific installs for you.</p>
|
|
96
|
-
</div>
|
|
97
|
-
|
|
98
|
-
---
|
|
99
|
-
### Developer Experience
|
|
100
|
-
|
|
101
|
-
* Auto import aliases (`@components`, `@services`, etc.)
|
|
102
|
-
* Code generators (screens & components)
|
|
103
|
-
* History tracking
|
|
9
|
+
What normally takes 3–6 hours of manual configuration — installation, setup, folder structure, aliases, API client setup — gets done automatically with a single command.
|
|
104
10
|
|
|
105
11
|
---
|
|
106
12
|
|
|
107
|
-
##
|
|
108
|
-
|
|
109
|
-
You DO NOT install RNSUP globally.
|
|
13
|
+
## Features at a Glance
|
|
110
14
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
15
|
+
| Feature | What You Get |
|
|
16
|
+
|---------|-------------|
|
|
17
|
+
| **Navigation** | React Navigation with preset stacks configured |
|
|
18
|
+
| **Performance** | Reanimated + Worklets for smooth animations |
|
|
19
|
+
| **Gestures** | Gesture Handler pre-integrated |
|
|
20
|
+
| **Routing** | TypeScript paths and Babel aliases |
|
|
21
|
+
| **APIs** | Axios with interceptors ready to use |
|
|
22
|
+
| **Utilities** | Responsive helpers, image imports, TypeScript support |
|
|
23
|
+
| **State** | Zustand store setup with TypeScript |
|
|
24
|
+
| **Generators** | CLI commands for screens, components, and folders |
|
|
25
|
+
| **Structure** | Pre-built folder organization |
|
|
116
26
|
|
|
117
27
|
---
|
|
118
28
|
|
|
119
|
-
##
|
|
29
|
+
## Install & Setup
|
|
120
30
|
|
|
121
|
-
|
|
122
|
-
for creating latest cli project !
|
|
31
|
+
No global installation needed. Just run:
|
|
123
32
|
|
|
124
33
|
```bash
|
|
125
|
-
npx create-rn
|
|
34
|
+
npx create-rn MyApp
|
|
126
35
|
cd MyApp
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
### 2) Run RNSUP
|
|
130
|
-
|
|
131
|
-
```bash
|
|
132
36
|
npx rnsup setup
|
|
133
37
|
```
|
|
134
38
|
|
|
135
|
-
Follow the prompts.
|
|
136
|
-
|
|
137
|
-
After setup:
|
|
39
|
+
Follow the prompts to select your package manager. That's it—your project is ready.
|
|
138
40
|
|
|
139
41
|
```bash
|
|
140
42
|
npx react-native start --reset-cache
|
|
141
43
|
npx react-native run-android
|
|
142
44
|
```
|
|
143
45
|
|
|
144
|
-
Your project is ready.
|
|
145
|
-
|
|
146
46
|
---
|
|
147
47
|
|
|
148
|
-
##
|
|
48
|
+
## What Gets Installed
|
|
149
49
|
|
|
150
|
-
|
|
50
|
+
RNSUP automatically installs and configures these packages:
|
|
151
51
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
52
|
+
| Package | Purpose | Type |
|
|
53
|
+
|---------|---------|------|
|
|
54
|
+
| `@react-navigation/native` | Screen navigation | Required |
|
|
55
|
+
| `react-native-gesture-handler` | Touch gesture support | Required |
|
|
56
|
+
| `react-native-reanimated` | Smooth animations | Required |
|
|
57
|
+
| `react-native-screens` | Performance optimization | Required |
|
|
58
|
+
| `axios` | HTTP client | Required |
|
|
59
|
+
| `zustand` | State management | Required |
|
|
60
|
+
| `@tanstack/react-query` | Data fetching | Required |
|
|
61
|
+
| `react-native-mmkv` | Fast storage | Required |
|
|
62
|
+
| `react-native-vector-icons` | Icon library | Required |
|
|
63
|
+
| `@react-navigation/native-stack` | Stack navigation | Optional |
|
|
64
|
+
| `@react-navigation/bottom-tabs` | Tab navigation | Optional |
|
|
65
|
+
| `react-native-svg` | SVG support | Optional |
|
|
66
|
+
| `lucide-react-native` | Icon set | Optional |
|
|
157
67
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
> Here `s` mean `screen`, and `g` mean `generate`
|
|
68
|
+
⚠️ **Note:** Many packages include native code. After setup, you'll need to complete native configuration for iOS and Android (pod install, gradle sync, manifest updates). Check the official docs for each package.
|
|
161
69
|
|
|
70
|
+
---
|
|
162
71
|
|
|
163
|
-
|
|
164
|
-
rnsup g s Login
|
|
165
|
-
rnsup g s auth/Login
|
|
166
|
-
rnsup g s features/auth/Login
|
|
167
|
-
```
|
|
72
|
+
## Project Structure
|
|
168
73
|
|
|
169
|
-
|
|
74
|
+
After setup, your project will have:
|
|
170
75
|
|
|
171
76
|
```
|
|
172
|
-
src/
|
|
173
|
-
|
|
174
|
-
|
|
77
|
+
src/
|
|
78
|
+
├── components/ # Reusable UI components
|
|
79
|
+
├── screens/ # App screens/pages
|
|
80
|
+
├── services/ # API calls & external services
|
|
81
|
+
├── utils/ # Helper functions
|
|
82
|
+
├── hooks/ # Custom React hooks
|
|
83
|
+
├── store/ # State management
|
|
84
|
+
├── theme/ # Colors, typography, styling
|
|
85
|
+
├── assets/ # Images, fonts, static files
|
|
86
|
+
└── types/ # TypeScript types & interfaces
|
|
175
87
|
```
|
|
176
88
|
|
|
177
89
|
---
|
|
178
90
|
|
|
179
|
-
|
|
91
|
+
## Commands
|
|
180
92
|
|
|
181
|
-
|
|
93
|
+
### Generate a Screen
|
|
182
94
|
|
|
183
|
-
```
|
|
184
|
-
rnsup g
|
|
185
|
-
rnsup g
|
|
95
|
+
```bash
|
|
96
|
+
rnsup g s LoginScreen
|
|
97
|
+
rnsup g s auth/LoginScreen
|
|
98
|
+
rnsup g s features/auth/LoginScreen
|
|
186
99
|
```
|
|
187
100
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
```
|
|
191
|
-
src/components/Button.tsx
|
|
192
|
-
src/components/ui/forms/Input.tsx
|
|
193
|
-
```
|
|
101
|
+
Choose from: **Basic**, **List**, **Form**, or **Detail** templates.
|
|
194
102
|
|
|
195
|
-
|
|
103
|
+
### Generate a Component
|
|
196
104
|
|
|
197
|
-
|
|
105
|
+
```bash
|
|
106
|
+
rnsup g c Button
|
|
107
|
+
rnsup g c ui/Card
|
|
108
|
+
rnsup g c forms/TextInput
|
|
109
|
+
```
|
|
198
110
|
|
|
199
|
-
|
|
111
|
+
Creates `.tsx` by default (press Enter) or choose `.jsx`.
|
|
200
112
|
|
|
201
|
-
|
|
113
|
+
### Generate a Folder
|
|
202
114
|
|
|
203
|
-
```
|
|
204
|
-
rnsup g d
|
|
205
|
-
rnsup g d src/
|
|
115
|
+
```bash
|
|
116
|
+
rnsup g d themes
|
|
117
|
+
rnsup g d src/api
|
|
206
118
|
rnsup g d src/utils/helpers
|
|
207
119
|
```
|
|
208
120
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
```
|
|
212
|
-
features/
|
|
213
|
-
src/store/
|
|
214
|
-
src/utils/helpers/
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
**Features:**
|
|
121
|
+
Auto-registers TypeScript aliases for `src/` folders.
|
|
218
122
|
|
|
219
|
-
|
|
220
|
-
- ✅ Confirmation before creating
|
|
221
|
-
- 📝 Optional `index.ts` file generation (for exports)
|
|
222
|
-
- 🔗 Auto-alias registration for `src/` folders
|
|
223
|
-
- 📋 History tracking
|
|
123
|
+
### View Project Structure
|
|
224
124
|
|
|
225
|
-
|
|
125
|
+
```bash
|
|
126
|
+
rnsup view # Show raw structure
|
|
127
|
+
rnsup view -p # Show with icons and colors
|
|
128
|
+
rnsup view --time # Show with timestamps
|
|
129
|
+
rnsup view -p --time # Pretty + timestamps
|
|
130
|
+
```
|
|
226
131
|
|
|
227
|
-
|
|
228
|
-
- If just a name is provided (e.g., `rnsup g d config`), folder is created at project root
|
|
229
|
-
- Supports nested paths: `rnsup g d src/features/auth/screens`
|
|
132
|
+
Choose between Root level or src/ folder when prompted.
|
|
230
133
|
|
|
231
134
|
---
|
|
232
135
|
|
|
233
|
-
##
|
|
136
|
+
## Usage Examples
|
|
234
137
|
|
|
235
|
-
|
|
138
|
+
### Import Components (No Relative Paths)
|
|
236
139
|
|
|
237
140
|
Instead of:
|
|
238
|
-
|
|
239
|
-
```ts
|
|
141
|
+
```typescript
|
|
240
142
|
import Button from '../../../components/Button';
|
|
241
143
|
```
|
|
242
144
|
|
|
243
145
|
Use:
|
|
244
|
-
|
|
245
|
-
```ts
|
|
146
|
+
```typescript
|
|
246
147
|
import Button from '@components/Button';
|
|
247
148
|
```
|
|
248
149
|
|
|
249
|
-
|
|
150
|
+
Automatically configured aliases:
|
|
151
|
+
- `@components` → `src/components/`
|
|
152
|
+
- `@screens` → `src/screens/`
|
|
153
|
+
- `@services` → `src/services/`
|
|
154
|
+
- `@utils` → `src/utils/`
|
|
155
|
+
- `@hooks` → `src/hooks/`
|
|
156
|
+
- `@store` → `src/store/`
|
|
157
|
+
- `@theme` → `src/theme/`
|
|
158
|
+
- `@assets` → `src/assets/`
|
|
250
159
|
|
|
251
|
-
|
|
252
|
-
@components
|
|
253
|
-
@services
|
|
254
|
-
@utils
|
|
255
|
-
@hooks
|
|
256
|
-
@store
|
|
257
|
-
@theme
|
|
258
|
-
@assets
|
|
259
|
-
```
|
|
160
|
+
### Use the API Client
|
|
260
161
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
---
|
|
264
|
-
|
|
265
|
-
## Axios Usage
|
|
266
|
-
|
|
267
|
-
```ts
|
|
162
|
+
```typescript
|
|
268
163
|
import api from '@services/api/client';
|
|
269
164
|
|
|
165
|
+
// GET request
|
|
270
166
|
const users = await api.get('/users');
|
|
271
|
-
```
|
|
272
167
|
|
|
273
|
-
|
|
168
|
+
// POST request
|
|
169
|
+
const response = await api.post('/login', { email, password });
|
|
170
|
+
```
|
|
274
171
|
|
|
275
|
-
|
|
172
|
+
Interceptors are pre-configured for error handling and auth tokens.
|
|
276
173
|
|
|
277
|
-
|
|
174
|
+
### Responsive Layouts
|
|
278
175
|
|
|
279
|
-
```
|
|
280
|
-
import { widthPercentageToDP as wp } from '@utils/responsive-screen';
|
|
176
|
+
```typescript
|
|
177
|
+
import { widthPercentageToDP as wp, heightPercentageToDP as hp } from '@utils/responsive-screen';
|
|
281
178
|
|
|
282
|
-
<View style={{ width: wp(80) }} />
|
|
179
|
+
<View style={{ width: wp(80), height: hp(50) }} />
|
|
283
180
|
```
|
|
284
181
|
|
|
285
|
-
|
|
182
|
+
Works on all device sizes without manual breakpoints.
|
|
286
183
|
|
|
287
|
-
|
|
184
|
+
### Import Images in TypeScript
|
|
288
185
|
|
|
289
|
-
```
|
|
186
|
+
```typescript
|
|
290
187
|
import logo from '@assets/logo.png';
|
|
291
188
|
|
|
292
|
-
<Image source={logo} />
|
|
189
|
+
<Image source={logo} style={{ width: 100, height: 100 }} />
|
|
293
190
|
```
|
|
294
191
|
|
|
295
|
-
No TypeScript
|
|
192
|
+
No TypeScript errors—types are automatically set up.
|
|
296
193
|
|
|
297
194
|
---
|
|
298
195
|
|
|
299
|
-
##
|
|
196
|
+
## Auto Aliases
|
|
300
197
|
|
|
301
|
-
|
|
198
|
+
New folders inside `src/` automatically get alias support:
|
|
302
199
|
|
|
303
|
-
|
|
200
|
+
```bash
|
|
201
|
+
rnsup g d src/modals
|
|
202
|
+
# Now use: import Modal from '@modals/MyModal';
|
|
203
|
+
```
|
|
304
204
|
|
|
305
|
-
|
|
306
|
-
* Prevents configuration mistakes
|
|
307
|
-
* Standardizes project structure
|
|
308
|
-
* Faster onboarding for new developers
|
|
309
|
-
* Clean import paths
|
|
310
|
-
* Production-ready base
|
|
205
|
+
Aliases update in both TypeScript `tsconfig.json` and Babel `.babelrc`.
|
|
311
206
|
|
|
312
207
|
---
|
|
313
208
|
|
|
314
209
|
## Best Practices
|
|
315
210
|
|
|
316
|
-
|
|
211
|
+
1. **Always use generators** — Keeps aliases and structure consistent
|
|
212
|
+
2. **Avoid manual folders** — Use `rnsup g d` instead
|
|
213
|
+
3. **Keep folder names consistent** — Use kebab-case or camelCase, not spaces
|
|
214
|
+
4. **Update native config** — Don't skip iOS/Android setup
|
|
215
|
+
5. **Commit early** — Make a git commit right after `rnsup setup`
|
|
317
216
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Troubleshooting
|
|
220
|
+
|
|
221
|
+
**Error: "Not a React Native CLI project"**
|
|
222
|
+
- Run `rnsup setup` from your React Native project root (where `package.json` exists)
|
|
322
223
|
|
|
323
|
-
|
|
224
|
+
**Error: "Selected package manager is not installed"**
|
|
225
|
+
- Install npm, yarn, or pnpm first
|
|
324
226
|
|
|
227
|
+
**Native build fails after setup**
|
|
228
|
+
- Run `cd ios && pod install` (macOS only)
|
|
229
|
+
- Check your Android SDK and NDK are up to date
|
|
230
|
+
- Read the official docs for each native package
|
|
325
231
|
|
|
326
|
-
|
|
232
|
+
**Aliases not working**
|
|
233
|
+
- Run `npx react-native start --reset-cache`
|
|
234
|
+
- If still broken, check `tsconfig.json` has correct paths
|
|
235
|
+
|
|
236
|
+
---
|
|
327
237
|
|
|
328
|
-
|
|
238
|
+
## Contributing
|
|
329
239
|
|
|
330
|
-
|
|
240
|
+
Found a bug or want a feature? Open an issue or submit a PR at dev branch.
|
|
331
241
|
|
|
332
242
|
---
|
|
333
243
|
|
|
334
244
|
## License
|
|
335
245
|
|
|
336
|
-
MIT
|
|
246
|
+
MIT © 2026
|
|
@@ -8,17 +8,36 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
10
10
|
const chalk_1 = __importDefault(require("chalk"));
|
|
11
|
-
const
|
|
11
|
+
const componentTemplates_1 = require("../templates/componentTemplates");
|
|
12
12
|
const parseComponentName_1 = require("../utils/parseComponentName");
|
|
13
13
|
const aliasManager_1 = require("../utils/aliasManager");
|
|
14
14
|
const history_1 = require("../utils/history");
|
|
15
|
+
const handleCancel_1 = require("../utils/handleCancel");
|
|
15
16
|
async function generateComponent(input) {
|
|
16
17
|
try {
|
|
17
18
|
const { componentName, fullDir, relativeDir } = (0, parseComponentName_1.parseComponentName)(input);
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
// Ask for file extension
|
|
20
|
+
const { fileExtension } = await inquirer_1.default.prompt([
|
|
21
|
+
{
|
|
22
|
+
type: 'list',
|
|
23
|
+
name: 'fileExtension',
|
|
24
|
+
message: 'Enter file extension:',
|
|
25
|
+
choices: [
|
|
26
|
+
{ name: 'TypeScript (tsx) - Default, Recommended', value: 'tsx' },
|
|
27
|
+
{ name: 'JavaScript (jsx)', value: 'jsx' }
|
|
28
|
+
],
|
|
29
|
+
default: 'tsx'
|
|
30
|
+
}
|
|
31
|
+
]);
|
|
32
|
+
const filePath = path_1.default.join(fullDir, `${componentName}.${fileExtension}`);
|
|
33
|
+
// Show colored details
|
|
34
|
+
console.log('\n' + chalk_1.default.cyan.bold('🏗️ Component Creation Details'));
|
|
35
|
+
console.log(chalk_1.default.gray('─'.repeat(50)));
|
|
36
|
+
console.log(chalk_1.default.yellow('Name: '), chalk_1.default.cyan(componentName));
|
|
37
|
+
console.log(chalk_1.default.yellow('Extension: '), chalk_1.default.magenta(fileExtension.toUpperCase()));
|
|
38
|
+
console.log(chalk_1.default.yellow('Location: '), chalk_1.default.white(relativeDir));
|
|
39
|
+
console.log(chalk_1.default.yellow('File: '), chalk_1.default.dim(`${componentName}.${fileExtension}`));
|
|
40
|
+
console.log(chalk_1.default.gray('─'.repeat(50)));
|
|
22
41
|
// overwrite check
|
|
23
42
|
if (await fs_extra_1.default.pathExists(filePath)) {
|
|
24
43
|
const { overwrite } = await inquirer_1.default.prompt([
|
|
@@ -30,7 +49,7 @@ async function generateComponent(input) {
|
|
|
30
49
|
}
|
|
31
50
|
]);
|
|
32
51
|
if (!overwrite) {
|
|
33
|
-
console.log(chalk_1.default.yellow('
|
|
52
|
+
console.log(chalk_1.default.yellow('Operation cancelled.'));
|
|
34
53
|
return;
|
|
35
54
|
}
|
|
36
55
|
}
|
|
@@ -38,33 +57,28 @@ async function generateComponent(input) {
|
|
|
38
57
|
{
|
|
39
58
|
type: 'confirm',
|
|
40
59
|
name: 'confirm',
|
|
41
|
-
message: `Create ${componentName}
|
|
60
|
+
message: chalk_1.default.green(`Create ${componentName} (${fileExtension.toUpperCase()})?`),
|
|
42
61
|
default: true
|
|
43
62
|
}
|
|
44
63
|
]);
|
|
45
|
-
if (!confirm)
|
|
64
|
+
if (!confirm) {
|
|
65
|
+
console.log(chalk_1.default.yellow('Cancelled.'));
|
|
46
66
|
return;
|
|
67
|
+
}
|
|
47
68
|
// create directory
|
|
48
69
|
await fs_extra_1.default.ensureDir(fullDir);
|
|
49
70
|
// ensure alias (for nested components like ui/forms)
|
|
50
71
|
await (0, aliasManager_1.registerAlias)(relativeDir);
|
|
51
|
-
// write component
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
await fs_extra_1.default.appendFile(indexFile, exportLine);
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
await fs_extra_1.default.writeFile(indexFile, exportLine);
|
|
63
|
-
}
|
|
64
|
-
await (0, history_1.addHistory)(`Generated component ${componentName}`);
|
|
65
|
-
console.log(chalk_1.default.green(`\n${componentName} created successfully.`));
|
|
72
|
+
// write component with simple template
|
|
73
|
+
const template = (0, componentTemplates_1.getComponentTemplate)(componentName, 'presentational');
|
|
74
|
+
await fs_extra_1.default.writeFile(filePath, template);
|
|
75
|
+
await (0, history_1.addHistory)(`Generated component ${componentName} (${fileExtension})`);
|
|
76
|
+
console.log(chalk_1.default.green(`\n✨ Component ${chalk_1.default.bold(componentName)} created successfully!`));
|
|
77
|
+
console.log(chalk_1.default.gray(`Location: ${relativeDir}`));
|
|
78
|
+
console.log(chalk_1.default.gray(`Extension: ${fileExtension}`));
|
|
79
|
+
console.log();
|
|
66
80
|
}
|
|
67
81
|
catch (err) {
|
|
68
|
-
|
|
82
|
+
(0, handleCancel_1.handleCancel)(err);
|
|
69
83
|
}
|
|
70
84
|
}
|
|
@@ -10,6 +10,7 @@ const inquirer_1 = __importDefault(require("inquirer"));
|
|
|
10
10
|
const chalk_1 = __importDefault(require("chalk"));
|
|
11
11
|
const history_1 = require("../utils/history");
|
|
12
12
|
const aliasManager_1 = require("../utils/aliasManager");
|
|
13
|
+
const handleCancel_1 = require("../utils/handleCancel");
|
|
13
14
|
async function generateFolder(input) {
|
|
14
15
|
try {
|
|
15
16
|
// normalize slashes and clean input
|
|
@@ -97,6 +98,6 @@ async function generateFolder(input) {
|
|
|
97
98
|
console.log();
|
|
98
99
|
}
|
|
99
100
|
catch (err) {
|
|
100
|
-
|
|
101
|
+
(0, handleCancel_1.handleCancel)(err);
|
|
101
102
|
}
|
|
102
103
|
}
|
|
@@ -9,16 +9,38 @@ const path_1 = __importDefault(require("path"));
|
|
|
9
9
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
10
10
|
const chalk_1 = __importDefault(require("chalk"));
|
|
11
11
|
const parseName_1 = require("../utils/parseName");
|
|
12
|
-
const
|
|
12
|
+
const screenTemplates_1 = require("../templates/screenTemplates");
|
|
13
13
|
const history_1 = require("../utils/history");
|
|
14
14
|
const aliasManager_1 = require("../utils/aliasManager");
|
|
15
|
+
const handleCancel_1 = require("../utils/handleCancel");
|
|
15
16
|
async function generateScreen(input) {
|
|
16
17
|
try {
|
|
17
18
|
const { screenName, fullDir, relativeDir } = await (0, parseName_1.parseScreenName)(input);
|
|
18
19
|
const filePath = path_1.default.join(fullDir, `${screenName}.tsx`);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
const indexFile = path_1.default.join(fullDir, 'index.ts');
|
|
21
|
+
// Ask for screen type
|
|
22
|
+
const { screenType } = await inquirer_1.default.prompt([
|
|
23
|
+
{
|
|
24
|
+
type: 'list',
|
|
25
|
+
name: 'screenType',
|
|
26
|
+
message: 'Select screen type:',
|
|
27
|
+
choices: [
|
|
28
|
+
{ name: 'Basic - Simple screen with title', value: 'basic' },
|
|
29
|
+
{ name: 'List - FlatList with items', value: 'list' },
|
|
30
|
+
{ name: 'Form - Input form with submission', value: 'form' },
|
|
31
|
+
{ name: 'Detail - Detail view with data display', value: 'detail' }
|
|
32
|
+
],
|
|
33
|
+
default: 'basic'
|
|
34
|
+
}
|
|
35
|
+
]);
|
|
36
|
+
// Show colored details
|
|
37
|
+
console.log('\n' + chalk_1.default.cyan.bold('🎬 Screen Creation Details'));
|
|
38
|
+
console.log(chalk_1.default.gray('─'.repeat(50)));
|
|
39
|
+
console.log(chalk_1.default.yellow('Name: '), chalk_1.default.cyan(screenName));
|
|
40
|
+
console.log(chalk_1.default.yellow('Type: '), chalk_1.default.magenta(screenType));
|
|
41
|
+
console.log(chalk_1.default.yellow('Location: '), chalk_1.default.white(relativeDir));
|
|
42
|
+
console.log(chalk_1.default.yellow('Files: '), chalk_1.default.dim(`${screenName}.tsx, index.ts`));
|
|
43
|
+
console.log(chalk_1.default.gray('─'.repeat(50)));
|
|
22
44
|
// confirm directory creation
|
|
23
45
|
if (!(await fs_extra_1.default.pathExists(fullDir))) {
|
|
24
46
|
const { createDir } = await inquirer_1.default.prompt([
|
|
@@ -53,7 +75,7 @@ async function generateScreen(input) {
|
|
|
53
75
|
{
|
|
54
76
|
type: 'confirm',
|
|
55
77
|
name: 'confirm',
|
|
56
|
-
message: `Create ${screenName}
|
|
78
|
+
message: chalk_1.default.green(`Create ${screenName} (${screenType})?`),
|
|
57
79
|
default: true
|
|
58
80
|
}
|
|
59
81
|
]);
|
|
@@ -63,9 +85,9 @@ async function generateScreen(input) {
|
|
|
63
85
|
}
|
|
64
86
|
await fs_extra_1.default.ensureDir(fullDir);
|
|
65
87
|
await (0, aliasManager_1.registerAlias)(relativeDir);
|
|
66
|
-
|
|
88
|
+
const template = (0, screenTemplates_1.getScreenTemplate)(screenName, screenType);
|
|
89
|
+
await fs_extra_1.default.writeFile(filePath, template);
|
|
67
90
|
// create index export
|
|
68
|
-
const indexFile = path_1.default.join(fullDir, 'index.ts');
|
|
69
91
|
const exportLine = `export { default as ${screenName} } from './${screenName}';\n`;
|
|
70
92
|
if (await fs_extra_1.default.pathExists(indexFile)) {
|
|
71
93
|
const existing = await fs_extra_1.default.readFile(indexFile, 'utf8');
|
|
@@ -75,10 +97,13 @@ async function generateScreen(input) {
|
|
|
75
97
|
else {
|
|
76
98
|
await fs_extra_1.default.writeFile(indexFile, exportLine);
|
|
77
99
|
}
|
|
78
|
-
await (0, history_1.addHistory)(`Generated screen ${screenName}`);
|
|
79
|
-
console.log(chalk_1.default.green(`\n${screenName} created successfully
|
|
100
|
+
await (0, history_1.addHistory)(`Generated screen ${screenName} (${screenType})`);
|
|
101
|
+
console.log(chalk_1.default.green(`\n✨ Screen ${chalk_1.default.bold(screenName)} created successfully!`));
|
|
102
|
+
console.log(chalk_1.default.gray(`Location: ${relativeDir}`));
|
|
103
|
+
console.log(chalk_1.default.gray(`Type: ${screenType}`));
|
|
104
|
+
console.log();
|
|
80
105
|
}
|
|
81
106
|
catch (err) {
|
|
82
|
-
|
|
107
|
+
(0, handleCancel_1.handleCancel)(err);
|
|
83
108
|
}
|
|
84
109
|
}
|