@nexusts/cli 0.7.4 → 0.7.6

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
@@ -518,7 +518,7 @@ var infoCommand = {
518
518
  summary: "Show project configuration",
519
519
  description: "Prints the resolved nx.config.ts plus relevant env vars.",
520
520
  async run(ctx) {
521
- logger.heading("Nexus CLI \u2014 Project Info");
521
+ logger.heading("NexusTS CLI \u2014 Project Info");
522
522
  logger.info(colors.bold("Resolved configuration"));
523
523
  logger.blank();
524
524
  logger.table([
@@ -978,7 +978,7 @@ export class {{ name }}Module {}
978
978
 
979
979
  // packages/cli/src/templates/project/nx.config.ts
980
980
  var nx_config_default = `/**
981
- * Nexus project configuration.
981
+ * NexusTS project configuration.
982
982
  * Run \`nx info\` to see the resolved values.
983
983
  */
984
984
 
@@ -1235,6 +1235,7 @@ var initCommand = {
1235
1235
  { path: ".env", mode: "skip" },
1236
1236
  { path: ".env.local", mode: "skip" },
1237
1237
  { path: ".gitignore", mode: "skip" },
1238
+ ...orm === "drizzle" ? [{ path: "drizzle.config.ts", mode: "write" }] : [],
1238
1239
  { path: "app/main.ts", mode: "write" },
1239
1240
  { path: "app/app.module.ts", mode: "write" },
1240
1241
  { path: "app/controllers/home.controller.ts", mode: "write" },
@@ -1261,6 +1262,12 @@ var initCommand = {
1261
1262
  if (orm === "drizzle") {
1262
1263
  coreDeps["@nexusts/drizzle"] = "*";
1263
1264
  coreDeps["drizzle-orm"] = "^0.45.0";
1265
+ if (db === "postgres")
1266
+ coreDeps["pg"] = "^8.13.0";
1267
+ if (db === "mysql")
1268
+ coreDeps["mysql2"] = "^3.11.0";
1269
+ if (db === "sqlite" || db === "node-sqlite" || db === "bun-sqlite")
1270
+ coreDeps["better-sqlite3"] = "^12.0.0";
1264
1271
  }
1265
1272
  if (view !== "none") {
1266
1273
  coreDeps["@nexusts/static"] = "*";
@@ -1269,7 +1276,7 @@ var initCommand = {
1269
1276
  mergePackageJson(abs, coreDeps);
1270
1277
  merged.push(entry.path);
1271
1278
  } else {
1272
- writeFileSync2(abs, JSON.stringify({
1279
+ const pkgJson = {
1273
1280
  name: target.split("/").pop() ?? "nexus-app",
1274
1281
  version: "0.1.0",
1275
1282
  type: "module",
@@ -1282,7 +1289,13 @@ var initCommand = {
1282
1289
  nx: "nx"
1283
1290
  },
1284
1291
  dependencies: coreDeps
1285
- }, null, 2));
1292
+ };
1293
+ if (orm === "drizzle") {
1294
+ pkgJson.devDependencies = {
1295
+ "drizzle-kit": "^0.31.0"
1296
+ };
1297
+ }
1298
+ writeFileSync2(abs, JSON.stringify(pkgJson, null, 2));
1286
1299
  created.push(entry.path);
1287
1300
  }
1288
1301
  continue;
@@ -1408,6 +1421,13 @@ DATABASE_URL=app.db
1408
1421
  # DATABASE_URL=postgres://user:password@localhost:5432/myapp
1409
1422
  # SESSION_SECRET=my-local-secret
1410
1423
  `;
1424
+ case "drizzle.config.ts": {
1425
+ const dialect = ctx.dbDriver === "bun-sqlite" || ctx.dbDriver === "node-sqlite" || ctx.dbDriver === "libsql" ? "sqlite" : ctx.dbDriver === "postgres" ? "postgresql" : "sqlite";
1426
+ return render(templates.project["drizzle.config.ts"], {
1427
+ dialect,
1428
+ dbUrl: ctx.dbUrl || "app.db"
1429
+ });
1430
+ }
1411
1431
  case "app/main.ts": {
1412
1432
  const hasView = ctx.view !== "none";
1413
1433
  const staticMw = hasView ? `import { StaticModule } from '@nexusts/static';
@@ -1471,7 +1491,7 @@ export class HomeController {
1471
1491
  case "README.md":
1472
1492
  return `# ${ctx.targetName}
1473
1493
 
1474
- A Nexus project.
1494
+ A NexusTS project.
1475
1495
 
1476
1496
  ## Run
1477
1497
 
@@ -1841,7 +1861,7 @@ var DIALECT_SPECS = {
1841
1861
  idOpts: "{ autoIncrement: true }",
1842
1862
  tsTimestamp: "text",
1843
1863
  tsDateMode: "",
1844
- defaultTs: `.default("(datetime('now'))")`,
1864
+ defaultTs: ".$defaultFn(() => new Date().toISOString())",
1845
1865
  defaultTsUpdate: ""
1846
1866
  },
1847
1867
  sqlite: {
@@ -2097,7 +2117,7 @@ var makeCrudCommand = {
2097
2117
  for (const f of written)
2098
2118
  logger.info(` ${f}`);
2099
2119
  logger.info(`2. Add ${variants.pascal}Module to AppModule.imports.`);
2100
- logger.info(`3. ${noRepo ? "" : `Run \`bunx drizzle-kit migrate\` (or your migration tool).`}`);
2120
+ logger.info(`3. ${noRepo ? "" : `Run \`bun nx db:generate & bun nx db:migrate\` (or your migration tool).`}`);
2101
2121
  logger.info(`4. Start the dev server: \`bun --hot app/main.ts\`.`);
2102
2122
  logger.blank();
2103
2123
  return 0;
@@ -2295,7 +2315,7 @@ var makeMigrationCommand = {
2295
2315
  if (isDrizzle) {
2296
2316
  logger.finger(`run \`nx migrate\` to apply pending migrations.`);
2297
2317
  } else {
2298
- logger.finger(`run \`bunx drizzle-kit migrate\` or your migration tool.`);
2318
+ logger.finger(`run \`bun nx db:generate & bun nx db:migrate\` or your migration tool.`);
2299
2319
  }
2300
2320
  return 0;
2301
2321
  }
@@ -2714,8 +2734,44 @@ var makeQueueCommand = {
2714
2734
  };
2715
2735
  var make_queue_default = makeQueueCommand;
2716
2736
 
2737
+ // packages/cli/src/commands/make-repository.ts
2738
+ import { mkdirSync as mkdirSync4 } from "fs";
2739
+ import { resolve as resolve15, dirname as dirname4 } from "path";
2740
+ var makeRepositoryCommand = {
2741
+ name: "make:repository",
2742
+ aliases: ["mr", "make-repository", "make:repo"],
2743
+ summary: "Generate a repository class",
2744
+ description: "Generates a DrizzleRepository class under app/repositories/. Requires a model file at app/models/<name>.model.ts.",
2745
+ examples: [
2746
+ "nx make:repository User",
2747
+ "nx make:repository Post"
2748
+ ],
2749
+ async run(ctx) {
2750
+ const name = ctx.positional[0];
2751
+ if (!name) {
2752
+ logger.error("Usage: nx make:repository <Name>");
2753
+ return 1;
2754
+ }
2755
+ const variants = nameVariants(name);
2756
+ const repository = `${variants.pascal}Repository`;
2757
+ const code = render(templates.repository, {
2758
+ name: variants.pascal,
2759
+ camel: variants.camel,
2760
+ kebab: variants.kebab,
2761
+ snake: variants.snake,
2762
+ repository
2763
+ });
2764
+ const out = resolve15(ctx.cwd, `${ctx.config.paths.app}/repositories`, `${variants.kebab}.repository.ts`);
2765
+ mkdirSync4(dirname4(out), { recursive: true });
2766
+ writeFile(out, code);
2767
+ logger.success(`created ${out}`);
2768
+ return 0;
2769
+ }
2770
+ };
2771
+ var make_repository_default = makeRepositoryCommand;
2772
+
2717
2773
  // packages/cli/src/commands/make-schedule.ts
2718
- import { resolve as resolve15 } from "path";
2774
+ import { resolve as resolve16 } from "path";
2719
2775
  var TASK_TEMPLATE = `
2720
2776
  import { Injectable } from '@nexusts/core';
2721
2777
  import { Cron, Interval, Timeout } from '@nexusts/schedule';
@@ -2759,7 +2815,7 @@ var makeScheduleCommand = {
2759
2815
  name: variants.pascal,
2760
2816
  kebab: variants.kebab
2761
2817
  });
2762
- const out = resolve15(ctx.cwd, "app/schedule/tasks", `${variants.kebab}.task.ts`);
2818
+ const out = resolve16(ctx.cwd, "app/schedule/tasks", `${variants.kebab}.task.ts`);
2763
2819
  if (writeFile(out, code, { skipIfExists: true })) {
2764
2820
  logger.success(`created ${out}`);
2765
2821
  } else {
@@ -2777,7 +2833,7 @@ var makeScheduleCommand = {
2777
2833
  var make_schedule_default = makeScheduleCommand;
2778
2834
 
2779
2835
  // packages/cli/src/commands/make-service.ts
2780
- import { resolve as resolve16 } from "path";
2836
+ import { resolve as resolve17 } from "path";
2781
2837
  var makeServiceCommand = {
2782
2838
  name: "make:service",
2783
2839
  aliases: ["ms", "make-service"],
@@ -2804,11 +2860,12 @@ var makeServiceCommand = {
2804
2860
  name: variants.pascal,
2805
2861
  camel: variants.camel,
2806
2862
  kebab: variants.kebab,
2863
+ snake: variants.snake,
2807
2864
  hasRepo,
2808
2865
  repository,
2809
2866
  repositoryCamel
2810
2867
  });
2811
- const out = resolve16(ctx.cwd, ctx.config.paths.services, `${variants.kebab}.service.ts`);
2868
+ const out = resolve17(ctx.cwd, ctx.config.paths.services, `${variants.kebab}.service.ts`);
2812
2869
  writeFile(out, code);
2813
2870
  logger.success(`created ${out}`);
2814
2871
  return 0;
@@ -2817,7 +2874,7 @@ var makeServiceCommand = {
2817
2874
  var make_service_default = makeServiceCommand;
2818
2875
 
2819
2876
  // packages/cli/src/commands/make-session.ts
2820
- import { resolve as resolve17 } from "path";
2877
+ import { resolve as resolve18 } from "path";
2821
2878
  var SESSION_TEMPLATE = `
2822
2879
  import { Inject, Injectable } from '@nexusts/core';
2823
2880
  import { SessionService } from '@nexusts/session';
@@ -2879,7 +2936,7 @@ var makeSessionCommand = {
2879
2936
  name: variants.pascal,
2880
2937
  kebab: variants.kebab
2881
2938
  });
2882
- const out = resolve17(ctx.cwd, "app/session/services", `${variants.kebab}.session.ts`);
2939
+ const out = resolve18(ctx.cwd, "app/session/services", `${variants.kebab}.session.ts`);
2883
2940
  if (writeFile(out, code, { skipIfExists: true })) {
2884
2941
  logger.success(`created ${out}`);
2885
2942
  } else {
@@ -2897,7 +2954,7 @@ var makeSessionCommand = {
2897
2954
  var make_session_default = makeSessionCommand;
2898
2955
 
2899
2956
  // packages/cli/src/commands/make-validator.ts
2900
- import { resolve as resolve18 } from "path";
2957
+ import { resolve as resolve19 } from "path";
2901
2958
  var makeValidatorCommand = {
2902
2959
  name: "make:validator",
2903
2960
  aliases: ["mv", "make-validator"],
@@ -2914,7 +2971,7 @@ var makeValidatorCommand = {
2914
2971
  const code = render(templates.validator, {
2915
2972
  name: variants.pascal
2916
2973
  });
2917
- const out = resolve18(ctx.cwd, ctx.config.paths.dto, `${variants.kebab}.dto.ts`);
2974
+ const out = resolve19(ctx.cwd, ctx.config.paths.dto, `${variants.kebab}.dto.ts`);
2918
2975
  writeFile(out, code);
2919
2976
  logger.success(`created ${out}`);
2920
2977
  return 0;
@@ -2925,7 +2982,7 @@ var make_validator_default = makeValidatorCommand;
2925
2982
  // packages/cli/src/commands/db-migrate.ts
2926
2983
  import { spawn } from "child_process";
2927
2984
  import { existsSync as existsSync5 } from "fs";
2928
- import { resolve as resolve19 } from "path";
2985
+ import { resolve as resolve20 } from "path";
2929
2986
  var dbMigrateCommand = {
2930
2987
  name: "db:migrate",
2931
2988
  aliases: ["db:m", "migrate"],
@@ -2960,9 +3017,9 @@ var dbMigrateCommand = {
2960
3017
  }
2961
3018
  ],
2962
3019
  async run(ctx) {
2963
- const folder = ctx.flags["folder"] ?? resolve19(ctx.cwd, ctx.config.paths.migrations);
3020
+ const folder = ctx.flags["folder"] ?? resolve20(ctx.cwd, ctx.config.paths.migrations);
2964
3021
  const dialect = ctx.flags["dialect"] ?? ctx.config.dialect ?? "bun-sqlite";
2965
- const configPath = ctx.flags["config"] ?? resolve19(ctx.cwd, "drizzle.config.ts");
3022
+ const configPath = ctx.flags["config"] ?? resolve20(ctx.cwd, "drizzle.config.ts");
2966
3023
  const wantStatus = Boolean(ctx.flags["status"]);
2967
3024
  const generateName = ctx.flags["generate"];
2968
3025
  if (generateName) {
@@ -3023,7 +3080,7 @@ const applied = await svc.appliedMigrations();
3023
3080
  console.log(JSON.stringify({ total: applied.length, applied }, null, 2));
3024
3081
  await svc.close();
3025
3082
  `;
3026
- const tmpFile = resolve19(cwd, ".nx-migrate-status.mjs");
3083
+ const tmpFile = resolve20(cwd, ".nx-migrate-status.mjs");
3027
3084
  await import("fs/promises").then((m) => m.writeFile(tmpFile, script, "utf-8"));
3028
3085
  try {
3029
3086
  const code = await new Promise((resP) => {
@@ -3047,7 +3104,7 @@ function readEnvUrl(dialect) {
3047
3104
  var db_migrate_default = dbMigrateCommand;
3048
3105
 
3049
3106
  // packages/cli/src/commands/db-generate.ts
3050
- import { resolve as resolve20 } from "path";
3107
+ import { resolve as resolve21 } from "path";
3051
3108
  var dbGenerateCommand = {
3052
3109
  name: "db:generate",
3053
3110
  aliases: ["db:g", "db-generate", "generate-migration"],
@@ -3080,7 +3137,7 @@ var dbGenerateCommand = {
3080
3137
  logger.info(`Generating raw SQL migration: ${name} (dialect=${dialect})`);
3081
3138
  return runSqlTemplate(ctx.cwd, name, dialect);
3082
3139
  }
3083
- const configPath = resolve20(ctx.cwd, "drizzle.config.ts");
3140
+ const configPath = resolve21(ctx.cwd, "drizzle.config.ts");
3084
3141
  const args2 = ["generate", "--config", configPath];
3085
3142
  if (name)
3086
3143
  args2.push("--name", name);
@@ -3089,10 +3146,10 @@ var dbGenerateCommand = {
3089
3146
  }
3090
3147
  };
3091
3148
  async function runSqlTemplate(cwd, name, dialect) {
3092
- const { mkdirSync: mkdirSync4, writeFileSync: writeFileSync3 } = await import("fs");
3149
+ const { mkdirSync: mkdirSync5, writeFileSync: writeFileSync3 } = await import("fs");
3093
3150
  const { join } = await import("path");
3094
3151
  const migrationsDir = join(cwd, "app", "database", "migrations");
3095
- mkdirSync4(migrationsDir, { recursive: true });
3152
+ mkdirSync5(migrationsDir, { recursive: true });
3096
3153
  const timestamp = Date.now();
3097
3154
  const filename = `${timestamp}_${name.replace(/[^a-z0-9_]+/g, "_")}.sql`;
3098
3155
  const filepath = join(migrationsDir, filename);
@@ -3116,7 +3173,7 @@ var db_generate_default = dbGenerateCommand;
3116
3173
  import { spawn as spawn2 } from "child_process";
3117
3174
  import { existsSync as existsSync6 } from "fs";
3118
3175
  import { mkdir, readdir, writeFile as writeFile2, unlink } from "fs/promises";
3119
- import { resolve as resolve21 } from "path";
3176
+ import { resolve as resolve22 } from "path";
3120
3177
  var SEED_TEMPLATE = `/**
3121
3178
  * Seed: {name}
3122
3179
  *
@@ -3177,7 +3234,7 @@ var dbSeedCommand = {
3177
3234
  }
3178
3235
  ],
3179
3236
  async run(ctx) {
3180
- const folder = resolve21(ctx.cwd, ctx.flags["folder"] ?? ctx.config.paths?.seeds ?? "db/seeds");
3237
+ const folder = resolve22(ctx.cwd, ctx.flags["folder"] ?? ctx.config.paths?.seeds ?? "db/seeds");
3181
3238
  const dialect = ctx.flags["dialect"] ?? ctx.config.dialect ?? "bun-sqlite";
3182
3239
  const createName = ctx.flags["create"];
3183
3240
  const fileName = ctx.flags["file"];
@@ -3188,7 +3245,7 @@ var dbSeedCommand = {
3188
3245
  if (!existsSync6(folder)) {
3189
3246
  logger.info(`creating empty seeds folder at ${folder}`);
3190
3247
  await mkdir(folder, { recursive: true });
3191
- await writeFile2(resolve21(folder, "_README.ts"), `// Seed files go here. Run with: nx db:seed
3248
+ await writeFile2(resolve22(folder, "_README.ts"), `// Seed files go here. Run with: nx db:seed
3192
3249
  `, "utf-8");
3193
3250
  return 0;
3194
3251
  }
@@ -3212,14 +3269,14 @@ var dbSeedCommand = {
3212
3269
  if (reset) {
3213
3270
  logger.warn("--reset is set: truncating every table in the schema before running seeds.");
3214
3271
  }
3215
- const seedImports = target.map((f, i) => `import seed_${i} from ${JSON.stringify(resolve21(folder, f))};`).join(`
3272
+ const seedImports = target.map((f, i) => `import seed_${i} from ${JSON.stringify(resolve22(folder, f))};`).join(`
3216
3273
  `);
3217
3274
  const seedCalls = target.map((_, i) => ` await seed_${i}({ db, logger, dialect, truncate: (t) => db.truncate(t) });`).join(`
3218
3275
  `);
3219
3276
  const script = `
3220
3277
  import 'reflect-metadata';
3221
- import { DrizzleService } from '${relativeImport(ctx.cwd, "src/drizzle/index.js")}';
3222
- import { logger as frameworkLogger } from '${relativeImport(ctx.cwd, "src/logger/index.js")}';
3278
+ import { DrizzleService } from '@nexusts/drizzle';
3279
+ import { Logger } from '@nexusts/logger';
3223
3280
 
3224
3281
  const url = ${JSON.stringify(url)};
3225
3282
  const dialect = ${JSON.stringify(dialect)};
@@ -3228,7 +3285,8 @@ const reset = ${JSON.stringify(reset)};
3228
3285
  const cfg = { dialect, connection: { url }, schema: dialect === 'postgres' ? 'public' : undefined };
3229
3286
  const db = new DrizzleService(cfg);
3230
3287
  await db.open();
3231
- const logger = frameworkLogger;
3288
+ const logger = new Logger({ level: 'info' });
3289
+ await logger.ready();
3232
3290
 
3233
3291
  if (reset) {
3234
3292
  const tables = await db.allTables();
@@ -3245,7 +3303,7 @@ ${seedCalls}
3245
3303
  await db.close();
3246
3304
  logger.info(\`Seeds complete (\${${target.length}} file(s))\`);
3247
3305
  `;
3248
- const tmpFile = resolve21(ctx.cwd, ".nx-db-seed.mjs");
3306
+ const tmpFile = resolve22(ctx.cwd, ".nx-db-seed.mjs");
3249
3307
  await writeFile2(tmpFile, script, "utf-8");
3250
3308
  try {
3251
3309
  const code = await new Promise((resP) => {
@@ -3287,11 +3345,11 @@ async function createSeedFile(folder, name) {
3287
3345
  await mkdir(folder, { recursive: true });
3288
3346
  let candidate = `${name}.ts`;
3289
3347
  let i = 1;
3290
- while (existsSync6(resolve21(folder, candidate))) {
3348
+ while (existsSync6(resolve22(folder, candidate))) {
3291
3349
  candidate = `${name}_${i}.ts`;
3292
3350
  i++;
3293
3351
  }
3294
- const path = resolve21(folder, candidate);
3352
+ const path = resolve22(folder, candidate);
3295
3353
  const body = SEED_TEMPLATE.replace(/\{name\}/g, name);
3296
3354
  await writeFile2(path, body, "utf-8");
3297
3355
  logger.info(`created ${path}`);
@@ -3301,26 +3359,15 @@ function readEnvUrl2(dialect) {
3301
3359
  const url = process.env["DATABASE_URL"] ?? process.env["NEXUS_DB_URL"] ?? (dialect === "postgres" ? process.env["POSTGRES_URL"] : dialect === "mysql" ? process.env["MYSQL_URL"] : dialect.includes("sqlite") ? process.env["SQLITE_FILENAME"] : null);
3302
3360
  return url ?? null;
3303
3361
  }
3304
- function relativeImport(cwd, target) {
3305
- const abs = resolve21(cwd, target);
3306
- let rel = abs;
3307
- if (rel.startsWith(cwd))
3308
- rel = rel.slice(cwd.length);
3309
- if (rel.startsWith("/"))
3310
- rel = rel.slice(1);
3311
- if (!rel.startsWith("."))
3312
- rel = "./" + rel;
3313
- return rel;
3314
- }
3315
3362
  var db_seed_default = dbSeedCommand;
3316
3363
 
3317
3364
  // packages/cli/src/commands/new.ts
3318
- import { existsSync as existsSync7, mkdirSync as mkdirSync4, writeFileSync as writeFileSync3 } from "fs";
3319
- import { resolve as resolve22 } from "path";
3365
+ import { existsSync as existsSync7, mkdirSync as mkdirSync5, writeFileSync as writeFileSync3 } from "fs";
3366
+ import { resolve as resolve23 } from "path";
3320
3367
  var newCommand = {
3321
3368
  name: "new",
3322
3369
  aliases: ["n"],
3323
- summary: "Create a new Nexus project",
3370
+ summary: "Create a new NexusTS project",
3324
3371
  description: "Generates a new project directory with nx.config.ts, tsconfig, package.json, and a starter app/main.ts.",
3325
3372
  examples: [
3326
3373
  "nx new my-app",
@@ -3351,7 +3398,7 @@ var newCommand = {
3351
3398
  return 1;
3352
3399
  }
3353
3400
  const interactive = !flagBool(ctx.flags, "no-interaction", false);
3354
- const target = resolve22(ctx.cwd, name);
3401
+ const target = resolve23(ctx.cwd, name);
3355
3402
  if (existsSync7(target)) {
3356
3403
  logger.error(`Directory already exists: ${target}`);
3357
3404
  return 1;
@@ -3377,21 +3424,21 @@ var newCommand = {
3377
3424
  default: "react"
3378
3425
  });
3379
3426
  const ssr = !flagBool(ctx.flags, "no-ssr", false);
3380
- mkdirSync4(resolve22(target, "app"), { recursive: true });
3427
+ mkdirSync5(resolve23(target, "app"), { recursive: true });
3381
3428
  if (view !== "none") {
3382
- mkdirSync4(resolve22(target, "resources/views"), { recursive: true });
3429
+ mkdirSync5(resolve23(target, "resources/views"), { recursive: true });
3383
3430
  }
3384
- mkdirSync4(resolve22(target, "public"), { recursive: true });
3385
- writeFileSync3(resolve22(target, "public/.gitkeep"), "");
3431
+ mkdirSync5(resolve23(target, "public"), { recursive: true });
3432
+ writeFileSync3(resolve23(target, "public/.gitkeep"), "");
3386
3433
  if (view !== "none") {
3387
- writeFileSync3(resolve22(target, "resources/views/welcome.html"), `<h1>Welcome to ${name}</h1>
3434
+ writeFileSync3(resolve23(target, "resources/views/welcome.html"), `<h1>Welcome to ${name}</h1>
3388
3435
  <p>This is a sample Rendu template.</p>
3389
3436
  <p>Founded <?= year ?>.</p>
3390
3437
  `);
3391
3438
  }
3392
- writeFileSync3(resolve22(target, ".env"), generateEnvFile());
3393
- writeFileSync3(resolve22(target, ".env.local"), generateEnvLocalFile());
3394
- writeFileSync3(resolve22(target, ".gitignore"), generateGitIgnore());
3439
+ writeFileSync3(resolve23(target, ".env"), generateEnvFile());
3440
+ writeFileSync3(resolve23(target, ".env.local"), generateEnvLocalFile());
3441
+ writeFileSync3(resolve23(target, ".gitignore"), generateGitIgnore());
3395
3442
  const code = render(templates.project["nx.config.ts"], {
3396
3443
  routing,
3397
3444
  view,
@@ -3403,7 +3450,15 @@ var newCommand = {
3403
3450
  inertiaSSR: ssr,
3404
3451
  inertiaVersion: "1.0.0"
3405
3452
  });
3406
- writeFileSync3(resolve22(target, "nx.config.ts"), code);
3453
+ writeFileSync3(resolve23(target, "nx.config.ts"), code);
3454
+ if (orm === "drizzle") {
3455
+ const dialect = db === "bun-sqlite" || db === "node-sqlite" || db === "libsql" ? "sqlite" : db === "postgres" ? "postgresql" : "sqlite";
3456
+ const drizzleConfig = render(templates.project["drizzle.config.ts"], {
3457
+ dialect,
3458
+ dbUrl: db === "bun-sqlite" || db === "node-sqlite" ? "app.db" : ""
3459
+ });
3460
+ writeFileSync3(resolve23(target, "drizzle.config.ts"), drizzleConfig);
3461
+ }
3407
3462
  const deps = {
3408
3463
  "@nexusts/core": "*",
3409
3464
  "reflect-metadata": "^0.2.2",
@@ -3413,11 +3468,17 @@ var newCommand = {
3413
3468
  if (orm === "drizzle") {
3414
3469
  deps["@nexusts/drizzle"] = "*";
3415
3470
  deps["drizzle-orm"] = "^0.45.0";
3471
+ if (db === "postgres")
3472
+ deps["pg"] = "^8.13.0";
3473
+ if (db === "mysql")
3474
+ deps["mysql2"] = "^3.11.0";
3475
+ if (db === "sqlite" || db === "node-sqlite" || db === "bun-sqlite")
3476
+ deps["better-sqlite3"] = "^12.0.0";
3416
3477
  }
3417
3478
  if (view !== "none") {
3418
3479
  deps["@nexusts/static"] = "*";
3419
3480
  }
3420
- writeFileSync3(resolve22(target, "package.json"), JSON.stringify({
3481
+ const pkgJson = {
3421
3482
  name,
3422
3483
  version: "0.1.0",
3423
3484
  type: "module",
@@ -3429,8 +3490,12 @@ var newCommand = {
3429
3490
  nx: "nx"
3430
3491
  },
3431
3492
  dependencies: deps
3432
- }, null, 2));
3433
- writeFileSync3(resolve22(target, "tsconfig.json"), `{
3493
+ };
3494
+ if (orm === "drizzle") {
3495
+ pkgJson.devDependencies = { "drizzle-kit": "^0.31.0" };
3496
+ }
3497
+ writeFileSync3(resolve23(target, "package.json"), JSON.stringify(pkgJson, null, 2));
3498
+ writeFileSync3(resolve23(target, "tsconfig.json"), `{
3434
3499
  "compilerOptions": {
3435
3500
  "target": "ES2022",
3436
3501
  "module": "ESNext",
@@ -3451,7 +3516,7 @@ const staticMiddleware = StaticModule.mount({ root: './public', prefix: '/static
3451
3516
  ` : "";
3452
3517
  const staticOption = hasView ? `
3453
3518
  middleware: [staticMiddleware],` : "";
3454
- writeFileSync3(resolve22(target, "app/main.ts"), `import 'reflect-metadata';
3519
+ writeFileSync3(resolve23(target, "app/main.ts"), `import 'reflect-metadata';
3455
3520
  import { Application } from '@nexusts/core';
3456
3521
  ${staticImport}import { AppModule } from './app.module.js';
3457
3522
 
@@ -3471,7 +3536,7 @@ console.log('[nexus] Listening on http://localhost:' + (process.env['PORT'] ?? 3
3471
3536
  connection: { filename: 'app.db' },
3472
3537
  logging: true,
3473
3538
  })` : "";
3474
- writeFileSync3(resolve22(target, "app/app.module.ts"), `${ormImport}import { Module } from '@nexusts/core';
3539
+ writeFileSync3(resolve23(target, "app/app.module.ts"), `${ormImport}import { Module } from '@nexusts/core';
3475
3540
  import { HomeController } from './controllers/home.controller.js';
3476
3541
 
3477
3542
  @Module({
@@ -3482,12 +3547,12 @@ ${ormBlock},
3482
3547
  })
3483
3548
  export class AppModule {}
3484
3549
  `);
3485
- mkdirSync4(resolve22(target, "app/controllers"), { recursive: true });
3550
+ mkdirSync5(resolve23(target, "app/controllers"), { recursive: true });
3486
3551
  const homeViewReturn = view !== "none" ? `{
3487
3552
  view: 'welcome.html',
3488
3553
  data: { year: new Date().getFullYear() },
3489
3554
  }` : `{ status: 200, body: { message: 'Hello from NexusTS!' } }`;
3490
- writeFileSync3(resolve22(target, "app/controllers/home.controller.ts"), `import { Controller, Get } from '@nexusts/core';
3555
+ writeFileSync3(resolve23(target, "app/controllers/home.controller.ts"), `import { Controller, Get } from '@nexusts/core';
3491
3556
 
3492
3557
  @Controller('/')
3493
3558
  export class HomeController {
@@ -3497,9 +3562,9 @@ export class HomeController {
3497
3562
  }
3498
3563
  }
3499
3564
  `);
3500
- writeFileSync3(resolve22(target, "README.md"), `# ${name}
3565
+ writeFileSync3(resolve23(target, "README.md"), `# ${name}
3501
3566
 
3502
- A new Nexus project.
3567
+ A new NexusTS project.
3503
3568
 
3504
3569
  ## Run
3505
3570
 
@@ -3579,7 +3644,7 @@ var new_default = newCommand;
3579
3644
 
3580
3645
  // packages/cli/src/commands/config.ts
3581
3646
  import { existsSync as existsSync8, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
3582
- import { resolve as resolve23 } from "path";
3647
+ import { resolve as resolve24 } from "path";
3583
3648
  var DEFAULT_VALUES = {
3584
3649
  routing: "nest",
3585
3650
  view: "rendu",
@@ -3694,12 +3759,12 @@ var configCommand = {
3694
3759
  async run(ctx) {
3695
3760
  const interactive = !flagBool(ctx.flags, "no-interaction", false);
3696
3761
  const force = flagBool(ctx.flags, "force", false);
3697
- const target = resolve23(ctx.cwd, ctx.flags["target"] ?? ".");
3762
+ const target = resolve24(ctx.cwd, ctx.flags["target"] ?? ".");
3698
3763
  if (!existsSync8(target)) {
3699
3764
  logger.error(`Target directory does not exist: ${target}`);
3700
3765
  return 1;
3701
3766
  }
3702
- const nxConfigPath = resolve23(target, "nx.config.ts");
3767
+ const nxConfigPath = resolve24(target, "nx.config.ts");
3703
3768
  const values = parseExistingConfig(nxConfigPath);
3704
3769
  const flag = (k) => ctx.flags[k];
3705
3770
  const flagBoolStrict = (k, def) => flagBool(ctx.flags, k, def);
@@ -3754,7 +3819,7 @@ var configCommand = {
3754
3819
  writeNxConfig(target, values);
3755
3820
  logger.info(` + nx.config.ts`);
3756
3821
  }
3757
- const drizzleConfigPath = resolve23(target, "drizzle.config.ts");
3822
+ const drizzleConfigPath = resolve24(target, "drizzle.config.ts");
3758
3823
  if (values.orm === "drizzle") {
3759
3824
  const dialect = driverToDialect(values.dbDriver);
3760
3825
  const dbUrl = values.dbUrl;
@@ -3782,22 +3847,22 @@ var configCommand = {
3782
3847
  };
3783
3848
  function writeNxConfig(target, values) {
3784
3849
  const code = render(templates.project["nx.config.ts"], values);
3785
- writeFileSync4(resolve23(target, "nx.config.ts"), code);
3850
+ writeFileSync4(resolve24(target, "nx.config.ts"), code);
3786
3851
  }
3787
3852
  function writeDrizzleConfig(target, values) {
3788
3853
  const code = render(templates.project["drizzle.config.ts"], values);
3789
- writeFileSync4(resolve23(target, "drizzle.config.ts"), code);
3854
+ writeFileSync4(resolve24(target, "drizzle.config.ts"), code);
3790
3855
  }
3791
3856
  var config_default = configCommand;
3792
3857
 
3793
3858
  // packages/cli/src/commands/repl.ts
3794
3859
  import {
3795
3860
  existsSync as existsSync9,
3796
- mkdirSync as mkdirSync5,
3861
+ mkdirSync as mkdirSync6,
3797
3862
  readFileSync as readFileSync6,
3798
3863
  writeFileSync as writeFileSync5
3799
3864
  } from "fs";
3800
- import { dirname as dirname4, resolve as resolve24 } from "path";
3865
+ import { dirname as dirname5, resolve as resolve25 } from "path";
3801
3866
  import * as readline from "readline";
3802
3867
  import * as vm from "vm";
3803
3868
  var BANNER = (() => {
@@ -3879,10 +3944,10 @@ var replCommand = {
3879
3944
  async run(ctx) {
3880
3945
  const mod = ctx.flags["module"];
3881
3946
  const noBoot = Boolean(ctx.flags["no-boot"]);
3882
- const histPath = resolve24(ctx.cwd, ctx.flags["history"] ?? ".nx-repl-history");
3947
+ const histPath = resolve25(ctx.cwd, ctx.flags["history"] ?? ".nx-repl-history");
3883
3948
  const env = { console };
3884
3949
  if (!noBoot) {
3885
- const modPath = resolve24(ctx.cwd, mod ?? "app/app.module.ts");
3950
+ const modPath = resolve25(ctx.cwd, mod ?? "app/app.module.ts");
3886
3951
  if (!existsSync9(modPath)) {
3887
3952
  logger.error(`module not found: ${modPath}`);
3888
3953
  logger.info("pass --module <path> or --no-boot to skip booting");
@@ -3982,20 +4047,33 @@ var replCommand = {
3982
4047
  console.log(" (no modules)");
3983
4048
  } else {
3984
4049
  for (const m of mods) {
3985
- console.log(` ${m.name ?? m.constructor?.name ?? "(anon)"}`);
4050
+ console.log(` ${m.moduleClass?.name ?? "(anon)"}`);
3986
4051
  }
3987
4052
  }
3988
4053
  return true;
3989
4054
  }
3990
4055
  case ".routes": {
3991
4056
  const app = env.app;
3992
- const routes = app?.server?.app?.routes ?? [];
4057
+ const getRoutes = app?.server?.router?.getRoutes;
4058
+ const raw = typeof getRoutes === "function" ? getRoutes.call(app.server.router) : [];
4059
+ const seen = new Set;
4060
+ const routes = raw.filter((r) => {
4061
+ const key = `${r.method}:${r.path}:${r.target?.name ?? ""}:${typeof r.propertyKey === "symbol" ? r.propertyKey.description ?? "" : String(r.propertyKey)}`;
4062
+ if (seen.has(key))
4063
+ return false;
4064
+ seen.add(key);
4065
+ return true;
4066
+ });
3993
4067
  if (routes.length === 0) {
3994
4068
  console.log(" (no routes registered)");
3995
4069
  } else {
4070
+ const methodPad = Math.max(...routes.map((r) => r.method.length));
4071
+ const pathPad = Math.max(...routes.map((r) => r.path.length));
3996
4072
  for (const r of routes) {
3997
- const m = (r.method ?? "?").padEnd(7);
3998
- console.log(` ${m} ${r.path ?? "?"}`);
4073
+ const m = r.method.padEnd(methodPad);
4074
+ const p = r.path.padEnd(pathPad);
4075
+ const c2 = `${r.target?.name ?? "?"}.${typeof r.propertyKey === "symbol" ? r.propertyKey.description ?? "?" : String(r.propertyKey)}`;
4076
+ console.log(` ${m} ${p} ${c2}`);
3999
4077
  }
4000
4078
  }
4001
4079
  return true;
@@ -4072,6 +4150,16 @@ async function preloadService(env, app, name, path, className) {
4072
4150
  logger.debug(`repl: ${path} not installed \u2014 skipping ${name}`);
4073
4151
  }
4074
4152
  }
4153
+ function describeToken(token) {
4154
+ if (typeof token === "symbol") {
4155
+ const desc = token.description ?? "(symbol)";
4156
+ return `Symbol(${desc})`;
4157
+ }
4158
+ if (typeof token === "function") {
4159
+ return token.name || "(anonymous class)";
4160
+ }
4161
+ return String(token);
4162
+ }
4075
4163
  function listServices(container) {
4076
4164
  if (!container)
4077
4165
  return [];
@@ -4079,7 +4167,7 @@ function listServices(container) {
4079
4167
  if (typeof c2.listProviders !== "function")
4080
4168
  return [];
4081
4169
  try {
4082
- return c2.listProviders().map((p) => p.token?.toString?.() ?? String(p.token));
4170
+ return c2.listProviders().map((p) => describeToken(p.token));
4083
4171
  } catch {
4084
4172
  return [];
4085
4173
  }
@@ -4174,9 +4262,9 @@ function loadHistory(path) {
4174
4262
  }
4175
4263
  function saveHistoryFile(path, history) {
4176
4264
  try {
4177
- const dir = dirname4(path);
4265
+ const dir = dirname5(path);
4178
4266
  if (!existsSync9(dir))
4179
- mkdirSync5(dir, { recursive: true });
4267
+ mkdirSync6(dir, { recursive: true });
4180
4268
  writeFileSync5(path, history.slice(-1000).join(`
4181
4269
  `));
4182
4270
  } catch {}
@@ -4185,7 +4273,7 @@ var repl_default = replCommand;
4185
4273
 
4186
4274
  // packages/cli/src/commands/route-list.ts
4187
4275
  import { readdirSync, statSync as statSync2 } from "fs";
4188
- import { resolve as resolve25 } from "path";
4276
+ import { resolve as resolve26 } from "path";
4189
4277
  var routeListCommand = {
4190
4278
  name: "route:list",
4191
4279
  aliases: ["routes", "route-list"],
@@ -4195,7 +4283,7 @@ var routeListCommand = {
4195
4283
  { name: "format", description: "Output format: table (default) | json" }
4196
4284
  ],
4197
4285
  async run(ctx) {
4198
- const controllersDir = resolve25(ctx.cwd, ctx.config.paths.controllers);
4286
+ const controllersDir = resolve26(ctx.cwd, ctx.config.paths.controllers);
4199
4287
  try {
4200
4288
  statSync2(controllersDir);
4201
4289
  } catch {
@@ -4209,14 +4297,15 @@ var routeListCommand = {
4209
4297
  }
4210
4298
  const routes = [];
4211
4299
  for (const file of files) {
4212
- const fullPath = resolve25(controllersDir, file);
4300
+ const fullPath = resolve26(controllersDir, file);
4213
4301
  try {
4214
4302
  const mod = await import(`${fullPath}?t=${Date.now()}`);
4215
4303
  for (const exportName of Object.keys(mod)) {
4216
4304
  const cls = mod[exportName];
4217
4305
  if (typeof cls !== "function")
4218
4306
  continue;
4219
- const prefix = Reflect.getMetadata("nexus:controller:prefix", cls) ?? "";
4307
+ const controllerMeta = Reflect.getMetadata("nexus:controller", cls);
4308
+ const prefix = controllerMeta?.prefix ?? "";
4220
4309
  const routeList = Reflect.getMetadata("nexus:routes", cls) ?? [];
4221
4310
  for (const r of routeList) {
4222
4311
  routes.push({
@@ -4278,6 +4367,7 @@ var commands = [
4278
4367
  config_default,
4279
4368
  make_crud_default,
4280
4369
  make_controller_default,
4370
+ make_repository_default,
4281
4371
  make_service_default,
4282
4372
  make_module_default,
4283
4373
  make_model_default,
@@ -4340,7 +4430,7 @@ function renderHelp(commandName) {
4340
4430
  renderCommandHelp(cmd);
4341
4431
  return 0;
4342
4432
  }
4343
- logger.heading("nx \u2014 Nexus CLI");
4433
+ logger.heading("nx \u2014 NexusTS CLI");
4344
4434
  console.log(`
4345
4435
  ${colors.dim("Adonis ACE-style command runner for the NexusTS framework.")}
4346
4436
 
@@ -4409,5 +4499,5 @@ main().then((code) => process.exit(code)).catch((err) => {
4409
4499
  process.exit(1);
4410
4500
  });
4411
4501
 
4412
- //# debugId=9D68E94AB6C5D92664756E2164756E21
4502
+ //# debugId=7EFC3F3E94521F7164756E2164756E21
4413
4503
  //# sourceMappingURL=index.js.map