create-nexa-app 1.0.11 → 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 +187 -88
  2. package/package.json +1 -1
package/bin/nexa.js CHANGED
@@ -202,7 +202,10 @@ ${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
- ${C.gray}nexa doctor${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}
206
209
 
207
210
 
208
211
  `);
@@ -1197,117 +1200,196 @@ function getFlagValue(argv, flagName) {
1197
1200
  return argv[index + 1] ?? null;
1198
1201
  }
1199
1202
 
1200
- /**
1201
- * Purpose: Parse command arguments and support:
1202
- * nexa new app my-app
1203
- * nexa new my-app
1204
- * nexa app my-app
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.
1205
1243
  */
1206
- function parseArgs(argv) {
1207
- const baseFlagValue = getFlagValue(argv, "--base");
1208
- const base = normalizeBase(baseFlagValue || "/");
1209
1244
 
1210
- const filtered = [];
1211
- for (let i = 0; i < argv.length; i++) {
1212
- if (argv[i] === "--base") {
1213
- i++;
1214
- continue;
1215
- }
1216
- filtered.push(argv[i]);
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}`);
1217
1272
  }
1218
1273
 
1219
- /** Runs the doctor in the cli */
1220
- function runDoctor() {
1221
- console.log(`\n${C.cyan}${C.bold}🩺 Nexa Doctor${C.reset}\n`);
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
+ }
1222
1280
 
1223
- // Node
1224
- try {
1225
- const nodeVersion = process.version;
1226
- console.log(`${C.green} Node:${C.reset} ${nodeVersion}`);
1227
- } catch {
1228
- console.log(`${C.red}✖ Node not found${C.reset}`);
1229
- }
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
+ }
1230
1286
 
1231
- // npm
1232
- try {
1233
- const npmVersion = execSync("npm -v").toString().trim();
1234
- console.log(`${C.green}✔ npm:${C.reset} ${npmVersion}`);
1235
- } catch {
1236
- console.log(`${C.red}✖ npm not found${C.reset}`);
1237
- }
1287
+ const cwd = process.cwd();
1238
1288
 
1239
- // CLI version
1240
- try {
1241
- const pkg = JSON.parse(
1242
- fs.readFileSync(path.join(__dirname, "../package.json"), "utf8"),
1243
- );
1244
- console.log(`${C.green}✔ Nexa CLI:${C.reset} v${pkg.version}`);
1245
- } catch {
1246
- console.log(`${C.yellow}⚠ Could not read CLI version${C.reset}`);
1247
- }
1289
+ console.log(`\n${C.cyan}Project Checks:${C.reset}\n`);
1248
1290
 
1249
- const cwd = process.cwd();
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");
1250
1297
 
1251
- console.log(`\n${C.cyan}Project Checks:${C.reset}\n`);
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
+ }
1252
1303
 
1253
- // package.json
1254
- if (fs.existsSync(path.join(cwd, "package.json"))) {
1255
- console.log(`${C.green} package.json found${C.reset}`);
1256
- } else {
1257
- console.log(`${C.red}✖ package.json missing${C.reset}`);
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
+ }
1258
1316
  }
1317
+ }
1259
1318
 
1260
- // node_modules
1261
- if (fs.existsSync(path.join(cwd, "node_modules"))) {
1262
- console.log(`${C.green} node_modules installed${C.reset}`);
1263
- } else {
1264
- console.log(
1265
- `${C.yellow}⚠ node_modules missing (run npm install)${C.reset}`,
1266
- );
1267
- }
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
+ }
1268
1324
 
1269
- // src
1270
- if (fs.existsSync(path.join(cwd, "src"))) {
1271
- console.log(`${C.green} src folder found${C.reset}`);
1272
- } else {
1273
- console.log(`${C.red}✖ src folder missing${C.reset}`);
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
+ }
1274
1337
  }
1338
+ }
1275
1339
 
1276
- // nexa.config.js
1277
- if (fs.existsSync(path.join(cwd, "nexa.config.js"))) {
1278
- console.log(`${C.green} nexa.config.js found${C.reset}`);
1279
- } else {
1280
- console.log(`${C.yellow}⚠ nexa.config.js missing${C.reset}`);
1281
- }
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
+ }
1282
1345
 
1283
- // index.html
1284
- if (fs.existsSync(path.join(cwd, "index.html"))) {
1285
- console.log(`${C.green} index.html found${C.reset}`);
1286
- } else {
1287
- console.log(`${C.red}✖ index.html missing${C.reset}`);
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
+ }
1288
1358
  }
1359
+ }
1289
1360
 
1290
- // manifest
1291
- if (fs.existsSync(path.join(cwd, "public", "manifest.json"))) {
1292
- console.log(`${C.green}✔ manifest.json found${C.reset}`);
1293
- } else {
1294
- console.log(`${C.yellow}⚠ manifest.json missing${C.reset}`);
1295
- }
1361
+ console.log(`\n${C.green}${C.bold}Doctor check complete ✔${C.reset}\n`);
1362
+ }
1363
+ /**
1364
+ * Purpose: Parse command arguments and support:
1365
+ * nexa new app my-app
1366
+ * nexa new my-app
1367
+ * nexa app my-app
1368
+ */
1369
+ function parseArgs(argv) {
1370
+ const baseFlagValue = getFlagValue(argv, "--base");
1371
+ const base = normalizeBase(baseFlagValue || "/");
1372
+ const fix = argv.includes("--fix");
1296
1373
 
1297
- console.log(`\n${C.green}${C.bold}Doctor check complete ✔${C.reset}\n`);
1374
+ const filtered = [];
1375
+ for (let i = 0; i < argv.length; i++) {
1376
+ if (argv[i] === "--base") {
1377
+ i++;
1378
+ continue;
1379
+ }
1380
+ if (argv[i] === "--fix") {
1381
+ continue;
1382
+ }
1383
+ filtered.push(argv[i]);
1298
1384
  }
1299
1385
 
1300
1386
  const first = filtered[0];
1301
1387
  const second = filtered[1];
1302
1388
  const third = filtered[2];
1303
1389
 
1304
- if (first === "doctor") {
1305
- runDoctor();
1306
- process.exit(0);
1307
- }
1308
- if (first === "doctor") {
1309
- runDoctor();
1310
- return;
1390
+ if (!first) {
1391
+ printUsage();
1392
+ process.exit(1);
1311
1393
  }
1312
1394
 
1313
1395
  if (first === "help" || first === "--help" || first === "-h") {
@@ -1315,6 +1397,14 @@ function parseArgs(argv) {
1315
1397
  process.exit(0);
1316
1398
  }
1317
1399
 
1400
+ if (first === "doctor") {
1401
+ return {
1402
+ shortcut: "doctor",
1403
+ fix,
1404
+ base,
1405
+ };
1406
+ }
1407
+
1318
1408
  if (first === "version" || first === "--version" || first === "-v") {
1319
1409
  console.log(`Nexa CLI v${pkg.version}`);
1320
1410
  process.exit(0);
@@ -1325,6 +1415,7 @@ function parseArgs(argv) {
1325
1415
  shortcut: second,
1326
1416
  name: third,
1327
1417
  base,
1418
+ fix,
1328
1419
  };
1329
1420
  }
1330
1421
 
@@ -1337,6 +1428,7 @@ function parseArgs(argv) {
1337
1428
  shortcut: "app",
1338
1429
  name: second,
1339
1430
  base,
1431
+ fix,
1340
1432
  };
1341
1433
  }
1342
1434
 
@@ -1345,6 +1437,7 @@ function parseArgs(argv) {
1345
1437
  shortcut: first,
1346
1438
  name: second,
1347
1439
  base,
1440
+ fix,
1348
1441
  };
1349
1442
  }
1350
1443
 
@@ -1358,6 +1451,7 @@ function parseArgs(argv) {
1358
1451
  "cc",
1359
1452
  "svc",
1360
1453
  "ctx",
1454
+ "doctor",
1361
1455
  "help",
1362
1456
  "--help",
1363
1457
  "-h",
@@ -1370,6 +1464,7 @@ function parseArgs(argv) {
1370
1464
  shortcut: "app",
1371
1465
  name: first,
1372
1466
  base,
1467
+ fix,
1373
1468
  };
1374
1469
  }
1375
1470
 
@@ -1377,7 +1472,7 @@ function parseArgs(argv) {
1377
1472
  process.exit(1);
1378
1473
  }
1379
1474
 
1380
- const { shortcut, name, base } = parseArgs(args);
1475
+ const { shortcut, name, base, fix } = parseArgs(args);
1381
1476
 
1382
1477
  async function main() {
1383
1478
  switch (shortcut) {
@@ -1416,6 +1511,10 @@ async function main() {
1416
1511
  await createApp(name, base);
1417
1512
  break;
1418
1513
 
1514
+ case "doctor":
1515
+ runDoctor({ fix });
1516
+ break;
1517
+
1419
1518
  default:
1420
1519
  console.error(`${C.yellow}❌ Unknown shortcut.${C.reset}`);
1421
1520
  printUsage();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-nexa-app",
3
- "version": "1.0.11",
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",