create-nexa-app 1.0.10 → 1.0.12

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 (2) hide show
  1. package/bin/nexa.js +188 -1
  2. package/package.json +1 -1
package/bin/nexa.js CHANGED
@@ -202,6 +202,12 @@ ${C.bold}${C.blue}Examples${C.reset}
202
202
  ${C.gray}nexa new svc auth-service${C.reset}
203
203
  ${C.gray}nexa new ctx user-session${C.reset}
204
204
  ${C.gray}nexa --version${C.reset}
205
+
206
+ ${C.green}nexa doctor${C.reset}
207
+ ${C.green}nexa doctor --fix${C.reset}
208
+ ${C.green}--fix${C.reset} ${C.gray}// auto-fix safe issues in doctor${C.reset}
209
+
210
+
205
211
  `);
206
212
  }
207
213
  /**
@@ -1194,6 +1200,166 @@ function getFlagValue(argv, flagName) {
1194
1200
  return argv[index + 1] ?? null;
1195
1201
  }
1196
1202
 
1203
+ function createDefaultManifest(cwd) {
1204
+ const manifestPath = path.join(cwd, "public", "manifest.json");
1205
+ const manifestContent = `{
1206
+ "name": "Nexa App",
1207
+ "short_name": "Nexa",
1208
+ "start_url": "./",
1209
+ "scope": "./",
1210
+ "display": "standalone",
1211
+ "background_color": "#07111f",
1212
+ "theme_color": "#3ee7ff",
1213
+ "icons": [
1214
+ {
1215
+ "src": "./icons/icon-192.png",
1216
+ "sizes": "192x192",
1217
+ "type": "image/png",
1218
+ "purpose": "any maskable"
1219
+ },
1220
+ {
1221
+ "src": "./icons/icon-512.png",
1222
+ "sizes": "512x512",
1223
+ "type": "image/png",
1224
+ "purpose": "any maskable"
1225
+ },
1226
+ {
1227
+ "src": "./nexa.svg",
1228
+ "sizes": "any",
1229
+ "type": "image/svg+xml",
1230
+ "purpose": "any"
1231
+ }
1232
+ ]
1233
+ }
1234
+ `;
1235
+ writeFileSafe(manifestPath, manifestContent);
1236
+ }
1237
+
1238
+ function createDefaultNexaConfig(cwd) {
1239
+ const configPath = path.join(cwd, "nexa.config.js");
1240
+ const configContent = `/**
1241
+ * File: nexa.config.js
1242
+ * Purpose: Vite configuration for Nexa-generated apps.
1243
+ */
1244
+
1245
+ import { defineConfig } from "vite";
1246
+ import react from "@vitejs/plugin-react";
1247
+
1248
+ export default defineConfig({
1249
+ root: ".",
1250
+ base: "/",
1251
+ plugins: [react()],
1252
+ server: {
1253
+ port: 5725,
1254
+ },
1255
+ build: {
1256
+ outDir: "dist",
1257
+ emptyOutDir: true,
1258
+ },
1259
+ clearScreen: false,
1260
+ });
1261
+ `;
1262
+ writeFileSafe(configPath, configContent);
1263
+ }
1264
+ /** Runs the doctor in the cli */
1265
+ function runDoctor({ fix = false } = {}) {
1266
+ console.log(`\n${C.cyan}${C.bold}🩺 Nexa Doctor${C.reset}\n`);
1267
+
1268
+ try {
1269
+ console.log(`${C.green}✔ Node:${C.reset} ${process.version}`);
1270
+ } catch {
1271
+ console.log(`${C.yellow}⚠ Could not detect Node version${C.reset}`);
1272
+ }
1273
+
1274
+ try {
1275
+ const npmVersion = execSync("npm -v").toString().trim();
1276
+ console.log(`${C.green}✔ npm:${C.reset} ${npmVersion}`);
1277
+ } catch {
1278
+ console.log(`${C.yellow}⚠ Could not detect npm version${C.reset}`);
1279
+ }
1280
+
1281
+ try {
1282
+ console.log(`${C.green}✔ Nexa CLI:${C.reset} v${pkg.version}`);
1283
+ } catch {
1284
+ console.log(`${C.yellow}⚠ Could not read CLI version${C.reset}`);
1285
+ }
1286
+
1287
+ const cwd = process.cwd();
1288
+
1289
+ console.log(`\n${C.cyan}Project Checks:${C.reset}\n`);
1290
+
1291
+ const packageJsonPath = path.join(cwd, "package.json");
1292
+ const nodeModulesPath = path.join(cwd, "node_modules");
1293
+ const srcPath = path.join(cwd, "src");
1294
+ const nexaConfigPath = path.join(cwd, "nexa.config.js");
1295
+ const indexHtmlPath = path.join(cwd, "index.html");
1296
+ const manifestPath = path.join(cwd, "public", "manifest.json");
1297
+
1298
+ if (fs.existsSync(packageJsonPath)) {
1299
+ console.log(`${C.green}✔ package.json found${C.reset}`);
1300
+ } else {
1301
+ console.log(`${C.yellow}⚠ package.json missing${C.reset}`);
1302
+ }
1303
+
1304
+ if (fs.existsSync(nodeModulesPath)) {
1305
+ console.log(`${C.green}✔ node_modules installed${C.reset}`);
1306
+ } else {
1307
+ console.log(`${C.yellow}⚠ node_modules missing${C.reset}`);
1308
+ if (fix && fs.existsSync(packageJsonPath)) {
1309
+ try {
1310
+ console.log(`${C.blue}🔧 Running npm install...${C.reset}`);
1311
+ execSync("npm install", { stdio: "inherit", cwd });
1312
+ console.log(`${C.green}✔ node_modules installed${C.reset}`);
1313
+ } catch {
1314
+ console.log(`${C.yellow}⚠ Failed to install dependencies${C.reset}`);
1315
+ }
1316
+ }
1317
+ }
1318
+
1319
+ if (fs.existsSync(srcPath)) {
1320
+ console.log(`${C.green}✔ src folder found${C.reset}`);
1321
+ } else {
1322
+ console.log(`${C.yellow}⚠ src folder missing${C.reset}`);
1323
+ }
1324
+
1325
+ if (fs.existsSync(nexaConfigPath)) {
1326
+ console.log(`${C.green}✔ nexa.config.js found${C.reset}`);
1327
+ } else {
1328
+ console.log(`${C.yellow}⚠ nexa.config.js missing${C.reset}`);
1329
+ if (fix) {
1330
+ try {
1331
+ console.log(`${C.blue}🔧 Creating nexa.config.js...${C.reset}`);
1332
+ createDefaultNexaConfig(cwd);
1333
+ console.log(`${C.green}✔ nexa.config.js created${C.reset}`);
1334
+ } catch {
1335
+ console.log(`${C.yellow}⚠ Failed to create nexa.config.js${C.reset}`);
1336
+ }
1337
+ }
1338
+ }
1339
+
1340
+ if (fs.existsSync(indexHtmlPath)) {
1341
+ console.log(`${C.green}✔ index.html found${C.reset}`);
1342
+ } else {
1343
+ console.log(`${C.yellow}⚠ index.html missing${C.reset}`);
1344
+ }
1345
+
1346
+ if (fs.existsSync(manifestPath)) {
1347
+ console.log(`${C.green}✔ manifest.json found${C.reset}`);
1348
+ } else {
1349
+ console.log(`${C.yellow}⚠ manifest.json missing${C.reset}`);
1350
+ if (fix) {
1351
+ try {
1352
+ console.log(`${C.blue}🔧 Creating manifest.json...${C.reset}`);
1353
+ createDefaultManifest(cwd);
1354
+ console.log(`${C.green}✔ manifest.json created${C.reset}`);
1355
+ } catch {
1356
+ console.log(`${C.yellow}⚠ Failed to create manifest.json${C.reset}`);
1357
+ }
1358
+ }
1359
+ }
1360
+
1361
+ console.log(`\n${C.green}${C.bold}Doctor check complete ✔${C.reset}\n`);
1362
+ }
1197
1363
  /**
1198
1364
  * Purpose: Parse command arguments and support:
1199
1365
  * nexa new app my-app
@@ -1203,6 +1369,7 @@ function getFlagValue(argv, flagName) {
1203
1369
  function parseArgs(argv) {
1204
1370
  const baseFlagValue = getFlagValue(argv, "--base");
1205
1371
  const base = normalizeBase(baseFlagValue || "/");
1372
+ const fix = argv.includes("--fix");
1206
1373
 
1207
1374
  const filtered = [];
1208
1375
  for (let i = 0; i < argv.length; i++) {
@@ -1210,6 +1377,9 @@ function parseArgs(argv) {
1210
1377
  i++;
1211
1378
  continue;
1212
1379
  }
1380
+ if (argv[i] === "--fix") {
1381
+ continue;
1382
+ }
1213
1383
  filtered.push(argv[i]);
1214
1384
  }
1215
1385
 
@@ -1227,6 +1397,14 @@ function parseArgs(argv) {
1227
1397
  process.exit(0);
1228
1398
  }
1229
1399
 
1400
+ if (first === "doctor") {
1401
+ return {
1402
+ shortcut: "doctor",
1403
+ fix,
1404
+ base,
1405
+ };
1406
+ }
1407
+
1230
1408
  if (first === "version" || first === "--version" || first === "-v") {
1231
1409
  console.log(`Nexa CLI v${pkg.version}`);
1232
1410
  process.exit(0);
@@ -1237,6 +1415,7 @@ function parseArgs(argv) {
1237
1415
  shortcut: second,
1238
1416
  name: third,
1239
1417
  base,
1418
+ fix,
1240
1419
  };
1241
1420
  }
1242
1421
 
@@ -1249,6 +1428,7 @@ function parseArgs(argv) {
1249
1428
  shortcut: "app",
1250
1429
  name: second,
1251
1430
  base,
1431
+ fix,
1252
1432
  };
1253
1433
  }
1254
1434
 
@@ -1257,6 +1437,7 @@ function parseArgs(argv) {
1257
1437
  shortcut: first,
1258
1438
  name: second,
1259
1439
  base,
1440
+ fix,
1260
1441
  };
1261
1442
  }
1262
1443
 
@@ -1270,6 +1451,7 @@ function parseArgs(argv) {
1270
1451
  "cc",
1271
1452
  "svc",
1272
1453
  "ctx",
1454
+ "doctor",
1273
1455
  "help",
1274
1456
  "--help",
1275
1457
  "-h",
@@ -1282,6 +1464,7 @@ function parseArgs(argv) {
1282
1464
  shortcut: "app",
1283
1465
  name: first,
1284
1466
  base,
1467
+ fix,
1285
1468
  };
1286
1469
  }
1287
1470
 
@@ -1289,7 +1472,7 @@ function parseArgs(argv) {
1289
1472
  process.exit(1);
1290
1473
  }
1291
1474
 
1292
- const { shortcut, name, base } = parseArgs(args);
1475
+ const { shortcut, name, base, fix } = parseArgs(args);
1293
1476
 
1294
1477
  async function main() {
1295
1478
  switch (shortcut) {
@@ -1328,6 +1511,10 @@ async function main() {
1328
1511
  await createApp(name, base);
1329
1512
  break;
1330
1513
 
1514
+ case "doctor":
1515
+ runDoctor({ fix });
1516
+ break;
1517
+
1331
1518
  default:
1332
1519
  console.error(`${C.yellow}❌ Unknown shortcut.${C.reset}`);
1333
1520
  printUsage();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-nexa-app",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
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",