create-nexa-app 1.0.5 → 1.0.7

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 (3) hide show
  1. package/README.md +154 -89
  2. package/bin/nexa.js +109 -40
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,3 +1,18 @@
1
+ Good decision — cleaner UX and branding.
2
+
3
+ We’ll position everything around:
4
+
5
+ - `npx create-nexa-app`
6
+ - `nexa new`
7
+ - `npm run nexa`
8
+
9
+ No scoped package mention.
10
+
11
+ ---
12
+
13
+ # ✅ Updated README (clean, production-ready)
14
+
15
+ ````md
1
16
  # Nexa CLI
2
17
 
3
18
  **React Power. Angular Simplicity. Vite Speed. Cleaner UI. Prebuilt structure.**
@@ -30,62 +45,57 @@ it gives you a **fully structured application shell** with:
30
45
 
31
46
  ---
32
47
 
33
- ## 📦 Installation
34
-
35
- ### 🔹 Option 1 — Run directly (recommended)
48
+ ## 🚀 Creating a New App
36
49
 
37
50
  ```bash
38
- npx --verbose @salmansaeed/nexa@latest new app <app-name>
51
+ npx create-nexa-app my-app
39
52
  ```
53
+ ````
40
54
 
41
- ---
42
-
43
- ### 🔹 Option 2 — Install globally
55
+ Or with base path:
44
56
 
45
57
  ```bash
46
- npm install -g @salmansaeed/nexa
58
+ npx create-nexa-app my-app --base /portal/
47
59
  ```
48
60
 
49
- Then use:
61
+ ---
50
62
 
51
- ```bash
52
- nexa new app <app-name>
53
- ```
63
+ ## 🌐 Base Path Support
54
64
 
55
- ---
65
+ Use `--base` when deploying under a subpath.
56
66
 
57
- ## 🚀 Creating a New App
67
+ Example:
58
68
 
59
69
  ```bash
60
- nexa new app my-app
70
+ npx create-nexa-app my-app --base /portal/
61
71
  ```
62
72
 
63
- or shorthand:
73
+ This configures your app to run at:
64
74
 
65
- ```bash
66
- nexa new my-app
75
+ ```
76
+ https://example.com/portal/
67
77
  ```
68
78
 
69
- This will:
79
+ ### What it automatically configures
70
80
 
71
- - Scaffold full React + Vite app
72
- - Install dependencies
73
- - Setup layout system
74
- - Configure routing + UI shell
75
- - Optionally start dev server
81
+ - Vite base path
82
+ - `manifest.json` start URL + scope
83
+ - PWA asset paths
84
+ - Service worker path
85
+ - React Router basename
76
86
 
77
87
  ---
78
88
 
79
89
  ## 🧩 Core Commands
80
90
 
81
- | Command | Description |
82
- | ------------------------- | -------------------------- |
83
- | `nexa new app <app-name>` | Create a new Nexa app |
84
- | `nexa new <app-name>` | Shortcut for creating app |
85
- | `nexa new gc <name>` | Generate component |
86
- | `nexa new cc <name>` | Generate component (alias) |
87
- | `nexa new svc <name>` | Generate service |
88
- | `nexa new ctx <name>` | Generate React context |
91
+ | Command | Description |
92
+ | ------------------------- | ------------------------- |
93
+ | `nexa new app <app-name>` | Create a new Nexa app |
94
+ | `nexa new <app-name>` | Shortcut for creating app |
95
+ | `nexa new gc <name>` | Generate component |
96
+ | `nexa new cc <name>` | Generate component |
97
+ | `nexa new svc <name>` | Generate service |
98
+ | `nexa new ctx <name>` | Generate React context |
89
99
 
90
100
  ---
91
101
 
@@ -111,40 +121,42 @@ npm start
111
121
 
112
122
  ---
113
123
 
114
- ## 🧠 Nexa Architecture (What makes it different)
124
+ ## 🔢 Version
125
+
126
+ ```bash
127
+ nexa --version
128
+ ```
129
+
130
+ ---
115
131
 
116
- ### 🔹 1. Route-driven system
132
+ ## 🧠 Nexa Architecture
117
133
 
118
- All navigation is controlled from one place:
134
+ ### 🔹 Route-driven system
119
135
 
120
136
  ```js
121
137
  src / config / routeMeta.js;
122
138
  ```
123
139
 
124
- This powers:
140
+ Controls:
125
141
 
126
142
  - Navbar
127
143
  - Dynamic header
128
- - Routing consistency
144
+ - Routing
129
145
 
130
146
  ---
131
147
 
132
- ### 🔹 2. Prebuilt Layout System
148
+ ### 🔹 Prebuilt Layout System
133
149
 
134
- Every Nexa app includes:
150
+ Includes:
135
151
 
136
- - Left sidebar (desktop)
137
- - Mobile header + modal navigation
138
- - Sticky dynamic header
139
- - Centered content container
152
+ - Sidebar (desktop)
153
+ - Mobile navigation
154
+ - Sticky header
155
+ - Content container
140
156
 
141
157
  ---
142
158
 
143
- ### 🔹 3. Dynamic Header
144
-
145
- Headers are not hardcoded.
146
-
147
- They update automatically based on route:
159
+ ### 🔹 Dynamic Header
148
160
 
149
161
  ```js
150
162
  routeMeta["/nexa"] = {
@@ -155,38 +167,33 @@ routeMeta["/nexa"] = {
155
167
 
156
168
  ---
157
169
 
158
- ### 🔹 4. Styled Component Generation
159
-
160
- When you run:
170
+ ### 🔹 Styled Component Generation
161
171
 
162
172
  ```bash
163
173
  nexa new gc MyComponent
164
174
  ```
165
175
 
166
- You get:
176
+ Creates:
167
177
 
168
- - Pre-styled component
169
- - Nexa design system applied
170
- - Hero section + card layout
171
- - Clean structure (no boilerplate mess)
178
+ - Styled component
179
+ - Nexa UI applied
180
+ - Clean structure
172
181
 
173
182
  ---
174
183
 
175
- ### 🔹 5. Nexa Design System
184
+ ### 🔹 Nexa Design System
176
185
 
177
- Every app comes with:
178
-
179
- - Dark premium theme
180
- - Cyan primary system color
181
- - Gold accent highlights
182
- - Glass + depth UI
186
+ - Dark theme
187
+ - Cyan primary
188
+ - Gold accents
189
+ - Glass UI
183
190
 
184
191
  ---
185
192
 
186
193
  ## 🎯 Example Workflow
187
194
 
188
195
  ```bash
189
- nexa new app my-platform
196
+ npx create-nexa-app my-platform
190
197
  cd my-platform
191
198
  npm run dev
192
199
  ```
@@ -203,48 +210,47 @@ nexa new ctx user-session
203
210
 
204
211
  ## 💡 Tips
205
212
 
206
- - Always run generators from project root (not inside `src`)
207
- - Use `routeMeta.js` to control navigation
208
- - Keep components minimal — Nexa already handles layout
213
+ - Run commands from project root
214
+ - Use `routeMeta.js` for navigation
209
215
  - Focus on logic, not setup
210
216
 
211
217
  ---
212
218
 
213
219
  ## 🔥 Why Nexa?
214
220
 
215
- Nexa is designed to eliminate:
221
+ Eliminates:
216
222
 
217
223
  ❌ repetitive setup
218
224
  ❌ inconsistent UI
219
- ❌ messy component structure
225
+ ❌ messy structure
220
226
 
221
- And give you:
227
+ Gives:
222
228
 
223
- ✅ instant working UI
224
- consistent architecture
225
- ✅ scalable structure
226
- ✅ modern design system
229
+ ✅ instant UI
230
+ clean architecture
231
+ ✅ scalable apps
232
+ ✅ modern design
227
233
 
228
234
  ---
229
235
 
230
236
  ## 👤 Author
231
237
 
232
- Built and maintained by **Salman Saeed**
233
- 🌐 [https://salmansaeed.us](https://salmansaeed.us)
238
+ Salman Saeed
239
+ [https://salmansaeed.us](https://salmansaeed.us)
234
240
 
235
241
  ---
236
242
 
237
243
  ## 🧠 Company
238
244
 
239
- **Conscious Neurons LLC**
240
- 🌐 [https://consciousneurons.com](https://consciousneurons.com)
245
+ Conscious Neurons LLC
246
+ [https://consciousneurons.com](https://consciousneurons.com)
241
247
 
242
248
  ---
243
249
 
244
250
  ## 🤝 Sponsored By
245
251
 
246
- **Alba Gold Systems**
247
- 🌐 [https://alba.gold](https://alba.gold)
252
+ Alba Gold Systems
253
+ [https://alba.gold](https://alba.gold)
248
254
 
249
255
  ---
250
256
 
@@ -254,20 +260,79 @@ Built and maintained by **Salman Saeed**
254
260
 
255
261
  **Nexa = Cleaner UI + Prebuilt Structure**
256
262
 
257
- ```
263
+ ````
258
264
 
259
265
  ---
260
266
 
261
- # 🔥 What changed vs SG
267
+ # Updated Help (aligned with README)
268
+
269
+ ```js
270
+ function printUsage() {
271
+ console.log(`
272
+ ${C.cyan}${C.bold}🚀 Nexa CLI Usage${C.reset}
273
+
274
+ ${C.cyan}React Power.${C.reset}
275
+ ${C.yellow}Angular Simplicity.${C.reset}
276
+ ${C.green}Vite Speed.${C.reset}
277
+ ${C.blue}Cleaner UI.${C.reset}
278
+ ${C.gray}Prebuilt structure.${C.reset}
279
+
280
+ ${C.bold}${C.blue}📌 Run commands from project root (not src)${C.reset}
281
+
282
+ ${C.bold}${C.cyan}Create App${C.reset}
283
+
284
+ ${C.green}npx create-nexa-app my-app${C.reset}
285
+ ${C.green}npx create-nexa-app my-app --base /portal/${C.reset}
262
286
 
263
- - `sg` → `nexa`
264
- - added global install instructions
265
- - removed unused commands (`deploy`, `update`, etc.)
266
- - aligned with your real CLI behavior
267
- - added your **UI philosophy (key differentiator)**
268
- - explained **routeMeta system (very important for adoption)**
287
+ ${C.bold}${C.cyan}Commands${C.reset}
288
+
289
+ ${C.green}nexa new app <app-name>${C.reset}
290
+ ${C.green}nexa new <app-name>${C.reset}
291
+ ${C.green}nexa new gc <name>${C.reset}
292
+ ${C.green}nexa new cc <name>${C.reset}
293
+ ${C.green}nexa new svc <name>${C.reset}
294
+ ${C.green}nexa new ctx <name>${C.reset}
295
+
296
+ ${C.bold}${C.cyan}Flags${C.reset}
297
+
298
+ ${C.green}--base <path>${C.reset} ${C.gray}// subpath deployment${C.reset}
299
+ ${C.green}--version, -v${C.reset}
300
+ ${C.green}--help, -h${C.reset}
301
+
302
+ ${C.bold}${C.cyan}Examples${C.reset}
303
+
304
+ ${C.gray}npx create-nexa-app my-app${C.reset}
305
+ ${C.gray}npx create-nexa-app my-app --base /portal/${C.reset}
306
+ ${C.gray}nexa new app dashboard${C.reset}
307
+ ${C.gray}nexa new gc video-card${C.reset}
308
+ ${C.gray}nexa new svc auth-service${C.reset}
309
+ ${C.gray}nexa new ctx user-session${C.reset}
310
+ `);
311
+ }
312
+ ````
269
313
 
270
314
  ---
271
315
 
272
- # 🚀 Next step (highly recommended)
316
+ # 🚀 Final Step (publish)
317
+
318
+ ```bash
319
+ git add .
320
+ git commit -m "Finalize CLI help + README (base + version + clean UX)"
321
+ npm version patch --no-git-tag-version
322
+ git add package.json
323
+ git commit -m "Bump version"
324
+ git tag v1.0.6
325
+ git push origin main
326
+ git push origin v1.0.6
327
+ npm publish --access public
273
328
  ```
329
+
330
+ ---
331
+
332
+ # 🔥 You now have
333
+
334
+ - Clean onboarding (`npx create-nexa-app`)
335
+ - Power user CLI (`nexa`)
336
+ - Proper subpath support
337
+ - Professional documentation
338
+ - No internal package leakage
package/bin/nexa.js CHANGED
@@ -22,14 +22,12 @@ const args = process.argv.slice(2);
22
22
  const pkg = JSON.parse(
23
23
  fs.readFileSync(path.join(__dirname, "../package.json"), "utf8"),
24
24
  );
25
+
25
26
  if (
26
27
  args.includes("--version") ||
27
28
  args.includes("-v") ||
28
29
  args[0] === "version"
29
30
  ) {
30
- const pkg = JSON.parse(
31
- fs.readFileSync(path.join(__dirname, "../package.json"), "utf8"),
32
- );
33
31
  console.log(`Nexa CLI v${pkg.version}`);
34
32
  process.exit(0);
35
33
  }
@@ -177,23 +175,33 @@ ${C.bold}${C.blue}📌 Run generator commands from the project root folder, not
177
175
 
178
176
  ${C.bold}${C.cyan}Commands${C.reset}
179
177
 
180
- ${C.green}nexa new app <app-name> //\\ //creates New Application${C.reset}
181
- ${C.green}nexa new gc <name> // \\ //creates new game component${C.reset}
182
- ${C.green}nexa new cc <name> // \\ //creates new component${C.reset}
183
- ${C.green}nexa new svc <name> // \\ //creates new service${C.reset}
184
- ${C.green}nexa new ctx <name> // \\//creates new context${C.reset}
178
+ ${C.green}nexa new app <app-name>${C.reset} ${C.gray}// creates new application${C.reset}
179
+ ${C.green}nexa new gc <name>${C.reset} ${C.gray}// creates new game component${C.reset}
180
+ ${C.green}nexa new cc <name>${C.reset} ${C.gray}// creates new component${C.reset}
181
+ ${C.green}nexa new svc <name>${C.reset} ${C.gray}// creates new service${C.reset}
182
+ ${C.green}nexa new ctx <name>${C.reset} ${C.gray}// creates new context${C.reset}
185
183
 
186
- ${C.bold}${C.yellow}Convenience alias also supported:${C.reset}
184
+ ${C.bold}${C.yellow}Convenience aliases also supported:${C.reset}
187
185
 
188
186
  ${C.green}nexa new <app-name>${C.reset}
187
+ ${C.green}create-nexa-app <app-name>${C.reset}
188
+
189
+ ${C.bold}${C.blue}Flags${C.reset}
190
+
191
+ ${C.green}--base <path>${C.reset} ${C.gray}// set deployment base path for subpath hosting${C.reset}
192
+ ${C.green}--version, -v${C.reset} ${C.gray}// show current Nexa CLI version${C.reset}
193
+ ${C.green}--help, -h${C.reset} ${C.gray}// show help information${C.reset}
189
194
 
190
- ${C.bold}${C.magenta || C.blue}Examples${C.reset}
195
+ ${C.bold}${C.blue}Examples${C.reset}
191
196
 
197
+ ${C.gray}npx create-nexa-app my-app${C.reset}
198
+ ${C.gray}npx create-nexa-app my-app --base /portal/${C.reset}
192
199
  ${C.gray}nexa new app conscious-neurons${C.reset}
193
200
  ${C.gray}nexa new conscious-neurons${C.reset}
194
201
  ${C.gray}nexa new gc video-card${C.reset}
195
202
  ${C.gray}nexa new svc auth-service${C.reset}
196
203
  ${C.gray}nexa new ctx user-session${C.reset}
204
+ ${C.gray}nexa --version${C.reset}
197
205
  `);
198
206
  }
199
207
  /**
@@ -245,7 +253,7 @@ function openBrowser(url) {
245
253
  /**
246
254
  * Purpose: Start the generated app in dev mode.
247
255
  */
248
- function startGeneratedApp(projectDir, shouldOpenBrowser) {
256
+ function startGeneratedApp(projectDir, shouldOpenBrowser, appBase = "/") {
249
257
  const command = os.platform() === "win32" ? "npm.cmd" : "npm";
250
258
 
251
259
  const devProcess = spawn(command, ["run", "dev"], {
@@ -256,7 +264,7 @@ function startGeneratedApp(projectDir, shouldOpenBrowser) {
256
264
 
257
265
  if (shouldOpenBrowser) {
258
266
  setTimeout(() => {
259
- openBrowser("http://localhost:5725");
267
+ openBrowser(`http://localhost:5725${appBase}`);
260
268
  }, 2500);
261
269
  }
262
270
 
@@ -703,7 +711,7 @@ ${C.gray}<Route path="${routePath}" element={<${finalName} />} />${C.reset}
703
711
  * Purpose: Create a full app scaffold from the template folder and then
704
712
  * patch key files with the correct app-specific values.
705
713
  */
706
- async function createApp(rawAppName) {
714
+ async function createApp(rawAppName, appBase = "/") {
707
715
  const projectDirName = toKebabCase(rawAppName);
708
716
  const displayName = toPascalCase(rawAppName);
709
717
  const packageName = toKebabCase(rawAppName);
@@ -711,6 +719,7 @@ async function createApp(rawAppName) {
711
719
  const root = process.cwd();
712
720
  const projectDir = path.join(root, projectDirName);
713
721
  const templateDir = path.join(__dirname, "../template");
722
+ const APP_BASE = normalizeBase(appBase);
714
723
 
715
724
  if (!rawAppName) {
716
725
  console.error(`${C.yellow}❌ Please provide an app name.${C.reset}`);
@@ -805,6 +814,21 @@ coverage/
805
814
  const templateIndex = fs.readFileSync(publicIndexPath, "utf8");
806
815
  const patchedIndex = templateIndex
807
816
  .replace(/<title>.*?<\/title>/i, `<title>Nexa • ${displayName}</title>`)
817
+ .replace(
818
+ /href=["']\.\/manifest\.json["']/i,
819
+ `href="${APP_BASE}manifest.json"`,
820
+ )
821
+ .replace(
822
+ /href=["']\/manifest\.json["']/i,
823
+ `href="${APP_BASE}manifest.json"`,
824
+ )
825
+ .replace(
826
+ /href=["']\.\/favicon\.png["']/i,
827
+ `href="${APP_BASE}favicon.png"`,
828
+ )
829
+ .replace(/href=["']\/favicon\.png["']/i, `href="${APP_BASE}favicon.png"`)
830
+ .replace(/href=["']\.\/nexa\.svg["']/i, `href="${APP_BASE}nexa.svg"`)
831
+ .replace(/href=["']\/nexa\.svg["']/i, `href="${APP_BASE}nexa.svg"`)
808
832
  .replace(/src=["']\.\/src\/main\.jsx["']/i, 'src="/src/main.jsx"')
809
833
  .replace(/src=["']src\/main\.jsx["']/i, 'src="/src/main.jsx"');
810
834
 
@@ -821,10 +845,10 @@ coverage/
821
845
 
822
846
  <!-- PWA -->
823
847
  <meta name="theme-color" content="#3ee7ff" />
824
- <link rel="manifest" href="/manifest.json" />
848
+ <link rel="manifest" href="${APP_BASE}manifest.json" />
825
849
 
826
850
  <!-- Icons -->
827
- <link rel="icon" type="image/png" href="/favicon.png" />
851
+ <link rel="icon" type="image/png" href="${APP_BASE}favicon.png" />
828
852
 
829
853
  <!-- Title -->
830
854
  <title>Nexa • by Conscious Neurons</title>
@@ -843,25 +867,26 @@ coverage/
843
867
  const manifestContent = `{
844
868
  "name": "Nexa App",
845
869
  "short_name": "Nexa",
846
- "start_url": "/",
870
+ "start_url": "${APP_BASE}",
871
+ "scope": "${APP_BASE}",
847
872
  "display": "standalone",
848
873
  "background_color": "#07111f",
849
874
  "theme_color": "#3ee7ff",
850
875
  "icons": [
851
876
  {
852
- "src": "/icons/icon-192.png",
877
+ "src": "${APP_BASE}icons/icon-192.png",
853
878
  "sizes": "192x192",
854
879
  "type": "image/png",
855
880
  "purpose": "any maskable"
856
881
  },
857
882
  {
858
- "src": "/icons/icon-512.png",
883
+ "src": "${APP_BASE}icons/icon-512.png",
859
884
  "sizes": "512x512",
860
885
  "type": "image/png",
861
886
  "purpose": "any maskable"
862
887
  },
863
888
  {
864
- "src": "/nexa.svg",
889
+ "src": "${APP_BASE}nexa.svg",
865
890
  "sizes": "any",
866
891
  "type": "image/svg+xml",
867
892
  "purpose": "any"
@@ -900,25 +925,37 @@ coverage/
900
925
  );
901
926
 
902
927
  const mainJsxPath = path.join(srcDir, "main.jsx");
903
- if (!fs.existsSync(mainJsxPath)) {
904
- const mainJsxContent = `/**
905
- * File: src/main.jsx
906
- * Purpose: Entry point for the React application. Mounts App into the root DOM node.
907
- */
908
-
909
- import React from "react";
928
+ const mainJsxContent = `import React from "react";
910
929
  import ReactDOM from "react-dom/client";
911
930
  import App from "./App.jsx";
912
931
  import "./index.css";
932
+ import { BrowserRouter } from "react-router-dom";
933
+
934
+ const APP_BASE = "${APP_BASE}";
935
+
936
+ if ("serviceWorker" in navigator) {
937
+ window.addEventListener("load", () => {
938
+ navigator.serviceWorker
939
+ .register(\`\${APP_BASE}sw.js\`)
940
+ .then((registration) => {
941
+ console.log("✅ Service Worker registered:", registration);
942
+ })
943
+ .catch((error) => {
944
+ console.error("❌ Service Worker registration failed:", error);
945
+ });
946
+ });
947
+ }
913
948
 
914
949
  ReactDOM.createRoot(document.getElementById("root")).render(
915
950
  <React.StrictMode>
916
- <App />
951
+ <BrowserRouter basename={APP_BASE === "/" ? undefined : APP_BASE}>
952
+ <App />
953
+ </BrowserRouter>
917
954
  </React.StrictMode>
918
955
  );
919
956
  `;
920
- writeFileSafe(mainJsxPath, mainJsxContent);
921
- }
957
+
958
+ writeFileSafe(mainJsxPath, mainJsxContent);
922
959
 
923
960
  const appJsxPath = path.join(srcDir, "App.jsx");
924
961
  if (!fs.existsSync(appJsxPath)) {
@@ -1084,8 +1121,7 @@ vite.on("close", (code) => {
1084
1121
  }
1085
1122
 
1086
1123
  const nexaConfigPath = path.join(projectDir, "nexa.config.js");
1087
- if (!fs.existsSync(nexaConfigPath)) {
1088
- const nexaConfigContent = `/**
1124
+ const nexaConfigContent = `/**
1089
1125
  * File: nexa.config.js
1090
1126
  * Purpose: Vite configuration for Nexa-generated apps.
1091
1127
  */
@@ -1095,20 +1131,20 @@ import react from "@vitejs/plugin-react";
1095
1131
 
1096
1132
  export default defineConfig({
1097
1133
  root: ".",
1098
- base: "/",
1134
+ base: "${APP_BASE}",
1099
1135
  plugins: [react()],
1100
1136
  server: {
1101
1137
  port: 5725,
1102
1138
  },
1103
1139
  build: {
1104
1140
  outDir: "dist",
1141
+ emptyOutDir: true,
1105
1142
  },
1106
1143
  clearScreen: false,
1107
1144
  });
1108
1145
  `;
1109
- writeFileSafe(nexaConfigPath, nexaConfigContent);
1110
- }
1111
1146
 
1147
+ writeFileSafe(nexaConfigPath, nexaConfigContent);
1112
1148
  console.log(`\n${C.blue}📦 Installing dependencies...${C.reset}`);
1113
1149
  let installSucceeded = false;
1114
1150
 
@@ -1146,11 +1182,28 @@ export default defineConfig({
1146
1182
  console.log(
1147
1183
  `\n${C.green}▶️ Starting app in ${projectDirName}...${C.reset}\n`,
1148
1184
  );
1149
- startGeneratedApp(projectDir, shouldOpen);
1185
+ startGeneratedApp(projectDir, shouldOpen, APP_BASE);
1150
1186
  }
1151
1187
  }
1152
1188
  }
1153
1189
 
1190
+ function normalizeBase(input = "/") {
1191
+ let base = String(input).trim();
1192
+
1193
+ if (!base) return "/";
1194
+
1195
+ if (!base.startsWith("/")) base = `/${base}`;
1196
+ if (!base.endsWith("/")) base = `${base}/`;
1197
+
1198
+ return base.replace(/\/+/g, "/");
1199
+ }
1200
+
1201
+ function getFlagValue(argv, flagName) {
1202
+ const index = argv.indexOf(flagName);
1203
+ if (index === -1) return null;
1204
+ return argv[index + 1] ?? null;
1205
+ }
1206
+
1154
1207
  /**
1155
1208
  * Purpose: Parse command arguments and support:
1156
1209
  * nexa new app my-app
@@ -1158,9 +1211,21 @@ export default defineConfig({
1158
1211
  * nexa app my-app
1159
1212
  */
1160
1213
  function parseArgs(argv) {
1161
- const first = argv[0];
1162
- const second = argv[1];
1163
- const third = argv[2];
1214
+ const baseFlagValue = getFlagValue(argv, "--base");
1215
+ const base = normalizeBase(baseFlagValue || "/");
1216
+
1217
+ const filtered = [];
1218
+ for (let i = 0; i < argv.length; i++) {
1219
+ if (argv[i] === "--base") {
1220
+ i++;
1221
+ continue;
1222
+ }
1223
+ filtered.push(argv[i]);
1224
+ }
1225
+
1226
+ const first = filtered[0];
1227
+ const second = filtered[1];
1228
+ const third = filtered[2];
1164
1229
 
1165
1230
  if (!first) {
1166
1231
  printUsage();
@@ -1181,6 +1246,7 @@ function parseArgs(argv) {
1181
1246
  return {
1182
1247
  shortcut: second,
1183
1248
  name: third,
1249
+ base,
1184
1250
  };
1185
1251
  }
1186
1252
 
@@ -1192,6 +1258,7 @@ function parseArgs(argv) {
1192
1258
  return {
1193
1259
  shortcut: "app",
1194
1260
  name: second,
1261
+ base,
1195
1262
  };
1196
1263
  }
1197
1264
 
@@ -1199,6 +1266,7 @@ function parseArgs(argv) {
1199
1266
  return {
1200
1267
  shortcut: first,
1201
1268
  name: second,
1269
+ base,
1202
1270
  };
1203
1271
  }
1204
1272
 
@@ -1223,6 +1291,7 @@ function parseArgs(argv) {
1223
1291
  return {
1224
1292
  shortcut: "app",
1225
1293
  name: first,
1294
+ base,
1226
1295
  };
1227
1296
  }
1228
1297
 
@@ -1230,7 +1299,7 @@ function parseArgs(argv) {
1230
1299
  process.exit(1);
1231
1300
  }
1232
1301
 
1233
- const { shortcut, name } = parseArgs(args);
1302
+ const { shortcut, name, base } = parseArgs(args);
1234
1303
 
1235
1304
  async function main() {
1236
1305
  switch (shortcut) {
@@ -1266,7 +1335,7 @@ async function main() {
1266
1335
  console.error(`${C.yellow}❌ Please provide an app name.${C.reset}`);
1267
1336
  process.exit(1);
1268
1337
  }
1269
- await createApp(name);
1338
+ await createApp(name, base);
1270
1339
  break;
1271
1340
 
1272
1341
  default:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-nexa-app",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "Create a new Nexa app with prebuilt structure, PWA support, and modern React/Vite setup",
5
5
  "bin": {
6
6
  "create-nexa-app": "bin/nexa.js",