@nexusts/cli 0.8.2 → 0.8.4

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/dist/index.js CHANGED
@@ -19,7 +19,7 @@ var __toESM = (mod, isNodeMode, target) => {
19
19
  var __require = import.meta.require;
20
20
 
21
21
  // packages/cli/src/commands/info.ts
22
- import { resolve as resolve4 } from "path";
22
+ import { resolve as resolve5 } from "path";
23
23
 
24
24
  // packages/cli/src/core/args.ts
25
25
  var LONG_RE = /^--([^=]+)(?:=(.*))?$/;
@@ -511,67 +511,9 @@ function loadVersion() {
511
511
  }
512
512
  }
513
513
  var VERSION = loadVersion();
514
- // packages/cli/src/commands/info.ts
515
- var infoCommand = {
516
- name: "info",
517
- aliases: ["i"],
518
- summary: "Show project configuration",
519
- description: "Prints the resolved nx.config.ts plus relevant env vars.",
520
- async run(ctx) {
521
- logger.heading("NexusTS CLI \u2014 Project Info");
522
- logger.info(colors.bold("Resolved configuration"));
523
- logger.blank();
524
- logger.table([
525
- ["routing", String(ctx.config.routing)],
526
- ["view", String(ctx.config.view)],
527
- ["orm", String(ctx.config.orm)],
528
- ["dialect", String(ctx.config.dialect ?? "(none)")],
529
- ["database.driver", String(ctx.config.database.driver)],
530
- ["database.url", String(ctx.config.database.url)],
531
- ["inertia.frontend", String(ctx.config.inertia.frontend)],
532
- ["inertia.ssr", String(ctx.config.inertia.ssr)],
533
- ["inertia.version", String(ctx.config.inertia.version)]
534
- ]);
535
- logger.blank();
536
- logger.info(colors.bold("Paths"));
537
- logger.blank();
538
- for (const [k, v] of Object.entries(ctx.config.paths)) {
539
- logger.table([[k, v]]);
540
- }
541
- logger.blank();
542
- logger.info(colors.bold("Environment"));
543
- logger.blank();
544
- const envKeys = [
545
- "NODE_ENV",
546
- "PORT",
547
- "NEXUS_DEBUG",
548
- "NO_COLOR",
549
- "FORCE_COLOR",
550
- "NX_ROUTING",
551
- "NX_VIEW",
552
- "NX_ORM",
553
- "NX_DATABASE_DRIVER",
554
- "NX_DATABASE_URL",
555
- "NX_INERTIA_FRONTEND",
556
- "NX_INERTIA_SSR"
557
- ];
558
- for (const k of envKeys) {
559
- const v = process.env[k];
560
- logger.table([[k, v === undefined ? colors.dim("(unset)") : v]]);
561
- }
562
- logger.blank();
563
- logger.info(colors.bold("Working directory"));
564
- logger.blank();
565
- logger.info(` ${resolve4(ctx.cwd)}`);
566
- logger.blank();
567
- return 0;
568
- }
569
- };
570
- var info_default = infoCommand;
571
-
572
- // packages/cli/src/commands/init.ts
573
- import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
574
- import { resolve as resolve5 } from "path";
514
+ // packages/cli/src/core/scaffold.ts
515
+ import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
516
+ import { resolve as resolve4 } from "path";
575
517
 
576
518
  // packages/cli/src/templates/controller/adonis.ts
577
519
  var adonis_default = `
@@ -1164,140 +1106,508 @@ var templates = {
1164
1106
  }
1165
1107
  };
1166
1108
 
1109
+ // packages/cli/src/core/scaffold.ts
1110
+ function ensureDirectories(target, view) {
1111
+ mkdirSync2(resolve4(target, "app/controllers"), { recursive: true });
1112
+ mkdirSync2(resolve4(target, "app/modules"), { recursive: true });
1113
+ mkdirSync2(resolve4(target, "app/services"), { recursive: true });
1114
+ mkdirSync2(resolve4(target, "app/models"), { recursive: true });
1115
+ mkdirSync2(resolve4(target, "app/repositories"), { recursive: true });
1116
+ mkdirSync2(resolve4(target, "app/dto"), { recursive: true });
1117
+ mkdirSync2(resolve4(target, "public"), { recursive: true });
1118
+ if (view === "inertia") {
1119
+ mkdirSync2(resolve4(target, "resources/js/Pages"), { recursive: true });
1120
+ } else if (view !== "none") {
1121
+ mkdirSync2(resolve4(target, "resources/views"), { recursive: true });
1122
+ }
1123
+ }
1124
+ function computeDeps(view, orm, db, frontend) {
1125
+ const deps = {
1126
+ "@nexusts/core": "*",
1127
+ "reflect-metadata": "^0.2.2",
1128
+ hono: "^4.6.0",
1129
+ zod: "^3.23.8"
1130
+ };
1131
+ const devDeps = {};
1132
+ if (orm === "drizzle") {
1133
+ deps["@nexusts/drizzle"] = "*";
1134
+ deps["drizzle-orm"] = "^0.45.0";
1135
+ if (db === "postgres")
1136
+ deps["pg"] = "^8.13.0";
1137
+ if (db === "mysql")
1138
+ deps["mysql2"] = "^3.11.0";
1139
+ if (db === "sqlite" || db === "node-sqlite" || db === "bun-sqlite")
1140
+ deps["better-sqlite3"] = "^12.0.0";
1141
+ devDeps["drizzle-kit"] = "^0.31.0";
1142
+ }
1143
+ if (view !== "none") {
1144
+ deps["@nexusts/static"] = "*";
1145
+ }
1146
+ deps["@nexusts/view"] = "*";
1147
+ if (view === "inertia") {
1148
+ if (frontend === "vue") {
1149
+ deps["@inertiajs/vue3"] = "^3.0.0";
1150
+ deps["vue"] = "^3.5.0";
1151
+ } else {
1152
+ deps["@inertiajs/react"] = "^3.0.0";
1153
+ deps["react"] = "^19.0.0";
1154
+ deps["react-dom"] = "^19.0.0";
1155
+ }
1156
+ }
1157
+ return { deps, devDeps };
1158
+ }
1159
+ function buildPackageJson(name, deps, devDeps, view, frontend) {
1160
+ const scripts = {
1161
+ dev: "bun --hot app/main.ts",
1162
+ build: "bun run build.ts",
1163
+ start: "bun app/main.ts",
1164
+ test: "vitest",
1165
+ nx: "nx"
1166
+ };
1167
+ if (view === "inertia") {
1168
+ const ext = frontend === "vue" ? "ts" : "tsx";
1169
+ scripts["build:frontend"] = `bun build ./resources/js/app.${ext} --outdir=./public --target=browser --format=esm --minify`;
1170
+ scripts["dev"] = `bun run build:frontend && bun --hot app/main.ts`;
1171
+ }
1172
+ const pkg = {
1173
+ name,
1174
+ version: "0.1.0",
1175
+ type: "module",
1176
+ private: true,
1177
+ scripts,
1178
+ dependencies: deps
1179
+ };
1180
+ if (Object.keys(devDeps).length > 0) {
1181
+ pkg.devDependencies = devDeps;
1182
+ }
1183
+ return pkg;
1184
+ }
1185
+ function generateNxConfig(target, opts) {
1186
+ const code = render(templates.project["nx.config.ts"], {
1187
+ routing: opts.routing,
1188
+ view: opts.view,
1189
+ viewPaths: opts.view === "none" ? "" : "resources/views",
1190
+ orm: opts.orm,
1191
+ dbDriver: opts.db,
1192
+ dbUrl: opts.dbUrl,
1193
+ inertiaFrontend: opts.frontend,
1194
+ inertiaSSR: opts.ssr,
1195
+ inertiaVersion: "1.0.0"
1196
+ });
1197
+ writeFileSync2(resolve4(target, "nx.config.ts"), code);
1198
+ }
1199
+ function generateDrizzleConfig(target, db, dbUrl) {
1200
+ if (db !== "bun-sqlite" && db !== "node-sqlite" && db !== "libsql" && db !== "postgres" && db !== "mysql")
1201
+ return;
1202
+ const dialect = db === "bun-sqlite" || db === "node-sqlite" || db === "libsql" ? "sqlite" : db === "postgres" ? "postgresql" : "mysql";
1203
+ const code = render(templates.project["drizzle.config.ts"], {
1204
+ dialect,
1205
+ dbUrl: dbUrl || "app.db"
1206
+ });
1207
+ writeFileSync2(resolve4(target, "drizzle.config.ts"), code);
1208
+ }
1209
+ function generateEnvFile() {
1210
+ return [
1211
+ "# \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
1212
+ "# NexusTS \u2014 Environment Variables (committed to git)",
1213
+ "#",
1214
+ "# Shared defaults for all environments. Override locally via",
1215
+ "# .env.local (gitignored) or by environment via .env.{NODE_ENV}",
1216
+ "# (e.g. .env.production, .env.development).",
1217
+ "# \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
1218
+ "",
1219
+ "# \u2500\u2500 App \u2500\u2500",
1220
+ "NODE_ENV=development",
1221
+ "PORT=3000",
1222
+ "",
1223
+ "# \u2500\u2500 Session secret (REQUIRED) \u2500\u2500",
1224
+ "# Generate with: openssl rand -base64 32",
1225
+ "SESSION_SECRET=change-me-in-production",
1226
+ "",
1227
+ "# \u2500\u2500 Database: SQLite (default, zero config) \u2500\u2500",
1228
+ "DATABASE_URL=app.db",
1229
+ "",
1230
+ "# \u2500\u2500 Database: PostgreSQL \u2500\u2500",
1231
+ "# DATABASE_URL=postgres://user:password@localhost:5432/myapp",
1232
+ "",
1233
+ "# \u2500\u2500 Database: MySQL \u2500\u2500",
1234
+ "# DATABASE_URL=mysql://user:password@localhost:3306/myapp",
1235
+ "",
1236
+ "# \u2500\u2500 Better Auth (if using nexusjs/auth) \u2500\u2500",
1237
+ "# BETTER_AUTH_SECRET=",
1238
+ "# BETTER_AUTH_URL=http://localhost:3000"
1239
+ ].join(`
1240
+ `) + `
1241
+ `;
1242
+ }
1243
+ function generateEnvLocalFile() {
1244
+ return [
1245
+ "# \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
1246
+ "# NexusTS \u2014 Local Overrides (DO NOT COMMIT to git)",
1247
+ "#",
1248
+ "# This file is gitignored. Use it for secrets and local",
1249
+ "# configuration that should never be checked in.",
1250
+ "# \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
1251
+ "",
1252
+ "# Override any value from .env here:",
1253
+ "# DATABASE_URL=postgres://user:password@localhost:5432/myapp",
1254
+ "# SESSION_SECRET=my-local-secret"
1255
+ ].join(`
1256
+ `) + `
1257
+ `;
1258
+ }
1259
+ function generateGitIgnore() {
1260
+ return `# NexusTS
1261
+ node_modules/
1262
+ app.db
1263
+ *.db
1264
+ .env.local
1265
+ dist/
1266
+ `;
1267
+ }
1268
+ function generateProjectFiles(target, opts) {
1269
+ const created = [];
1270
+ const write = (path, content) => {
1271
+ writeFileSync2(resolve4(target, path), content);
1272
+ created.push(path);
1273
+ };
1274
+ generateNxConfig(target, opts);
1275
+ write("public/.gitkeep", "");
1276
+ if (opts.view === "inertia") {
1277
+ if (opts.frontend === "vue") {
1278
+ write("resources/js/Pages/Welcome.vue", `<template>
1279
+ <main style="font-family: system-ui, sans-serif; max-width: 560px; margin: 2em auto">
1280
+ <h1>Hello, {{ name }}!</h1>
1281
+ </main>
1282
+ </template>
1283
+
1284
+ <script setup lang="ts">
1285
+ defineProps<{ name: string }>();
1286
+ </script>
1287
+ `);
1288
+ write("resources/js/app.ts", `import { createInertiaApp } from "@inertiajs/vue3";
1289
+ import { createApp, h } from "vue";
1290
+ import Welcome from "./Pages/Welcome.vue";
1291
+
1292
+ createInertiaApp({
1293
+ resolve: (name: string) => {
1294
+ if (name === "Welcome") return Welcome;
1295
+ throw new Error("Unknown page: " + name);
1296
+ },
1297
+ setup({ el, App, props }: any) {
1298
+ createApp({ render: () => h(App, props) }).mount(el);
1299
+ },
1300
+ });
1301
+ `);
1302
+ } else {
1303
+ write("resources/js/Pages/Welcome.tsx", `import { useState } from "react";
1304
+
1305
+ export default function Welcome({ name }: { name: string }) {
1306
+ const [count, setCount] = useState(0);
1307
+ return (
1308
+ <main style={{ fontFamily: "system-ui, sans-serif", maxWidth: 560, margin: "2em auto" }}>
1309
+ <h1>Hello, {name}!</h1>
1310
+ <p>Counter: <strong>{count}</strong></p>
1311
+ <button onClick={() => setCount((c) => c + 1)} style={{ padding: "0.5em 1em" }}>
1312
+ +1
1313
+ </button>
1314
+ </main>
1315
+ );
1316
+ }
1317
+ `);
1318
+ write("resources/js/app.tsx", `import { createInertiaApp } from "@inertiajs/react";
1319
+ import { createRoot } from "react-dom/client";
1320
+ import Welcome from "./Pages/Welcome.js";
1321
+
1322
+ createInertiaApp({
1323
+ resolve: (name: string) => {
1324
+ if (name === "Welcome") return Welcome;
1325
+ throw new Error("Unknown page: " + name);
1326
+ },
1327
+ setup({ el, App, props }: any) {
1328
+ createRoot(el).render(<App {...props} />);
1329
+ },
1330
+ });
1331
+ `);
1332
+ }
1333
+ } else if (opts.view !== "none") {
1334
+ write("resources/views/welcome.html", `<h1>Welcome to ${opts.name}</h1>
1335
+ <p>This is a sample Rendu template.</p>
1336
+ <p>Founded <?= year ?>.</p>
1337
+ `);
1338
+ }
1339
+ write(".env", generateEnvFile());
1340
+ write(".env.local", generateEnvLocalFile());
1341
+ write(".gitignore", generateGitIgnore());
1342
+ {
1343
+ const hasView = opts.view !== "none";
1344
+ const staticMw = hasView ? `import { StaticModule } from '@nexusts/static';
1345
+ const staticMiddleware = StaticModule.mount({ root: './public', prefix: '/static' });
1346
+ ` : "";
1347
+ const staticOpt = hasView ? `
1348
+ middleware: [staticMiddleware],` : "";
1349
+ write("app/main.ts", `import 'reflect-metadata';
1350
+ import { Application } from '@nexusts/core';
1351
+ ${staticMw}import { AppModule } from './app.module.js';
1352
+
1353
+ const app = new Application(AppModule, {
1354
+ logging: true,
1355
+ port: Number(process.env['PORT'] ?? 3000),${staticOpt}
1356
+ });
1357
+
1358
+ await app.listen();
1359
+ console.log('[nexus] Listening on http://localhost:' + (process.env['PORT'] ?? 3000));
1360
+ `);
1361
+ }
1362
+ {
1363
+ const hasOrm = opts.orm === "drizzle";
1364
+ const ormImport = hasOrm ? `import { DrizzleModule } from '@nexusts/drizzle';
1365
+ ` : "";
1366
+ const forRootDialect = opts.db === "bun-sqlite" ? "bun-sqlite" : "sqlite";
1367
+ const ormBlock = hasOrm ? ` DrizzleModule.forRoot({
1368
+ dialect: '${forRootDialect}',
1369
+ connection: { filename: '${opts.dbUrl || "app.db"}' },
1370
+ logging: true,
1371
+ })` : "";
1372
+ const isInertia = opts.view === "inertia";
1373
+ const inertiaImport = isInertia ? `import { Inertia } from '@nexusts/view';
1374
+ ` : "";
1375
+ const inertiaProvider = isInertia ? ` providers: [{ provide: Inertia.TOKEN, useValue: new Inertia({ scripts: ['/static/app.js'] }) }],
1376
+ ` : "";
1377
+ write("app/app.module.ts", `${ormImport}${inertiaImport}import { Module } from '@nexusts/core';
1378
+ import { HomeController } from './controllers/home.controller.js';
1379
+
1380
+ @Module({
1381
+ imports: [${hasOrm ? `
1382
+ ${ormBlock},
1383
+ ` : ""} ],
1384
+ ${inertiaProvider} controllers: [HomeController],
1385
+ })
1386
+ export class AppModule {}
1387
+ `);
1388
+ }
1389
+ {
1390
+ if (opts.view === "inertia") {
1391
+ write("app/controllers/home.controller.ts", `import { Controller, Get, Inject } from '@nexusts/core';
1392
+ import { Inertia } from '@nexusts/view';
1393
+
1394
+ @Controller('/')
1395
+ export class HomeController {
1396
+ constructor(@Inject(Inertia.TOKEN) private inertia: Inertia) {}
1397
+
1398
+ @Get('/')
1399
+ index() {
1400
+ return this.inertia.render('Welcome', { name: 'NexusTS' });
1401
+ }
1402
+ }
1403
+ `);
1404
+ } else if (opts.view !== "none") {
1405
+ write("app/controllers/home.controller.ts", `import { Controller, Get } from '@nexusts/core';
1406
+
1407
+ @Controller('/')
1408
+ export class HomeController {
1409
+ @Get('/')
1410
+ index() {
1411
+ return {
1412
+ view: 'welcome.html',
1413
+ data: { year: new Date().getFullYear() },
1414
+ };
1415
+ }
1416
+ }
1417
+ `);
1418
+ } else {
1419
+ write("app/controllers/home.controller.ts", `import { Controller, Get } from '@nexusts/core';
1420
+
1421
+ @Controller('/')
1422
+ export class HomeController {
1423
+ @Get('/')
1424
+ index() {
1425
+ return { status: 200, body: { message: 'Hello from NexusTS!' } };
1426
+ }
1427
+ }
1428
+ `);
1429
+ }
1430
+ }
1431
+ if (opts.orm === "drizzle") {
1432
+ generateDrizzleConfig(target, opts.db, opts.dbUrl);
1433
+ }
1434
+ write("README.md", `# ${opts.name}
1435
+
1436
+ A NexusTS project.
1437
+
1438
+ ## Run
1439
+
1440
+ \`\`\`bash
1441
+ bun install
1442
+ bun run dev
1443
+ \`\`\`
1444
+
1445
+ ## Scaffolding
1446
+
1447
+ \`\`\`bash
1448
+ bunx nx make:crud Post
1449
+ \`\`\`
1450
+ `);
1451
+ return created;
1452
+ }
1453
+ // packages/cli/src/commands/info.ts
1454
+ var infoCommand = {
1455
+ name: "info",
1456
+ aliases: ["i"],
1457
+ summary: "Show project configuration",
1458
+ description: "Prints the resolved nx.config.ts plus relevant env vars.",
1459
+ async run(ctx) {
1460
+ logger.heading("NexusTS CLI \u2014 Project Info");
1461
+ logger.info(colors.bold("Resolved configuration"));
1462
+ logger.blank();
1463
+ logger.table([
1464
+ ["routing", String(ctx.config.routing)],
1465
+ ["view", String(ctx.config.view)],
1466
+ ["orm", String(ctx.config.orm)],
1467
+ ["dialect", String(ctx.config.dialect ?? "(none)")],
1468
+ ["database.driver", String(ctx.config.database.driver)],
1469
+ ["database.url", String(ctx.config.database.url)],
1470
+ ["inertia.frontend", String(ctx.config.inertia.frontend)],
1471
+ ["inertia.ssr", String(ctx.config.inertia.ssr)],
1472
+ ["inertia.version", String(ctx.config.inertia.version)]
1473
+ ]);
1474
+ logger.blank();
1475
+ logger.info(colors.bold("Paths"));
1476
+ logger.blank();
1477
+ for (const [k, v] of Object.entries(ctx.config.paths)) {
1478
+ logger.table([[k, v]]);
1479
+ }
1480
+ logger.blank();
1481
+ logger.info(colors.bold("Environment"));
1482
+ logger.blank();
1483
+ const envKeys = [
1484
+ "NODE_ENV",
1485
+ "PORT",
1486
+ "NEXUS_DEBUG",
1487
+ "NO_COLOR",
1488
+ "FORCE_COLOR",
1489
+ "NX_ROUTING",
1490
+ "NX_VIEW",
1491
+ "NX_ORM",
1492
+ "NX_DATABASE_DRIVER",
1493
+ "NX_DATABASE_URL",
1494
+ "NX_INERTIA_FRONTEND",
1495
+ "NX_INERTIA_SSR"
1496
+ ];
1497
+ for (const k of envKeys) {
1498
+ const v = process.env[k];
1499
+ logger.table([[k, v === undefined ? colors.dim("(unset)") : v]]);
1500
+ }
1501
+ logger.blank();
1502
+ logger.info(colors.bold("Working directory"));
1503
+ logger.blank();
1504
+ logger.info(` ${resolve5(ctx.cwd)}`);
1505
+ logger.blank();
1506
+ return 0;
1507
+ }
1508
+ };
1509
+ var info_default = infoCommand;
1510
+
1167
1511
  // packages/cli/src/commands/init.ts
1512
+ import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
1513
+ import { resolve as resolve6 } from "path";
1514
+ var VALID_OPTIONS = {
1515
+ style: ["nest", "adonis", "functional"],
1516
+ view: ["rendu", "edge", "eta", "inertia", "none"],
1517
+ orm: ["drizzle", "prisma", "kysely", "none"],
1518
+ db: ["bun-sqlite", "node-sqlite", "libsql", "postgres", "mysql", "none"],
1519
+ frontend: ["react", "vue", "svelte", "solid"]
1520
+ };
1521
+ async function resolveOpt(flags, key, valid, defaultVal, interactive) {
1522
+ const flagVal = flags[key];
1523
+ if (flagVal) {
1524
+ if (valid.includes(flagVal))
1525
+ return flagVal;
1526
+ if (!interactive) {
1527
+ logger.error(`Invalid --${key} "${flagVal}". Valid values: ${valid.join(", ")}`);
1528
+ process.exit(1);
1529
+ }
1530
+ logger.warn(`"${flagVal}" is not valid for --${key}. Please choose from the list.`);
1531
+ }
1532
+ const label = key === "style" ? "Routing style" : key === "view" ? "View engine" : key === "orm" ? "ORM driver" : key === "db" ? "Database driver" : "Inertia frontend";
1533
+ for (;; ) {
1534
+ const answer = await select(label, [...valid], { default: defaultVal });
1535
+ if (valid.includes(answer))
1536
+ return answer;
1537
+ logger.warn(`"${answer}" is not valid. Please choose from: ${valid.join(", ")}`);
1538
+ }
1539
+ }
1168
1540
  var initCommand = {
1169
1541
  name: "init",
1170
1542
  aliases: ["i"],
1171
- summary: "Initialize nx.config.ts + app scaffold in the current directory",
1172
- description: "Non-destructive scaffold: adds nx.config.ts, app/*, and merges NexusTS into the existing package.json and tsconfig.json. Skips files that already exist (unless --force).",
1543
+ summary: "Initialize NexusTS in an existing directory",
1544
+ description: "Scaffolds a new NexusTS project in the current or target directory. Non-destructive: skips existing files, merges package.json and tsconfig.json.",
1173
1545
  examples: [
1174
1546
  "nx init",
1175
- "nx init ./my-existing-app",
1547
+ "nx init ./my-app",
1176
1548
  "nx init --style nest --view inertia --orm drizzle --db bun-sqlite",
1177
1549
  "nx init --force"
1178
1550
  ],
1179
1551
  flags: [
1180
1552
  { name: "target", description: "Target directory (default: cwd)" },
1181
- {
1182
- name: "style",
1183
- description: "Routing style (nest|adonis|functional|mixed)"
1184
- },
1553
+ { name: "style", description: "Routing style (nest|adonis|functional)" },
1185
1554
  { name: "view", description: "View engine (rendu|edge|eta|inertia|none)" },
1186
1555
  { name: "orm", description: "ORM driver (drizzle|prisma|kysely|none)" },
1187
- {
1188
- name: "db",
1189
- description: "Database driver (bun-sqlite|node-sqlite|libsql|postgres|mysql|none)"
1190
- },
1556
+ { name: "db", description: "Database driver (bun-sqlite|node-sqlite|libsql|postgres|mysql|none)" },
1191
1557
  {
1192
1558
  name: "frontend",
1193
1559
  description: "Inertia frontend (react|vue|svelte|solid)"
1194
1560
  },
1195
1561
  { name: "no-ssr", description: "Disable Inertia SSR" },
1196
- { name: "force", description: "Overwrite files that already exist" },
1197
- { name: "no-interaction", description: "Disable interactive prompts" }
1562
+ { name: "force", description: "Overwrite existing files" },
1563
+ { name: "no-interaction", description: "Skip interactive prompts" }
1198
1564
  ],
1199
1565
  async run(ctx) {
1200
- const interactive = !flagBool(ctx.flags, "no-interaction", false);
1566
+ const interactive = flagBool(ctx.flags, "interaction", true);
1201
1567
  const force = flagBool(ctx.flags, "force", false);
1202
- const target = resolve5(ctx.cwd, ctx.flags["target"] ?? ".");
1203
- if (!existsSync4(target)) {
1204
- logger.error(`Target directory does not exist: ${target}`);
1205
- logger.info(`Run \`nx new <name>\` to create a fresh project, or \`mkdir -p ${target}\` first.`);
1206
- return 1;
1207
- }
1208
- const routing = ctx.flags["style"] ?? await select("Routing style", ["nest", "adonis", "functional"], {
1209
- interactive,
1210
- default: "nest"
1211
- });
1212
- const view = ctx.flags["view"] ?? await select("View engine", ["rendu", "edge", "eta", "inertia", "none"], {
1213
- interactive,
1214
- default: "rendu"
1215
- });
1216
- const orm = ctx.flags["orm"] ?? await select("ORM driver", ["drizzle", "prisma", "kysely", "none"], {
1217
- interactive,
1218
- default: "drizzle"
1219
- });
1220
- const db = ctx.flags["db"] ?? await select("Database driver", ["bun-sqlite", "node-sqlite", "libsql", "postgres", "mysql", "none"], {
1221
- interactive,
1222
- default: "bun-sqlite"
1223
- });
1224
- const frontend = ctx.flags["frontend"] ?? await select("Inertia frontend", ["react", "vue", "svelte", "solid"], {
1225
- interactive,
1226
- default: "react"
1227
- });
1568
+ const target = resolve6(ctx.cwd, ctx.flags["target"] ?? ".");
1569
+ const routing = await resolveOpt(ctx.flags, "style", VALID_OPTIONS.style, "nest", interactive);
1570
+ const view = await resolveOpt(ctx.flags, "view", VALID_OPTIONS.view, "rendu", interactive);
1571
+ const orm = await resolveOpt(ctx.flags, "orm", VALID_OPTIONS.orm, "drizzle", interactive);
1572
+ const db = await resolveOpt(ctx.flags, "db", VALID_OPTIONS.db, "bun-sqlite", interactive);
1573
+ const frontend = await resolveOpt(ctx.flags, "frontend", VALID_OPTIONS.frontend, "react", interactive);
1228
1574
  const ssr = !flagBool(ctx.flags, "no-ssr", false);
1575
+ const name = target.split("/").pop() ?? "nexus-app";
1576
+ const dbUrl = db === "bun-sqlite" || db === "node-sqlite" ? "app.db" : "";
1229
1577
  const plan = [
1230
- { path: "nx.config.ts", mode: "write" },
1231
1578
  { path: "package.json", mode: "merge-pkg" },
1232
1579
  { path: "tsconfig.json", mode: "merge-tsconfig" },
1233
- { path: "public/.gitkeep", mode: "write" },
1234
- ...view !== "none" ? [{ path: "resources/views/welcome.html", mode: "write" }] : [],
1235
1580
  { path: ".env", mode: "skip" },
1236
1581
  { path: ".env.local", mode: "skip" },
1237
1582
  { path: ".gitignore", mode: "skip" },
1238
- ...orm === "drizzle" ? [{ path: "drizzle.config.ts", mode: "write" }] : [],
1583
+ { path: "nx.config.ts", mode: "write" },
1584
+ { path: "public/.gitkeep", mode: "write" },
1239
1585
  { path: "app/main.ts", mode: "write" },
1240
1586
  { path: "app/app.module.ts", mode: "write" },
1241
1587
  { path: "app/controllers/home.controller.ts", mode: "write" },
1242
- { path: "README.md", mode: "write" }
1588
+ { path: "README.md", mode: "write" },
1589
+ ...view === "inertia" ? [
1590
+ { path: `resources/js/Pages/Welcome.${frontend === "vue" ? "vue" : "tsx"}`, mode: "write" },
1591
+ { path: `resources/js/app.${frontend === "vue" ? "ts" : "tsx"}`, mode: "write" }
1592
+ ] : view !== "none" ? [{ path: "resources/views/welcome.html", mode: "write" }] : [],
1593
+ ...orm === "drizzle" ? [{ path: "drizzle.config.ts", mode: "write" }] : []
1243
1594
  ];
1244
1595
  const created = [];
1245
1596
  const skipped = [];
1246
1597
  const merged = [];
1247
- mkdirSync2(resolve5(target, "app/controllers"), { recursive: true });
1248
- mkdirSync2(resolve5(target, "public"), { recursive: true });
1249
- if (view !== "none") {
1250
- mkdirSync2(resolve5(target, "resources/views"), { recursive: true });
1251
- }
1598
+ ensureDirectories(target, view);
1252
1599
  for (const entry of plan) {
1253
- const abs = resolve5(target, entry.path);
1600
+ const abs = resolve6(target, entry.path);
1254
1601
  const exists = existsSync4(abs);
1255
1602
  if (entry.mode === "merge-pkg") {
1256
- const coreDeps = {
1257
- "@nexusts/core": "*",
1258
- "reflect-metadata": "^0.2.2",
1259
- hono: "^4.6.0",
1260
- zod: "^3.23.8"
1261
- };
1262
- const devDeps = {};
1263
- if (orm === "drizzle") {
1264
- coreDeps["@nexusts/drizzle"] = "*";
1265
- coreDeps["drizzle-orm"] = "^0.45.0";
1266
- if (db === "postgres")
1267
- coreDeps["pg"] = "^8.13.0";
1268
- if (db === "mysql")
1269
- coreDeps["mysql2"] = "^3.11.0";
1270
- if (db === "sqlite" || db === "node-sqlite" || db === "bun-sqlite")
1271
- coreDeps["better-sqlite3"] = "^12.0.0";
1272
- devDeps["drizzle-kit"] = "^0.31.0";
1273
- }
1274
- if (view !== "none") {
1275
- coreDeps["@nexusts/static"] = "*";
1276
- }
1603
+ const { deps, devDeps } = computeDeps(view, orm, db, frontend);
1277
1604
  if (exists) {
1278
- mergePackageJson(abs, coreDeps, devDeps);
1605
+ mergePackageJson(abs, deps, devDeps, view, frontend);
1279
1606
  merged.push(entry.path);
1280
1607
  } else {
1281
- const pkgJson = {
1282
- name: target.split("/").pop() ?? "nexus-app",
1283
- version: "0.1.0",
1284
- type: "module",
1285
- private: true,
1286
- scripts: {
1287
- dev: "bun --hot app/main.ts",
1288
- build: "bun run build.ts",
1289
- start: "bun app/main.ts",
1290
- test: "vitest",
1291
- nx: "nx"
1292
- },
1293
- dependencies: coreDeps
1294
- };
1295
- if (orm === "drizzle") {
1296
- pkgJson.devDependencies = {
1297
- "drizzle-kit": "^0.31.0"
1298
- };
1299
- }
1300
- writeFileSync2(abs, JSON.stringify(pkgJson, null, 2));
1608
+ const pkgJson = buildPackageJson(name, deps, devDeps, view, frontend);
1609
+ writeFileSync3(abs, JSON.stringify(pkgJson, null, 2) + `
1610
+ `);
1301
1611
  created.push(entry.path);
1302
1612
  }
1303
1613
  continue;
@@ -1310,7 +1620,7 @@ var initCommand = {
1310
1620
  });
1311
1621
  merged.push(entry.path);
1312
1622
  } else {
1313
- writeFileSync2(abs, defaultTsconfig());
1623
+ writeFileSync3(abs, defaultTsconfig());
1314
1624
  created.push(entry.path);
1315
1625
  }
1316
1626
  continue;
@@ -1319,217 +1629,34 @@ var initCommand = {
1319
1629
  skipped.push(entry.path);
1320
1630
  continue;
1321
1631
  }
1322
- const content = renderContent(entry.path, {
1323
- routing,
1324
- view,
1325
- viewPaths: view === "none" ? "" : "resources/views",
1326
- orm,
1327
- dbDriver: db,
1328
- dbUrl: db === "bun-sqlite" || db === "node-sqlite" ? "app.db" : "",
1329
- inertiaFrontend: frontend,
1330
- inertiaSSR: ssr,
1331
- inertiaVersion: "1.0.0",
1332
- targetName: target.split("/").pop() ?? "nexus-app"
1333
- });
1334
- writeFileSync2(abs, content);
1335
1632
  created.push(entry.path);
1336
1633
  }
1634
+ const scaffoldOpts = { target, name, routing, view, orm, db, frontend, ssr, dbUrl };
1635
+ const scaffoldFiles = generateProjectFiles(target, scaffoldOpts);
1636
+ for (const f of scaffoldFiles) {
1637
+ if (!plan.some((p) => p.path === f)) {
1638
+ created.push(f);
1639
+ }
1640
+ }
1337
1641
  logger.success(`initialized NexusTS in ${target}`);
1338
1642
  logger.blank();
1339
- if (created.length) {
1643
+ if (created.length)
1340
1644
  logger.heading("Created");
1341
- for (const f of created)
1342
- logger.info(` + ${f}`);
1343
- }
1344
- if (merged.length) {
1645
+ for (const f of created)
1646
+ logger.info(` + ${f}`);
1647
+ if (merged.length)
1345
1648
  logger.heading("Merged into existing files");
1346
- for (const f of merged)
1347
- logger.info(` ~ ${f}`);
1348
- }
1349
- if (skipped.length) {
1649
+ for (const f of merged)
1650
+ logger.info(` ~ ${f}`);
1651
+ if (skipped.length)
1350
1652
  logger.heading("Skipped (already exist; use --force to overwrite)");
1351
- for (const f of skipped)
1352
- logger.info(` - ${f}`);
1353
- }
1354
- logger.blank();
1355
- logger.heading("Next steps");
1356
- logger.info(` cd ${target === ctx.cwd ? "." : target}`);
1357
- logger.info(` bun install`);
1358
- logger.info(` bun run dev`);
1653
+ for (const f of skipped)
1654
+ logger.info(` - ${f}`);
1359
1655
  logger.blank();
1360
1656
  return 0;
1361
1657
  }
1362
1658
  };
1363
- function renderContent(path, ctx) {
1364
- switch (path) {
1365
- case "nx.config.ts":
1366
- return render(templates.project["nx.config.ts"], ctx);
1367
- case "public/.gitkeep":
1368
- return "";
1369
- case "resources/views/welcome.html":
1370
- return `<h1>Welcome to ${ctx.targetName}</h1>
1371
- <p>This is a sample Rendu template.</p>
1372
- <p>Founded <?= year ?>.</p>
1373
- `;
1374
- case ".gitignore":
1375
- return `# NexusTS
1376
- node_modules/
1377
- app.db
1378
- *.db
1379
- .env.local
1380
- dist/
1381
- `;
1382
- case ".env":
1383
- return `# \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
1384
- # NexusTS \u2014 Environment Variables (committed to git)
1385
- #
1386
- # Shared defaults for all environments. Override locally via
1387
- # .env.local (gitignored) or by environment via .env.{NODE_ENV}
1388
- # (e.g. .env.production, .env.development).
1389
- #
1390
- # Uncomment the database config for your driver:
1391
- # \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
1392
-
1393
- # \u2500\u2500 App \u2500\u2500
1394
- NODE_ENV=development
1395
- PORT=3000
1396
-
1397
- # \u2500\u2500 Session secret (REQUIRED) \u2500\u2500
1398
- # Generate with: openssl rand -base64 32
1399
- SESSION_SECRET=change-me-in-production
1400
-
1401
- # \u2500\u2500 Database: SQLite (default, zero config) \u2500\u2500
1402
- DATABASE_URL=app.db
1403
-
1404
- # \u2500\u2500 Database: PostgreSQL \u2500\u2500
1405
- # DATABASE_URL=postgres://user:password@localhost:5432/myapp
1406
-
1407
- # \u2500\u2500 Database: MySQL \u2500\u2500
1408
- # DATABASE_URL=mysql://user:password@localhost:3306/myapp
1409
-
1410
- # \u2500\u2500 Better Auth (if using nexusjs/auth) \u2500\u2500
1411
- # BETTER_AUTH_SECRET=
1412
- # BETTER_AUTH_URL=http://localhost:3000
1413
- `;
1414
- case ".env.local":
1415
- return `# \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
1416
- # NexusTS \u2014 Local Overrides (DO NOT COMMIT to git)
1417
- #
1418
- # This file is gitignored. Use it for secrets and local
1419
- # configuration that should never be checked in.
1420
- # \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
1421
-
1422
- # Override any value from .env here:
1423
- # DATABASE_URL=postgres://user:password@localhost:5432/myapp
1424
- # SESSION_SECRET=my-local-secret
1425
- `;
1426
- case "drizzle.config.ts": {
1427
- const dialect = ctx.dbDriver === "bun-sqlite" || ctx.dbDriver === "node-sqlite" || ctx.dbDriver === "libsql" ? "sqlite" : ctx.dbDriver === "postgres" ? "postgresql" : "sqlite";
1428
- return render(templates.project["drizzle.config.ts"], {
1429
- dialect,
1430
- dbUrl: ctx.dbUrl || "app.db"
1431
- });
1432
- }
1433
- case "app/main.ts": {
1434
- const hasView = ctx.view !== "none";
1435
- const staticMw = hasView ? `import { StaticModule } from '@nexusts/static';
1436
- ` + `const staticMiddleware = StaticModule.mount({ root: './public', prefix: '/static' });
1437
- ` : "";
1438
- const staticOpt = hasView ? `
1439
- middleware: [staticMiddleware],` : "";
1440
- return `import 'reflect-metadata';
1441
- import { Application } from '@nexusts/core';
1442
- ${staticMw}import { AppModule } from './app.module.js';
1443
-
1444
- const app = new Application(AppModule, {
1445
- logging: true,
1446
- port: Number(process.env['PORT'] ?? 3000),${staticOpt}
1447
- });
1448
-
1449
- await app.listen();
1450
- console.log('[nexus] Listening on http://localhost:' + (process.env['PORT'] ?? 3000));
1451
- `;
1452
- }
1453
- case "app/app.module.ts": {
1454
- const hasOrm = ctx.orm === "drizzle";
1455
- const ormImport = hasOrm ? `import { DrizzleModule } from '@nexusts/drizzle';
1456
- ` : "";
1457
- const forRootDialect = ctx.dbDriver === "bun-sqlite" ? "bun-sqlite" : "sqlite";
1458
- const forRootFile = ctx.dbUrl || "app.db";
1459
- const ormBlock = hasOrm ? ` DrizzleModule.forRoot({
1460
- dialect: '` + forRootDialect + `',
1461
- connection: { filename: '` + forRootFile + `' },
1462
- logging: true,
1463
- })` : "";
1464
- return `${ormImport}import { Module } from '@nexusts/core';
1465
- import { HomeController } from './controllers/home.controller.js';
1466
-
1467
- @Module({
1468
- imports: [${hasOrm ? `
1469
- ${ormBlock},
1470
- ` : ""} ],
1471
- controllers: [HomeController],
1472
- })
1473
- export class AppModule {}
1474
- `;
1475
- }
1476
- case "app/controllers/home.controller.ts": {
1477
- const hasView = ctx.view !== "none";
1478
- const body = hasView ? `{
1479
- view: 'welcome.html',
1480
- data: { year: new Date().getFullYear() },
1481
- }` : `{ status: 200, body: { message: 'Hello from NexusTS!' } }`;
1482
- return `import { Controller, Get } from '@nexusts/core';
1483
-
1484
- @Controller('/')
1485
- export class HomeController {
1486
- @Get('/')
1487
- index() {
1488
- return ${body};
1489
- }
1490
- }
1491
- `;
1492
- }
1493
- case "README.md":
1494
- return `# ${ctx.targetName}
1495
-
1496
- A NexusTS project.
1497
-
1498
- ## Run
1499
-
1500
- \`\`\`bash
1501
- bun install
1502
- bun run dev
1503
- \`\`\`
1504
-
1505
- ## Scaffolding
1506
-
1507
- \`\`\`bash
1508
- bunx nx make:crud Post
1509
- \`\`\`
1510
- `;
1511
- default:
1512
- throw new Error(`No render template for: ${path}`);
1513
- }
1514
- }
1515
- function defaultTsconfig() {
1516
- return `{
1517
- "compilerOptions": {
1518
- "target": "ES2022",
1519
- "module": "ESNext",
1520
- "moduleResolution": "bundler",
1521
- "experimentalDecorators": true,
1522
- "emitDecoratorMetadata": true,
1523
- "strict": true,
1524
- "esModuleInterop": true,
1525
- "skipLibCheck": true,
1526
- "types": ["bun-types"]
1527
- },
1528
- "include": ["app/**/*.ts", "nx.config.ts"]
1529
- }
1530
- `;
1531
- }
1532
- function mergePackageJson(path, additions, devAdditions = {}) {
1659
+ function mergePackageJson(path, additions, devAdditions = {}, view, frontend) {
1533
1660
  const raw = readFileSync4(path, "utf8");
1534
1661
  const pkg = parseJsonLoose(raw);
1535
1662
  let changed = false;
@@ -1548,6 +1675,11 @@ function mergePackageJson(path, additions, devAdditions = {}) {
1548
1675
  test: "vitest",
1549
1676
  nx: "nx"
1550
1677
  };
1678
+ if (view === "inertia") {
1679
+ const ext = frontend === "vue" ? "ts" : "tsx";
1680
+ SCRIPTS["build:frontend"] = `bun build ./resources/js/app.${ext} --outdir=./public --target=browser --format=esm --minify`;
1681
+ SCRIPTS["dev"] = `bun run build:frontend && bun --hot app/main.ts`;
1682
+ }
1551
1683
  const existingScripts = pkg["scripts"] ?? {};
1552
1684
  for (const [k, v] of Object.entries(SCRIPTS)) {
1553
1685
  if (!(k in existingScripts)) {
@@ -1555,9 +1687,8 @@ function mergePackageJson(path, additions, devAdditions = {}) {
1555
1687
  changed = true;
1556
1688
  }
1557
1689
  }
1558
- if (Object.keys(existingScripts).length > 0) {
1690
+ if (Object.keys(existingScripts).length > 0)
1559
1691
  pkg["scripts"] = existingScripts;
1560
- }
1561
1692
  const deps = pkg["dependencies"] ?? {};
1562
1693
  for (const [k, v] of Object.entries(additions)) {
1563
1694
  if (!(k in deps)) {
@@ -1576,10 +1707,9 @@ function mergePackageJson(path, additions, devAdditions = {}) {
1576
1707
  }
1577
1708
  pkg["devDependencies"] = devDeps;
1578
1709
  }
1579
- if (changed) {
1580
- writeFileSync2(path, JSON.stringify(pkg, null, 2) + `
1710
+ if (changed)
1711
+ writeFileSync3(path, JSON.stringify(pkg, null, 2) + `
1581
1712
  `);
1582
- }
1583
1713
  }
1584
1714
  function mergeTsconfig(path, additions) {
1585
1715
  const raw = readFileSync4(path, "utf8");
@@ -1592,26 +1722,40 @@ function mergeTsconfig(path, additions) {
1592
1722
  changed = true;
1593
1723
  }
1594
1724
  }
1595
- const inc = cfg.include ?? [];
1596
- if (!inc.includes("app/**/*.ts")) {
1597
- inc.push("app/**/*.ts");
1598
- changed = true;
1599
- }
1600
- if (!inc.includes("nx.config.ts")) {
1601
- inc.push("nx.config.ts");
1602
- changed = true;
1725
+ cfg.compilerOptions = co;
1726
+ const include = cfg.include ?? [];
1727
+ for (const g of ["app/**/*.ts", "nx.config.ts"]) {
1728
+ if (!include.includes(g)) {
1729
+ include.push(g);
1730
+ changed = true;
1731
+ }
1603
1732
  }
1604
- if (changed) {
1605
- cfg.compilerOptions = co;
1606
- cfg.include = inc;
1607
- writeFileSync2(path, JSON.stringify(cfg, null, 2) + `
1733
+ cfg.include = include;
1734
+ if (changed)
1735
+ writeFileSync3(path, JSON.stringify(cfg, null, 2) + `
1608
1736
  `);
1609
- }
1737
+ }
1738
+ function defaultTsconfig() {
1739
+ return `{
1740
+ "compilerOptions": {
1741
+ "target": "ES2022",
1742
+ "module": "ESNext",
1743
+ "moduleResolution": "bundler",
1744
+ "experimentalDecorators": true,
1745
+ "emitDecoratorMetadata": true,
1746
+ "strict": true,
1747
+ "esModuleInterop": true,
1748
+ "skipLibCheck": true,
1749
+ "types": ["@types/bun"]
1750
+ },
1751
+ "include": ["app/**/*.ts", "nx.config.ts"]
1752
+ }
1753
+ `;
1610
1754
  }
1611
1755
  var init_default = initCommand;
1612
1756
 
1613
1757
  // packages/cli/src/commands/make-auth.ts
1614
- import { resolve as resolve6 } from "path";
1758
+ import { resolve as resolve7 } from "path";
1615
1759
  var AUTH_INSTANCE_TEMPLATE = `/**
1616
1760
  * Better-auth instance \u2014 generated by \`nx make:auth\`.
1617
1761
  *
@@ -1726,7 +1870,7 @@ var makeAuthCommand = {
1726
1870
  passkeyRpId: rpId,
1727
1871
  passkeyOrigin: Array.isArray(origin) ? origin.join(",") : origin
1728
1872
  });
1729
- const authOut = resolve6(ctx.cwd, "app/auth/auth.ts");
1873
+ const authOut = resolve7(ctx.cwd, "app/auth/auth.ts");
1730
1874
  if (writeFile(authOut, authCode)) {
1731
1875
  logger.success(`created ${authOut}`);
1732
1876
  } else {
@@ -1736,7 +1880,7 @@ var makeAuthCommand = {
1736
1880
  providers: providers.length > 0,
1737
1881
  entries
1738
1882
  });
1739
- const envOut = resolve6(ctx.cwd, ".env.example");
1883
+ const envOut = resolve7(ctx.cwd, ".env.example");
1740
1884
  if (writeFile(envOut, envCode, { skipIfExists: true })) {
1741
1885
  logger.success(`created ${envOut}`);
1742
1886
  } else {
@@ -1762,7 +1906,7 @@ var makeAuthCommand = {
1762
1906
  var make_auth_default = makeAuthCommand;
1763
1907
 
1764
1908
  // packages/cli/src/commands/make-controller.ts
1765
- import { resolve as resolve7 } from "path";
1909
+ import { resolve as resolve8 } from "path";
1766
1910
  var makeControllerCommand = {
1767
1911
  name: "make:controller",
1768
1912
  aliases: ["mc", "make-controller"],
@@ -1808,7 +1952,7 @@ var makeControllerCommand = {
1808
1952
  service: serviceName,
1809
1953
  serviceCamel
1810
1954
  }).replace(/import .*\n/g, skipService ? (m) => m.includes("services/") ? "" : m : (m) => m);
1811
- const out = resolve7(ctx.cwd, ctx.config.paths.controllers, `${variants.kebab}.controller.ts`);
1955
+ const out = resolve8(ctx.cwd, ctx.config.paths.controllers, `${variants.kebab}.controller.ts`);
1812
1956
  const ok = writeFile(out, code, { skipIfExists: false });
1813
1957
  if (!ok) {
1814
1958
  logger.error(`Refusing to overwrite existing file: ${out}`);
@@ -1823,7 +1967,7 @@ var make_controller_default = makeControllerCommand;
1823
1967
 
1824
1968
  // packages/cli/src/commands/make-crud.ts
1825
1969
  import { mkdirSync as mkdirSync3 } from "fs";
1826
- import { dirname as dirname3, resolve as resolve8 } from "path";
1970
+ import { dirname as dirname3, resolve as resolve9 } from "path";
1827
1971
 
1828
1972
  // packages/cli/src/templates/model/drizzle-dialect.ts
1829
1973
  function renderDrizzleDialect(dialect) {
@@ -1998,7 +2142,7 @@ var makeCrudCommand = {
1998
2142
  viewShowComponent,
1999
2143
  hasInertia
2000
2144
  });
2001
- const out = resolve8(ctx.cwd, ctx.config.paths.controllers, `${variants.kebab}.controller.ts`);
2145
+ const out = resolve9(ctx.cwd, ctx.config.paths.controllers, `${variants.kebab}.controller.ts`);
2002
2146
  if (!writeFile(out, code, { skipIfExists: true })) {
2003
2147
  logger.warn(`skipped (exists): ${out}`);
2004
2148
  } else {
@@ -2016,7 +2160,7 @@ var makeCrudCommand = {
2016
2160
  repository,
2017
2161
  repositoryCamel: variants.camel + "Repository"
2018
2162
  });
2019
- const out = resolve8(ctx.cwd, ctx.config.paths.services, `${variants.kebab}.service.ts`);
2163
+ const out = resolve9(ctx.cwd, ctx.config.paths.services, `${variants.kebab}.service.ts`);
2020
2164
  if (!writeFile(out, code, { skipIfExists: true })) {
2021
2165
  logger.warn(`skipped (exists): ${out}`);
2022
2166
  } else {
@@ -2050,7 +2194,7 @@ var makeCrudCommand = {
2050
2194
  prismaBlock: ""
2051
2195
  });
2052
2196
  }
2053
- const out = resolve8(ctx.cwd, ctx.config.paths.models, `${variants.kebab}.model.ts`);
2197
+ const out = resolve9(ctx.cwd, ctx.config.paths.models, `${variants.kebab}.model.ts`);
2054
2198
  if (!writeFile(out, code, { skipIfExists: true })) {
2055
2199
  logger.warn(`skipped (exists): ${out}`);
2056
2200
  } else {
@@ -2066,7 +2210,7 @@ var makeCrudCommand = {
2066
2210
  tableName,
2067
2211
  repository
2068
2212
  });
2069
- const repoOut = resolve8(ctx.cwd, `${ctx.config.paths.app}/repositories`, `${variants.kebab}.repository.ts`);
2213
+ const repoOut = resolve9(ctx.cwd, `${ctx.config.paths.app}/repositories`, `${variants.kebab}.repository.ts`);
2070
2214
  mkdirSync3(dirname3(repoOut), { recursive: true });
2071
2215
  if (!writeFile(repoOut, repoCode, { skipIfExists: true })) {
2072
2216
  logger.warn(`skipped (exists): ${repoOut}`);
@@ -2081,7 +2225,7 @@ var makeCrudCommand = {
2081
2225
  camel: variants.camel,
2082
2226
  kebab: variants.kebab
2083
2227
  });
2084
- const out = resolve8(ctx.cwd, ctx.config.paths.dto, `${variants.kebab}.dto.ts`);
2228
+ const out = resolve9(ctx.cwd, ctx.config.paths.dto, `${variants.kebab}.dto.ts`);
2085
2229
  if (!writeFile(out, code, { skipIfExists: true })) {
2086
2230
  logger.warn(`skipped (exists): ${out}`);
2087
2231
  } else {
@@ -2099,7 +2243,7 @@ var makeCrudCommand = {
2099
2243
  repository,
2100
2244
  hasRepo: !noRepo
2101
2245
  });
2102
- const out = resolve8(ctx.cwd, ctx.config.paths.modules, `${variants.kebab}.module.ts`);
2246
+ const out = resolve9(ctx.cwd, ctx.config.paths.modules, `${variants.kebab}.module.ts`);
2103
2247
  if (!writeFile(out, code, { skipIfExists: true })) {
2104
2248
  logger.warn(`skipped (exists): ${out}`);
2105
2249
  } else {
@@ -2115,7 +2259,7 @@ var makeCrudCommand = {
2115
2259
  controller,
2116
2260
  service
2117
2261
  });
2118
- const out = resolve8(ctx.cwd, "tests", `${variants.kebab}.test.ts`);
2262
+ const out = resolve9(ctx.cwd, "tests", `${variants.kebab}.test.ts`);
2119
2263
  if (!writeFile(out, code, { skipIfExists: true })) {
2120
2264
  logger.warn(`skipped (exists): ${out}`);
2121
2265
  } else {
@@ -2151,7 +2295,7 @@ function renderDrizzleColumns(dialect) {
2151
2295
  var make_crud_default = makeCrudCommand;
2152
2296
 
2153
2297
  // packages/cli/src/commands/make-listener.ts
2154
- import { resolve as resolve9 } from "path";
2298
+ import { resolve as resolve10 } from "path";
2155
2299
  var LISTENER_TEMPLATE = `
2156
2300
  import { Inject, Injectable } from '@nexusts/core';
2157
2301
  import { EventService, OnEvent } from '@nexusts/events';
@@ -2202,7 +2346,7 @@ var makeListenerCommand = {
2202
2346
  name: variants.pascal,
2203
2347
  kebab: variants.kebab
2204
2348
  });
2205
- const out = resolve9(ctx.cwd, "app/events/listeners", `${variants.kebab}.listener.ts`);
2349
+ const out = resolve10(ctx.cwd, "app/events/listeners", `${variants.kebab}.listener.ts`);
2206
2350
  if (writeFile(out, code, { skipIfExists: true })) {
2207
2351
  logger.success(`created ${out}`);
2208
2352
  } else {
@@ -2222,7 +2366,7 @@ var makeListenerCommand = {
2222
2366
  var make_listener_default = makeListenerCommand;
2223
2367
 
2224
2368
  // packages/cli/src/commands/make-middleware.ts
2225
- import { resolve as resolve10 } from "path";
2369
+ import { resolve as resolve11 } from "path";
2226
2370
  var makeMiddlewareCommand = {
2227
2371
  name: "make:middleware",
2228
2372
  aliases: ["mwm", "make-middleware"],
@@ -2239,7 +2383,7 @@ var makeMiddlewareCommand = {
2239
2383
  const code = render(templates.middleware, {
2240
2384
  name: variants.pascal
2241
2385
  });
2242
- const out = resolve10(ctx.cwd, ctx.config.paths.middleware, `${variants.kebab}.middleware.ts`);
2386
+ const out = resolve11(ctx.cwd, ctx.config.paths.middleware, `${variants.kebab}.middleware.ts`);
2243
2387
  writeFile(out, code);
2244
2388
  logger.success(`created ${out}`);
2245
2389
  logger.finger(`register with: app.server.app.use('*', new ${variants.pascal}Middleware().handle)`);
@@ -2249,7 +2393,7 @@ var makeMiddlewareCommand = {
2249
2393
  var make_middleware_default = makeMiddlewareCommand;
2250
2394
 
2251
2395
  // packages/cli/src/commands/make-migration.ts
2252
- import { resolve as resolve11 } from "path";
2396
+ import { resolve as resolve12 } from "path";
2253
2397
  var makeMigrationCommand = {
2254
2398
  name: "make:migration",
2255
2399
  aliases: ["mkm", "make-migration"],
@@ -2321,7 +2465,7 @@ var makeMigrationCommand = {
2321
2465
  return 1;
2322
2466
  }
2323
2467
  const filename = `${formatTimestamp(new Date)}_${variants.snake}.${extension}`;
2324
- const out = resolve11(ctx.cwd, ctx.config.paths.migrations, filename);
2468
+ const out = resolve12(ctx.cwd, ctx.config.paths.migrations, filename);
2325
2469
  writeFile(out, code);
2326
2470
  logger.success(`created ${out}`);
2327
2471
  if (isDrizzle) {
@@ -2409,7 +2553,7 @@ function formatTimestamp(d) {
2409
2553
  var make_migration_default = makeMigrationCommand;
2410
2554
 
2411
2555
  // packages/cli/src/commands/make-model.ts
2412
- import { resolve as resolve12 } from "path";
2556
+ import { resolve as resolve13 } from "path";
2413
2557
  var makeModelCommand = {
2414
2558
  name: "make:model",
2415
2559
  aliases: ["mmodel", "make-model"],
@@ -2481,7 +2625,7 @@ var makeModelCommand = {
2481
2625
  prismaBlock
2482
2626
  });
2483
2627
  }
2484
- const out = resolve12(ctx.cwd, ctx.config.paths.models, `${variants.kebab}.model.ts`);
2628
+ const out = resolve13(ctx.cwd, ctx.config.paths.models, `${variants.kebab}.model.ts`);
2485
2629
  writeFile(out, code);
2486
2630
  logger.success(`created ${out}`);
2487
2631
  logger.finger(`run \`nx make:migration create_${tableName}_table\` to scaffold a migration.`);
@@ -2540,7 +2684,7 @@ function capitalize(s) {
2540
2684
  var make_model_default = makeModelCommand;
2541
2685
 
2542
2686
  // packages/cli/src/commands/make-module.ts
2543
- import { resolve as resolve13 } from "path";
2687
+ import { resolve as resolve14 } from "path";
2544
2688
  var makeModuleCommand = {
2545
2689
  name: "make:module",
2546
2690
  aliases: ["mm", "make-module"],
@@ -2574,7 +2718,7 @@ var makeModuleCommand = {
2574
2718
  hasService,
2575
2719
  hasRepo
2576
2720
  });
2577
- const out = resolve13(ctx.cwd, ctx.config.paths.modules, `${variants.kebab}.module.ts`);
2721
+ const out = resolve14(ctx.cwd, ctx.config.paths.modules, `${variants.kebab}.module.ts`);
2578
2722
  writeFile(out, code);
2579
2723
  logger.success(`created ${out}`);
2580
2724
  logger.finger(`add ${variants.pascal}Module to AppModule.imports.`);
@@ -2584,7 +2728,7 @@ var makeModuleCommand = {
2584
2728
  var make_module_default = makeModuleCommand;
2585
2729
 
2586
2730
  // packages/cli/src/commands/make-queue.ts
2587
- import { resolve as resolve14 } from "path";
2731
+ import { resolve as resolve15 } from "path";
2588
2732
  var WORKER_TEMPLATE = `
2589
2733
  import { Inject, Injectable } from '@nexusts/core';
2590
2734
  import { QueueService, OnQueueReady } from '@nexusts/queue';
@@ -2712,7 +2856,7 @@ var makeQueueCommand = {
2712
2856
  name: variants.pascal,
2713
2857
  kebab: variants.kebab
2714
2858
  });
2715
- const out = resolve14(ctx.cwd, "app/queue/workers", `${variants.kebab}.worker.ts`);
2859
+ const out = resolve15(ctx.cwd, "app/queue/workers", `${variants.kebab}.worker.ts`);
2716
2860
  if (writeFile(out, code, { skipIfExists: true })) {
2717
2861
  logger.success(`created ${out}`);
2718
2862
  } else {
@@ -2724,7 +2868,7 @@ var makeQueueCommand = {
2724
2868
  name: variants.pascal,
2725
2869
  kebab: variants.kebab
2726
2870
  });
2727
- const out = resolve14(ctx.cwd, "app/queue/jobs", `${variants.kebab}.job.ts`);
2871
+ const out = resolve15(ctx.cwd, "app/queue/jobs", `${variants.kebab}.job.ts`);
2728
2872
  if (writeFile(out, code, { skipIfExists: true })) {
2729
2873
  logger.success(`created ${out}`);
2730
2874
  } else {
@@ -2748,7 +2892,7 @@ var make_queue_default = makeQueueCommand;
2748
2892
 
2749
2893
  // packages/cli/src/commands/make-repository.ts
2750
2894
  import { mkdirSync as mkdirSync4 } from "fs";
2751
- import { resolve as resolve15, dirname as dirname4 } from "path";
2895
+ import { resolve as resolve16, dirname as dirname4 } from "path";
2752
2896
  var makeRepositoryCommand = {
2753
2897
  name: "make:repository",
2754
2898
  aliases: ["mr", "make-repository", "make:repo"],
@@ -2773,7 +2917,7 @@ var makeRepositoryCommand = {
2773
2917
  snake: variants.snake,
2774
2918
  repository
2775
2919
  });
2776
- const out = resolve15(ctx.cwd, `${ctx.config.paths.app}/repositories`, `${variants.kebab}.repository.ts`);
2920
+ const out = resolve16(ctx.cwd, `${ctx.config.paths.app}/repositories`, `${variants.kebab}.repository.ts`);
2777
2921
  mkdirSync4(dirname4(out), { recursive: true });
2778
2922
  writeFile(out, code);
2779
2923
  logger.success(`created ${out}`);
@@ -2783,7 +2927,7 @@ var makeRepositoryCommand = {
2783
2927
  var make_repository_default = makeRepositoryCommand;
2784
2928
 
2785
2929
  // packages/cli/src/commands/make-schedule.ts
2786
- import { resolve as resolve16 } from "path";
2930
+ import { resolve as resolve17 } from "path";
2787
2931
  var TASK_TEMPLATE = `
2788
2932
  import { Injectable } from '@nexusts/core';
2789
2933
  import { Cron, Interval, Timeout } from '@nexusts/schedule';
@@ -2827,7 +2971,7 @@ var makeScheduleCommand = {
2827
2971
  name: variants.pascal,
2828
2972
  kebab: variants.kebab
2829
2973
  });
2830
- const out = resolve16(ctx.cwd, "app/schedule/tasks", `${variants.kebab}.task.ts`);
2974
+ const out = resolve17(ctx.cwd, "app/schedule/tasks", `${variants.kebab}.task.ts`);
2831
2975
  if (writeFile(out, code, { skipIfExists: true })) {
2832
2976
  logger.success(`created ${out}`);
2833
2977
  } else {
@@ -2845,7 +2989,7 @@ var makeScheduleCommand = {
2845
2989
  var make_schedule_default = makeScheduleCommand;
2846
2990
 
2847
2991
  // packages/cli/src/commands/make-service.ts
2848
- import { resolve as resolve17 } from "path";
2992
+ import { resolve as resolve18 } from "path";
2849
2993
  var makeServiceCommand = {
2850
2994
  name: "make:service",
2851
2995
  aliases: ["ms", "make-service"],
@@ -2877,7 +3021,7 @@ var makeServiceCommand = {
2877
3021
  repository,
2878
3022
  repositoryCamel
2879
3023
  });
2880
- const out = resolve17(ctx.cwd, ctx.config.paths.services, `${variants.kebab}.service.ts`);
3024
+ const out = resolve18(ctx.cwd, ctx.config.paths.services, `${variants.kebab}.service.ts`);
2881
3025
  writeFile(out, code);
2882
3026
  logger.success(`created ${out}`);
2883
3027
  return 0;
@@ -2886,7 +3030,7 @@ var makeServiceCommand = {
2886
3030
  var make_service_default = makeServiceCommand;
2887
3031
 
2888
3032
  // packages/cli/src/commands/make-session.ts
2889
- import { resolve as resolve18 } from "path";
3033
+ import { resolve as resolve19 } from "path";
2890
3034
  var SESSION_TEMPLATE = `
2891
3035
  import { Inject, Injectable } from '@nexusts/core';
2892
3036
  import { SessionService } from '@nexusts/session';
@@ -2948,7 +3092,7 @@ var makeSessionCommand = {
2948
3092
  name: variants.pascal,
2949
3093
  kebab: variants.kebab
2950
3094
  });
2951
- const out = resolve18(ctx.cwd, "app/session/services", `${variants.kebab}.session.ts`);
3095
+ const out = resolve19(ctx.cwd, "app/session/services", `${variants.kebab}.session.ts`);
2952
3096
  if (writeFile(out, code, { skipIfExists: true })) {
2953
3097
  logger.success(`created ${out}`);
2954
3098
  } else {
@@ -2966,7 +3110,7 @@ var makeSessionCommand = {
2966
3110
  var make_session_default = makeSessionCommand;
2967
3111
 
2968
3112
  // packages/cli/src/commands/make-validator.ts
2969
- import { resolve as resolve19 } from "path";
3113
+ import { resolve as resolve20 } from "path";
2970
3114
  var makeValidatorCommand = {
2971
3115
  name: "make:validator",
2972
3116
  aliases: ["mv", "make-validator"],
@@ -2983,7 +3127,7 @@ var makeValidatorCommand = {
2983
3127
  const code = render(templates.validator, {
2984
3128
  name: variants.pascal
2985
3129
  });
2986
- const out = resolve19(ctx.cwd, ctx.config.paths.dto, `${variants.kebab}.dto.ts`);
3130
+ const out = resolve20(ctx.cwd, ctx.config.paths.dto, `${variants.kebab}.dto.ts`);
2987
3131
  writeFile(out, code);
2988
3132
  logger.success(`created ${out}`);
2989
3133
  return 0;
@@ -2994,7 +3138,7 @@ var make_validator_default = makeValidatorCommand;
2994
3138
  // packages/cli/src/commands/db-migrate.ts
2995
3139
  import { spawn } from "child_process";
2996
3140
  import { existsSync as existsSync5 } from "fs";
2997
- import { resolve as resolve20 } from "path";
3141
+ import { resolve as resolve21 } from "path";
2998
3142
  var dbMigrateCommand = {
2999
3143
  name: "db:migrate",
3000
3144
  aliases: ["db:m", "migrate"],
@@ -3029,9 +3173,9 @@ var dbMigrateCommand = {
3029
3173
  }
3030
3174
  ],
3031
3175
  async run(ctx) {
3032
- const folder = ctx.flags["folder"] ?? resolve20(ctx.cwd, ctx.config.paths.migrations);
3176
+ const folder = ctx.flags["folder"] ?? resolve21(ctx.cwd, ctx.config.paths.migrations);
3033
3177
  const dialect = ctx.flags["dialect"] ?? ctx.config.dialect ?? "bun-sqlite";
3034
- const configPath = ctx.flags["config"] ?? resolve20(ctx.cwd, "drizzle.config.ts");
3178
+ const configPath = ctx.flags["config"] ?? resolve21(ctx.cwd, "drizzle.config.ts");
3035
3179
  const wantStatus = Boolean(ctx.flags["status"]);
3036
3180
  const generateName = ctx.flags["generate"];
3037
3181
  if (generateName) {
@@ -3092,7 +3236,7 @@ const applied = await svc.appliedMigrations();
3092
3236
  console.log(JSON.stringify({ total: applied.length, applied }, null, 2));
3093
3237
  await svc.close();
3094
3238
  `;
3095
- const tmpFile = resolve20(cwd, ".nx-migrate-status.mjs");
3239
+ const tmpFile = resolve21(cwd, ".nx-migrate-status.mjs");
3096
3240
  await import("fs/promises").then((m) => m.writeFile(tmpFile, script, "utf-8"));
3097
3241
  try {
3098
3242
  const code = await new Promise((resP) => {
@@ -3116,7 +3260,7 @@ function readEnvUrl(dialect) {
3116
3260
  var db_migrate_default = dbMigrateCommand;
3117
3261
 
3118
3262
  // packages/cli/src/commands/db-generate.ts
3119
- import { resolve as resolve21 } from "path";
3263
+ import { resolve as resolve22 } from "path";
3120
3264
  var dbGenerateCommand = {
3121
3265
  name: "db:generate",
3122
3266
  aliases: ["db:g", "db-generate", "generate-migration"],
@@ -3149,7 +3293,7 @@ var dbGenerateCommand = {
3149
3293
  logger.info(`Generating raw SQL migration: ${name} (dialect=${dialect})`);
3150
3294
  return runSqlTemplate(ctx.cwd, name, dialect);
3151
3295
  }
3152
- const configPath = resolve21(ctx.cwd, "drizzle.config.ts");
3296
+ const configPath = resolve22(ctx.cwd, "drizzle.config.ts");
3153
3297
  const args2 = ["generate", "--config", configPath];
3154
3298
  if (name)
3155
3299
  args2.push("--name", name);
@@ -3158,7 +3302,7 @@ var dbGenerateCommand = {
3158
3302
  }
3159
3303
  };
3160
3304
  async function runSqlTemplate(cwd, name, dialect) {
3161
- const { mkdirSync: mkdirSync5, writeFileSync: writeFileSync3 } = await import("fs");
3305
+ const { mkdirSync: mkdirSync5, writeFileSync: writeFileSync4 } = await import("fs");
3162
3306
  const { join } = await import("path");
3163
3307
  const migrationsDir = join(cwd, "app", "database", "migrations");
3164
3308
  mkdirSync5(migrationsDir, { recursive: true });
@@ -3174,7 +3318,7 @@ async function runSqlTemplate(cwd, name, dialect) {
3174
3318
  -- Generated: ${new Date().toISOString()}
3175
3319
 
3176
3320
  `;
3177
- writeFileSync3(filepath, header);
3321
+ writeFileSync4(filepath, header);
3178
3322
  logger.success(`created ${filepath}`);
3179
3323
  logger.info("Edit the SQL file, then run `nx db:migrate` to apply it.");
3180
3324
  return 0;
@@ -3185,7 +3329,7 @@ var db_generate_default = dbGenerateCommand;
3185
3329
  import { spawn as spawn2 } from "child_process";
3186
3330
  import { existsSync as existsSync6 } from "fs";
3187
3331
  import { mkdir, readdir, writeFile as writeFile2, unlink } from "fs/promises";
3188
- import { resolve as resolve22 } from "path";
3332
+ import { resolve as resolve23 } from "path";
3189
3333
  var SEED_TEMPLATE = `/**
3190
3334
  * Seed: {name}
3191
3335
  *
@@ -3255,7 +3399,7 @@ var dbSeedCommand = {
3255
3399
  }
3256
3400
  ],
3257
3401
  async run(ctx) {
3258
- const folder = resolve22(ctx.cwd, ctx.flags["folder"] ?? ctx.config.paths?.seeds ?? "db/seeds");
3402
+ const folder = resolve23(ctx.cwd, ctx.flags["folder"] ?? ctx.config.paths?.seeds ?? "db/seeds");
3259
3403
  const dialect = ctx.flags["dialect"] ?? ctx.config.dialect ?? "bun-sqlite";
3260
3404
  const createName = ctx.flags["create"];
3261
3405
  const fileName = ctx.flags["file"];
@@ -3266,7 +3410,7 @@ var dbSeedCommand = {
3266
3410
  if (!existsSync6(folder)) {
3267
3411
  logger.info(`creating empty seeds folder at ${folder}`);
3268
3412
  await mkdir(folder, { recursive: true });
3269
- await writeFile2(resolve22(folder, "_README.ts"), `// Seed files go here. Run with: nx db:seed
3413
+ await writeFile2(resolve23(folder, "_README.ts"), `// Seed files go here. Run with: nx db:seed
3270
3414
  `, "utf-8");
3271
3415
  return 0;
3272
3416
  }
@@ -3290,7 +3434,7 @@ var dbSeedCommand = {
3290
3434
  if (reset) {
3291
3435
  logger.warn("--reset is set: truncating every table in the schema before running seeds.");
3292
3436
  }
3293
- const seedImports = target.map((f, i) => `import seed_${i} from ${JSON.stringify(resolve22(folder, f))};`).join(`
3437
+ const seedImports = target.map((f, i) => `import seed_${i} from ${JSON.stringify(resolve23(folder, f))};`).join(`
3294
3438
  `);
3295
3439
  const seedCalls = target.map((_, i) => ` await seed_${i}({ db, logger, dialect, truncate: (t) => db.truncate(t) });`).join(`
3296
3440
  `);
@@ -3324,7 +3468,7 @@ ${seedCalls}
3324
3468
  await db.close();
3325
3469
  logger.info(\`Seeds complete (\${${target.length}} file(s))\`);
3326
3470
  `;
3327
- const tmpFile = resolve22(ctx.cwd, ".nx-db-seed.mjs");
3471
+ const tmpFile = resolve23(ctx.cwd, ".nx-db-seed.mjs");
3328
3472
  await writeFile2(tmpFile, script, "utf-8");
3329
3473
  try {
3330
3474
  const code = await new Promise((resP) => {
@@ -3366,11 +3510,11 @@ async function createSeedFile(folder, name) {
3366
3510
  await mkdir(folder, { recursive: true });
3367
3511
  let candidate = `${name}.ts`;
3368
3512
  let i = 1;
3369
- while (existsSync6(resolve22(folder, candidate))) {
3513
+ while (existsSync6(resolve23(folder, candidate))) {
3370
3514
  candidate = `${name}_${i}.ts`;
3371
3515
  i++;
3372
3516
  }
3373
- const path = resolve22(folder, candidate);
3517
+ const path = resolve23(folder, candidate);
3374
3518
  const body = SEED_TEMPLATE.replace(/\{name\}/g, name);
3375
3519
  await writeFile2(path, body, "utf-8");
3376
3520
  logger.info(`created ${path}`);
@@ -3383,8 +3527,34 @@ function readEnvUrl2(dialect) {
3383
3527
  var db_seed_default = dbSeedCommand;
3384
3528
 
3385
3529
  // packages/cli/src/commands/new.ts
3386
- import { existsSync as existsSync7, mkdirSync as mkdirSync5, writeFileSync as writeFileSync3 } from "fs";
3387
- import { resolve as resolve23 } from "path";
3530
+ import { existsSync as existsSync7, mkdirSync as mkdirSync5, writeFileSync as writeFileSync4 } from "fs";
3531
+ import { resolve as resolve24 } from "path";
3532
+ var VALID_OPTIONS2 = {
3533
+ style: ["nest", "adonis", "functional"],
3534
+ view: ["rendu", "edge", "eta", "inertia", "none"],
3535
+ orm: ["drizzle", "prisma", "kysely", "none"],
3536
+ db: ["bun-sqlite", "node-sqlite", "libsql", "postgres", "mysql", "none"],
3537
+ frontend: ["react", "vue", "svelte", "solid"]
3538
+ };
3539
+ async function resolveOpt2(flags, key, valid, defaultVal, interactive) {
3540
+ const flagVal = flags[key];
3541
+ if (flagVal) {
3542
+ if (valid.includes(flagVal))
3543
+ return flagVal;
3544
+ if (!interactive) {
3545
+ logger.error(`Invalid --${key} "${flagVal}". Valid values: ${valid.join(", ")}`);
3546
+ process.exit(1);
3547
+ }
3548
+ logger.warn(`"${flagVal}" is not valid for --${key}. Please choose from the list.`);
3549
+ }
3550
+ const label = key === "style" ? "Routing style" : key === "view" ? "View engine" : key === "orm" ? "ORM driver" : key === "db" ? "Database driver" : "Inertia frontend";
3551
+ for (;; ) {
3552
+ const answer = await select(label, [...valid], { default: defaultVal });
3553
+ if (valid.includes(answer))
3554
+ return answer;
3555
+ logger.warn(`"${answer}" is not valid. Please choose from: ${valid.join(", ")}`);
3556
+ }
3557
+ }
3388
3558
  var newCommand = {
3389
3559
  name: "new",
3390
3560
  aliases: ["n"],
@@ -3392,131 +3562,38 @@ var newCommand = {
3392
3562
  description: "Generates a new project directory with nx.config.ts, tsconfig, package.json, and a starter app/main.ts.",
3393
3563
  examples: [
3394
3564
  "nx new my-app",
3395
- "nx new my-app --style nest --view rendu --orm drizzle --db bun-sqlite"
3565
+ "nx new my-app --view inertia --frontend vue"
3396
3566
  ],
3397
3567
  flags: [
3398
- {
3399
- name: "style",
3400
- description: "Routing style (nest|adonis|functional|mixed)"
3401
- },
3568
+ { name: "style", description: "Routing style (nest|adonis|functional)" },
3402
3569
  { name: "view", description: "View engine (rendu|edge|eta|inertia|none)" },
3403
3570
  { name: "orm", description: "ORM driver (drizzle|prisma|kysely|none)" },
3404
- {
3405
- name: "db",
3406
- description: "Database driver (bun-sqlite|node-sqlite|libsql|postgres|mysql|none)"
3407
- },
3408
- {
3409
- name: "frontend",
3410
- description: "Inertia frontend (react|vue|svelte|solid)"
3411
- },
3412
- { name: "no-ssr", description: "Disable Inertia SSR" },
3413
- { name: "no-interaction", description: "Disable interactive prompts" }
3571
+ { name: "db", description: "Database driver" },
3572
+ { name: "frontend", description: "Inertia frontend (react|vue|svelte|solid)" },
3573
+ { name: "no-ssr", description: "Disable SSR" }
3414
3574
  ],
3415
3575
  async run(ctx) {
3416
3576
  const name = ctx.positional[0];
3417
3577
  if (!name) {
3418
- logger.error("Usage: nx new <project-name>");
3578
+ logger.error("Usage: nx new <name>");
3419
3579
  return 1;
3420
3580
  }
3421
- const interactive = !flagBool(ctx.flags, "no-interaction", false);
3422
- const target = resolve23(ctx.cwd, name);
3581
+ const interactive = flagBool(ctx.flags, "interaction", true);
3582
+ const target = resolve24(ctx.cwd, name);
3423
3583
  if (existsSync7(target)) {
3424
- logger.error(`Directory already exists: ${target}`);
3584
+ logger.error(`Directory "${name}" already exists.`);
3425
3585
  return 1;
3426
3586
  }
3427
- const routing = ctx.flags["style"] ?? await select("Routing style", ["nest", "adonis", "functional"], {
3428
- interactive,
3429
- default: "nest"
3430
- });
3431
- const view = ctx.flags["view"] ?? await select("View engine", ["rendu", "edge", "eta", "inertia", "none"], {
3432
- interactive,
3433
- default: "rendu"
3434
- });
3435
- const orm = ctx.flags["orm"] ?? await select("ORM driver", ["drizzle", "prisma", "kysely", "none"], {
3436
- interactive,
3437
- default: "drizzle"
3438
- });
3439
- const db = ctx.flags["db"] ?? await select("Database driver", ["bun-sqlite", "node-sqlite", "libsql", "postgres", "mysql", "none"], {
3440
- interactive,
3441
- default: "bun-sqlite"
3442
- });
3443
- const frontend = ctx.flags["frontend"] ?? await select("Inertia frontend", ["react", "vue", "svelte", "solid"], {
3444
- interactive,
3445
- default: "react"
3446
- });
3587
+ const routing = await resolveOpt2(ctx.flags, "style", VALID_OPTIONS2.style, "nest", interactive);
3588
+ const view = await resolveOpt2(ctx.flags, "view", VALID_OPTIONS2.view, "rendu", interactive);
3589
+ const orm = await resolveOpt2(ctx.flags, "orm", VALID_OPTIONS2.orm, "drizzle", interactive);
3590
+ const db = await resolveOpt2(ctx.flags, "db", VALID_OPTIONS2.db, "bun-sqlite", interactive);
3591
+ const frontend = await resolveOpt2(ctx.flags, "frontend", VALID_OPTIONS2.frontend, "react", interactive);
3447
3592
  const ssr = !flagBool(ctx.flags, "no-ssr", false);
3448
- mkdirSync5(resolve23(target, "app"), { recursive: true });
3449
- if (view !== "none") {
3450
- mkdirSync5(resolve23(target, "resources/views"), { recursive: true });
3451
- }
3452
- mkdirSync5(resolve23(target, "public"), { recursive: true });
3453
- writeFileSync3(resolve23(target, "public/.gitkeep"), "");
3454
- if (view !== "none") {
3455
- writeFileSync3(resolve23(target, "resources/views/welcome.html"), `<h1>Welcome to ${name}</h1>
3456
- <p>This is a sample Rendu template.</p>
3457
- <p>Founded <?= year ?>.</p>
3458
- `);
3459
- }
3460
- writeFileSync3(resolve23(target, ".env"), generateEnvFile());
3461
- writeFileSync3(resolve23(target, ".env.local"), generateEnvLocalFile());
3462
- writeFileSync3(resolve23(target, ".gitignore"), generateGitIgnore());
3463
- const code = render(templates.project["nx.config.ts"], {
3464
- routing,
3465
- view,
3466
- viewPaths: view === "none" ? "" : "resources/views",
3467
- orm,
3468
- dbDriver: db,
3469
- dbUrl: db === "bun-sqlite" || db === "node-sqlite" ? "app.db" : "",
3470
- inertiaFrontend: frontend,
3471
- inertiaSSR: ssr,
3472
- inertiaVersion: "1.0.0"
3473
- });
3474
- writeFileSync3(resolve23(target, "nx.config.ts"), code);
3475
- if (orm === "drizzle") {
3476
- const dialect = db === "bun-sqlite" || db === "node-sqlite" || db === "libsql" ? "sqlite" : db === "postgres" ? "postgresql" : "sqlite";
3477
- const drizzleConfig = render(templates.project["drizzle.config.ts"], {
3478
- dialect,
3479
- dbUrl: db === "bun-sqlite" || db === "node-sqlite" ? "app.db" : ""
3480
- });
3481
- writeFileSync3(resolve23(target, "drizzle.config.ts"), drizzleConfig);
3482
- }
3483
- const deps = {
3484
- "@nexusts/core": "*",
3485
- "reflect-metadata": "^0.2.2",
3486
- hono: "^4.6.0",
3487
- zod: "^3.23.8"
3488
- };
3489
- if (orm === "drizzle") {
3490
- deps["@nexusts/drizzle"] = "*";
3491
- deps["drizzle-orm"] = "^0.45.0";
3492
- if (db === "postgres")
3493
- deps["pg"] = "^8.13.0";
3494
- if (db === "mysql")
3495
- deps["mysql2"] = "^3.11.0";
3496
- if (db === "sqlite" || db === "node-sqlite" || db === "bun-sqlite")
3497
- deps["better-sqlite3"] = "^12.0.0";
3498
- }
3499
- if (view !== "none") {
3500
- deps["@nexusts/static"] = "*";
3501
- }
3502
- const pkgJson = {
3503
- name,
3504
- version: "0.1.0",
3505
- type: "module",
3506
- scripts: {
3507
- dev: "bun --hot app/main.ts",
3508
- build: "bun run build.ts",
3509
- start: "bun app/main.ts",
3510
- test: "vitest",
3511
- nx: "nx"
3512
- },
3513
- dependencies: deps
3514
- };
3515
- if (orm === "drizzle") {
3516
- pkgJson.devDependencies = { "drizzle-kit": "^0.31.0" };
3517
- }
3518
- writeFileSync3(resolve23(target, "package.json"), JSON.stringify(pkgJson, null, 2));
3519
- writeFileSync3(resolve23(target, "tsconfig.json"), `{
3593
+ mkdirSync5(target, { recursive: true });
3594
+ const dbUrl = db === "bun-sqlite" || db === "node-sqlite" ? "app.db" : "";
3595
+ ensureDirectories(target, view);
3596
+ writeFileSync4(resolve24(target, "tsconfig.json"), `{
3520
3597
  "compilerOptions": {
3521
3598
  "target": "ES2022",
3522
3599
  "module": "ESNext",
@@ -3526,81 +3603,22 @@ var newCommand = {
3526
3603
  "strict": true,
3527
3604
  "esModuleInterop": true,
3528
3605
  "skipLibCheck": true,
3529
- "types": ["bun-types"]
3606
+ "types": ["@types/bun"]
3530
3607
  },
3531
3608
  "include": ["app/**/*.ts", "nx.config.ts"]
3532
3609
  }
3533
3610
  `);
3534
- const hasView = view !== "none";
3535
- const staticImport = hasView ? `import { StaticModule } from '@nexusts/static';
3536
- const staticMiddleware = StaticModule.mount({ root: './public', prefix: '/static' });
3537
- ` : "";
3538
- const staticOption = hasView ? `
3539
- middleware: [staticMiddleware],` : "";
3540
- writeFileSync3(resolve23(target, "app/main.ts"), `import 'reflect-metadata';
3541
- import { Application } from '@nexusts/core';
3542
- ${staticImport}import { AppModule } from './app.module.js';
3543
-
3544
- const app = new Application(AppModule, {
3545
- logging: true,
3546
- port: Number(process.env['PORT'] ?? 3000),${staticOption}
3547
- });
3548
-
3549
- await app.listen();
3550
- console.log('[nexus] Listening on http://localhost:' + (process.env['PORT'] ?? 3000));
3551
- `);
3552
- const ormImport = orm === "drizzle" ? `import { DrizzleModule } from '@nexusts/drizzle';
3553
- ` : "";
3554
- const forRootDialect = db === "bun-sqlite" ? "bun-sqlite" : "sqlite";
3555
- const ormBlock = orm === "drizzle" ? ` DrizzleModule.forRoot({
3556
- dialect: '${forRootDialect}',
3557
- connection: { filename: 'app.db' },
3558
- logging: true,
3559
- })` : "";
3560
- writeFileSync3(resolve23(target, "app/app.module.ts"), `${ormImport}import { Module } from '@nexusts/core';
3561
- import { HomeController } from './controllers/home.controller.js';
3562
-
3563
- @Module({
3564
- imports: [${orm === "drizzle" ? `
3565
- ${ormBlock},
3566
- ` : ""} ],
3567
- controllers: [HomeController],
3568
- })
3569
- export class AppModule {}
3570
- `);
3571
- mkdirSync5(resolve23(target, "app/controllers"), { recursive: true });
3572
- const homeViewReturn = view !== "none" ? `{
3573
- view: 'welcome.html',
3574
- data: { year: new Date().getFullYear() },
3575
- }` : `{ status: 200, body: { message: 'Hello from NexusTS!' } }`;
3576
- writeFileSync3(resolve23(target, "app/controllers/home.controller.ts"), `import { Controller, Get } from '@nexusts/core';
3577
-
3578
- @Controller('/')
3579
- export class HomeController {
3580
- @Get('/')
3581
- index() {
3582
- return ${homeViewReturn};
3583
- }
3584
- }
3585
- `);
3586
- writeFileSync3(resolve23(target, "README.md"), `# ${name}
3587
-
3588
- A new NexusTS project.
3589
-
3590
- ## Run
3591
-
3592
- \`\`\`bash
3593
- bun install
3594
- bun run dev
3595
- \`\`\`
3596
-
3597
- ## Scaffolding
3598
-
3599
- \`\`\`bash
3600
- bunx nx make:crud Post
3601
- \`\`\`
3611
+ const { deps, devDeps } = computeDeps(view, orm, db, frontend);
3612
+ const pkgJson = buildPackageJson(name, deps, devDeps, view, frontend);
3613
+ writeFileSync4(resolve24(target, "package.json"), JSON.stringify(pkgJson, null, 2) + `
3602
3614
  `);
3603
- logger.success(`created ${target}`);
3615
+ const opts = { target, name, routing, view, orm, db, frontend, ssr, dbUrl };
3616
+ const files = generateProjectFiles(target, opts);
3617
+ logger.success(`created ${name}`);
3618
+ for (const f of files)
3619
+ logger.info(` + ${f}`);
3620
+ logger.info(` + tsconfig.json`);
3621
+ logger.info(` + package.json`);
3604
3622
  logger.blank();
3605
3623
  logger.heading("Next steps");
3606
3624
  logger.info(` cd ${name}`);
@@ -3610,62 +3628,11 @@ bunx nx make:crud Post
3610
3628
  return 0;
3611
3629
  }
3612
3630
  };
3613
- function generateEnvFile() {
3614
- return `# \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
3615
- # NexusTS \u2014 Environment Variables (committed to git)
3616
- #
3617
- # Shared defaults for all environments. Override locally via
3618
- # .env.local (gitignored) or by environment via .env.{NODE_ENV}
3619
- # (e.g. .env.production, .env.development).
3620
- #
3621
- # Uncomment the database config for your driver:
3622
- # \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
3623
-
3624
- # \u2500\u2500 App \u2500\u2500
3625
- NODE_ENV=development
3626
- PORT=3000
3627
-
3628
- # \u2500\u2500 Session secret (REQUIRED) \u2500\u2500
3629
- # Generate with: openssl rand -base64 32
3630
- SESSION_SECRET=change-me-in-production
3631
-
3632
- # \u2500\u2500 Database: SQLite (default, zero config) \u2500\u2500
3633
- DATABASE_URL=app.db
3634
-
3635
- # \u2500\u2500 Database: PostgreSQL \u2500\u2500
3636
- # DATABASE_URL=postgres://user:password@localhost:5432/myapp
3637
-
3638
- # \u2500\u2500 Database: MySQL \u2500\u2500
3639
- # DATABASE_URL=mysql://user:password@localhost:3306/myapp
3640
- `;
3641
- }
3642
- function generateEnvLocalFile() {
3643
- return `# \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
3644
- # NexusTS \u2014 Local Overrides (DO NOT COMMIT to git)
3645
- #
3646
- # This file is gitignored. Use it for secrets and local
3647
- # configuration that should never be checked in.
3648
- # \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
3649
-
3650
- # Override any value from .env here:
3651
- # DATABASE_URL=postgres://user:password@localhost:5432/myapp
3652
- # SESSION_SECRET=my-local-secret
3653
- `;
3654
- }
3655
- function generateGitIgnore() {
3656
- return `# NexusTS
3657
- node_modules/
3658
- app.db
3659
- *.db
3660
- .env.local
3661
- dist/
3662
- `;
3663
- }
3664
3631
  var new_default = newCommand;
3665
3632
 
3666
3633
  // packages/cli/src/commands/config.ts
3667
- import { existsSync as existsSync8, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
3668
- import { resolve as resolve24 } from "path";
3634
+ import { existsSync as existsSync8, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "fs";
3635
+ import { resolve as resolve25 } from "path";
3669
3636
  var DEFAULT_VALUES = {
3670
3637
  routing: "nest",
3671
3638
  view: "rendu",
@@ -3780,12 +3747,12 @@ var configCommand = {
3780
3747
  async run(ctx) {
3781
3748
  const interactive = !flagBool(ctx.flags, "no-interaction", false);
3782
3749
  const force = flagBool(ctx.flags, "force", false);
3783
- const target = resolve24(ctx.cwd, ctx.flags["target"] ?? ".");
3750
+ const target = resolve25(ctx.cwd, ctx.flags["target"] ?? ".");
3784
3751
  if (!existsSync8(target)) {
3785
3752
  logger.error(`Target directory does not exist: ${target}`);
3786
3753
  return 1;
3787
3754
  }
3788
- const nxConfigPath = resolve24(target, "nx.config.ts");
3755
+ const nxConfigPath = resolve25(target, "nx.config.ts");
3789
3756
  const values = parseExistingConfig(nxConfigPath);
3790
3757
  const flag = (k) => ctx.flags[k];
3791
3758
  const flagBoolStrict = (k, def) => flagBool(ctx.flags, k, def);
@@ -3840,7 +3807,7 @@ var configCommand = {
3840
3807
  writeNxConfig(target, values);
3841
3808
  logger.info(` + nx.config.ts`);
3842
3809
  }
3843
- const drizzleConfigPath = resolve24(target, "drizzle.config.ts");
3810
+ const drizzleConfigPath = resolve25(target, "drizzle.config.ts");
3844
3811
  if (values.orm === "drizzle") {
3845
3812
  const dialect = driverToDialect(values.dbDriver);
3846
3813
  const dbUrl = values.dbUrl;
@@ -3868,11 +3835,11 @@ var configCommand = {
3868
3835
  };
3869
3836
  function writeNxConfig(target, values) {
3870
3837
  const code = render(templates.project["nx.config.ts"], values);
3871
- writeFileSync4(resolve24(target, "nx.config.ts"), code);
3838
+ writeFileSync5(resolve25(target, "nx.config.ts"), code);
3872
3839
  }
3873
3840
  function writeDrizzleConfig(target, values) {
3874
3841
  const code = render(templates.project["drizzle.config.ts"], values);
3875
- writeFileSync4(resolve24(target, "drizzle.config.ts"), code);
3842
+ writeFileSync5(resolve25(target, "drizzle.config.ts"), code);
3876
3843
  }
3877
3844
  var config_default = configCommand;
3878
3845
 
@@ -3881,9 +3848,9 @@ import {
3881
3848
  existsSync as existsSync9,
3882
3849
  mkdirSync as mkdirSync6,
3883
3850
  readFileSync as readFileSync6,
3884
- writeFileSync as writeFileSync5
3851
+ writeFileSync as writeFileSync6
3885
3852
  } from "fs";
3886
- import { dirname as dirname5, resolve as resolve25 } from "path";
3853
+ import { dirname as dirname5, resolve as resolve26 } from "path";
3887
3854
  import * as readline from "readline";
3888
3855
  import * as vm from "vm";
3889
3856
  var BANNER = (() => {
@@ -3965,10 +3932,10 @@ var replCommand = {
3965
3932
  async run(ctx) {
3966
3933
  const mod = ctx.flags["module"];
3967
3934
  const noBoot = Boolean(ctx.flags["no-boot"]);
3968
- const histPath = resolve25(ctx.cwd, ctx.flags["history"] ?? ".nx-repl-history");
3935
+ const histPath = resolve26(ctx.cwd, ctx.flags["history"] ?? ".nx-repl-history");
3969
3936
  const env = { console };
3970
3937
  if (!noBoot) {
3971
- const modPath = resolve25(ctx.cwd, mod ?? "app/app.module.ts");
3938
+ const modPath = resolve26(ctx.cwd, mod ?? "app/app.module.ts");
3972
3939
  if (!existsSync9(modPath)) {
3973
3940
  logger.error(`module not found: ${modPath}`);
3974
3941
  logger.info("pass --module <path> or --no-boot to skip booting");
@@ -4286,7 +4253,7 @@ function saveHistoryFile(path, history) {
4286
4253
  const dir = dirname5(path);
4287
4254
  if (!existsSync9(dir))
4288
4255
  mkdirSync6(dir, { recursive: true });
4289
- writeFileSync5(path, history.slice(-1000).join(`
4256
+ writeFileSync6(path, history.slice(-1000).join(`
4290
4257
  `));
4291
4258
  } catch {}
4292
4259
  }
@@ -4294,7 +4261,7 @@ var repl_default = replCommand;
4294
4261
 
4295
4262
  // packages/cli/src/commands/route-list.ts
4296
4263
  import { readdirSync, statSync as statSync2 } from "fs";
4297
- import { resolve as resolve26 } from "path";
4264
+ import { resolve as resolve27 } from "path";
4298
4265
  var routeListCommand = {
4299
4266
  name: "route:list",
4300
4267
  aliases: ["routes", "route-list"],
@@ -4304,7 +4271,7 @@ var routeListCommand = {
4304
4271
  { name: "format", description: "Output format: table (default) | json" }
4305
4272
  ],
4306
4273
  async run(ctx) {
4307
- const controllersDir = resolve26(ctx.cwd, ctx.config.paths.controllers);
4274
+ const controllersDir = resolve27(ctx.cwd, ctx.config.paths.controllers);
4308
4275
  try {
4309
4276
  statSync2(controllersDir);
4310
4277
  } catch {
@@ -4318,7 +4285,7 @@ var routeListCommand = {
4318
4285
  }
4319
4286
  const routes = [];
4320
4287
  for (const file of files) {
4321
- const fullPath = resolve26(controllersDir, file);
4288
+ const fullPath = resolve27(controllersDir, file);
4322
4289
  try {
4323
4290
  const mod = await import(`${fullPath}?t=${Date.now()}`);
4324
4291
  for (const exportName of Object.keys(mod)) {
@@ -4520,5 +4487,5 @@ main().then((code) => process.exit(code)).catch((err) => {
4520
4487
  process.exit(1);
4521
4488
  });
4522
4489
 
4523
- //# debugId=398828C274DA323A64756E2164756E21
4490
+ //# debugId=C2DE7496FA294EC464756E2164756E21
4524
4491
  //# sourceMappingURL=index.js.map