create-newt-app 0.31.9 → 0.32.0

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.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  //#region src/templates/types.d.ts
2
+ type Nest = "on" | "off" | "di-only";
2
3
  type Extra = "anti-slop";
3
4
  //#endregion
4
5
  //#region src/index.d.ts
@@ -20,7 +21,7 @@ type Options = {
20
21
  database: Database;
21
22
  linter: Linter;
22
23
  deployment: Deployment;
23
- nestDiOnly: boolean;
24
+ nest: Nest;
24
25
  includeExample: boolean;
25
26
  extras: readonly Extra[];
26
27
  explicitFlags: readonly string[];
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/templates/types.ts","../src/index.ts"],"mappings":";KAgCY;;;cCbN;cACA;cACA;cACA;KAGD,kBAAkB;KAClB,mBAAmB;KACnB,iBAAiB;KACjB,qBAAqB;KAcrB;EACH;EACA;EACA;EACA;EACA;EACA,SAAS;EACT,UAAU;EACV,QAAQ;EACR,YAAY;EACZ;EACA;EACA,iBAAiB;EACjB;;iBAWoB,OAAO,SAAS,UAAO"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/templates/types.ts","../src/index.ts"],"mappings":";KAIY;KAgCA;;;cChBN;cACA;cACA;cACA;KAID,kBAAkB;KAClB,mBAAmB;KACnB,iBAAiB;KACjB,qBAAqB;KAcrB;EACH;EACA;EACA;EACA;EACA;EACA,SAAS;EACT,UAAU;EACV,QAAQ;EACR,YAAY;EACZ,MAAM;EACN;EACA,iBAAiB;EACjB;;iBAWoB,OAAO,SAAS,UAAO"}
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import { existsSync, promises } from "fs";
11
11
  import path from "path";
12
12
  import https from "node:https";
13
13
  //#region package.json
14
- var version = "0.31.9";
14
+ var version = "0.32.0";
15
15
  var engines = { "node": ">=24.0.0" };
16
16
  //#endregion
17
17
  //#region src/templates/root/index.ts
@@ -165,7 +165,7 @@ allowBuilds:
165
165
  filename: "README.md",
166
166
  template: `# <%= projectName %>
167
167
 
168
- Full-stack monorepo: Next.js 16 + NestJS 11 + better-auth + <%= database === 'postgres' ? 'Postgres' : 'SQLite' %>.
168
+ Full-stack monorepo: Next.js 16<% if (nest !== 'off') { %> + NestJS 11<% } %> + better-auth + <%= database === 'postgres' ? 'Postgres' : 'SQLite' %>.
169
169
 
170
170
  ## Quick start
171
171
 
@@ -180,7 +180,11 @@ Open [http://localhost:3000](http://localhost:3000).
180
180
  ## Apps
181
181
 
182
182
  - **web**: Next.js frontend (port 3000)
183
+ <% if (nest === 'on') { -%>
183
184
  - **api**: NestJS backend (port 3001)
185
+ <% } else if (nest === 'di-only') { -%>
186
+ - **api**: NestJS providers, resolved from the web process (no HTTP server)
187
+ <% } -%>
184
188
 
185
189
  ## Packages
186
190
 
@@ -227,7 +231,7 @@ This version has breaking changes — APIs, conventions, and file structure may
227
231
  const web$1 = {
228
232
  templates: [
229
233
  {
230
- when: (s) => !s.nestDiOnly,
234
+ when: (s) => s.nest !== "di-only",
231
235
  filename: "apps/web/package.json",
232
236
  template: `{
233
237
  "name": "web",
@@ -238,8 +242,7 @@ const web$1 = {
238
242
  "dev": "next dev --port 3000",
239
243
  "build": "next build",
240
244
  "start": "next start",
241
- "typecheck": "next typegen && tsc --noEmit",
242
- "db:migrate": "better-auth migrate"
245
+ "typecheck": "next typegen && tsc --noEmit"
243
246
  },
244
247
  "dependencies": {
245
248
  "@<%= projectName %>/auth": "workspace:*",
@@ -342,7 +345,7 @@ The easiest way to deploy your Next.js app is to use the [Vercel Platform](https
342
345
  Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.`
343
346
  },
344
347
  {
345
- when: (s) => s.deployment === "none" && !s.nestDiOnly,
348
+ when: (s) => s.deployment === "none" && s.nest === "on",
346
349
  filename: "apps/web/next.config.js",
347
350
  template: `import dotenv from 'dotenv';
348
351
  import { resolve } from 'path';
@@ -370,7 +373,7 @@ export default nextConfig;`
370
373
  template: `export { default } from "@<%= projectName %>/ui/postcss.config";`
371
374
  },
372
375
  {
373
- when: (s) => !s.nestDiOnly,
376
+ when: (s) => s.nest !== "di-only",
374
377
  filename: "apps/web/tsconfig.json",
375
378
  template: `{
376
379
  "extends": "@<%= projectName %>/typescript-config/nextjs.json",
@@ -748,7 +751,7 @@ export const authClient: ReturnType<typeof createAuthClient> = createAuthClient(
748
751
  //#region src/templates/api/index.ts
749
752
  const api$1 = { templates: [
750
753
  {
751
- when: (s) => !s.nestDiOnly && s.deployment !== "spa",
754
+ when: (s) => s.nest === "on" && s.deployment !== "spa",
752
755
  filename: "apps/api/package.json",
753
756
  template: `{
754
757
  "name": "api",
@@ -797,7 +800,7 @@ const api$1 = { templates: [
797
800
  }`
798
801
  },
799
802
  {
800
- when: (s) => !s.nestDiOnly,
803
+ when: (s) => s.nest === "on",
801
804
  filename: "apps/api/tsconfig.json",
802
805
  template: `{
803
806
  "compilerOptions": {
@@ -834,7 +837,7 @@ const api$1 = { templates: [
834
837
  }`
835
838
  },
836
839
  {
837
- when: (s) => s.nestDiOnly && !s.todoExample,
840
+ when: (s) => s.nest === "di-only" && !s.todoExample,
838
841
  filename: "apps/api/src/app.module.ts",
839
842
  template: `import { Module } from '@nestjs/common';
840
843
  import { AppService } from './app.service';
@@ -887,7 +890,7 @@ NestJS backend for the monorepo.
887
890
  \`\`\`sh
888
891
  pnpm dev # watch mode
889
892
  pnpm build # production build
890
- pnpm test # unit tests<% if (!nestDiOnly) { %>
893
+ pnpm test # unit tests<% if (nest === 'on') { %>
891
894
  pnpm test:e2e # e2e tests<% } %>
892
895
  \`\`\``
893
896
  }
@@ -10009,6 +10012,7 @@ export default nextJsConfig;`
10009
10012
  //#endregion
10010
10013
  //#region src/templates/api/templates/eslint-config.ts
10011
10014
  var eslint_config_default$1 = {
10015
+ when: (s) => s.nest !== "off",
10012
10016
  filename: "apps/api/eslint.config.mjs",
10013
10017
  template: `// @ts-check
10014
10018
  import eslint from '@eslint/js';
@@ -10732,7 +10736,7 @@ describe('AppController (e2e)', () => {
10732
10736
  //#region src/templates/deployment-standalone/index.ts
10733
10737
  const deploymentStandalone = { templates: [
10734
10738
  {
10735
- when: (s) => !s.nestDiOnly,
10739
+ when: (s) => s.nest === "on",
10736
10740
  filename: "Dockerfile",
10737
10741
  template: `FROM node:24-alpine AS base
10738
10742
  ENV PNPM_HOME="/pnpm"
@@ -10770,7 +10774,7 @@ WORKDIR /app
10770
10774
  CMD ["pnpm", "db:migrate"]`
10771
10775
  },
10772
10776
  {
10773
- when: (s) => !s.nestDiOnly,
10777
+ when: (s) => s.nest === "on",
10774
10778
  filename: "docker-compose.yml",
10775
10779
  template: `x-app-env: &app-env
10776
10780
  BETTER_AUTH_SECRET: \${BETTER_AUTH_SECRET}
@@ -10848,7 +10852,7 @@ volumes:
10848
10852
  db_data:`
10849
10853
  },
10850
10854
  {
10851
- when: (s) => !s.nestDiOnly,
10855
+ when: (s) => s.nest === "on",
10852
10856
  filename: "apps/web/next.config.js",
10853
10857
  template: `import dotenv from 'dotenv';
10854
10858
  import { resolve } from 'path';
@@ -11098,8 +11102,7 @@ export async function GET() {
11098
11102
  "scripts": {
11099
11103
  "dev": "next dev --port 3000",
11100
11104
  "build": "next build",
11101
- "start": "next start",
11102
- "db:migrate": "better-auth migrate"
11105
+ "start": "next start"
11103
11106
  },
11104
11107
  "dependencies": {
11105
11108
  "@<%= projectName %>/api": "workspace:*",
@@ -11183,8 +11186,38 @@ export default nextConfig;`
11183
11186
  }
11184
11187
  ] };
11185
11188
  //#endregion
11186
- //#region src/templates/deployment-standalone-di/index.ts
11187
- const deploymentStandaloneDi = { templates: [
11189
+ //#region src/templates/nest-off/index.ts
11190
+ const nestOff = { templates: [{
11191
+ when: (s) => s.deployment === "none",
11192
+ filename: "apps/web/next.config.js",
11193
+ template: `import dotenv from 'dotenv';
11194
+ import { resolve } from 'path';
11195
+
11196
+ // Load root .env first, then local .env (local takes precedence)
11197
+ dotenv.config({ path: resolve(process.cwd(), '../../.env') });
11198
+ dotenv.config({ path: resolve(process.cwd(), '.env') });
11199
+
11200
+ // No /api rewrite: there is no second process, so Next serves /api itself.
11201
+ /** @type {import('next').NextConfig} */
11202
+ const nextConfig = {};
11203
+
11204
+ export default nextConfig;`
11205
+ }, {
11206
+ filename: "apps/web/app/api/hello/route.ts",
11207
+ template: `import { NextResponse } from 'next/server';
11208
+ import { headers } from 'next/headers';
11209
+ import { auth } from '@<%= projectName %>/auth';
11210
+
11211
+ export async function GET() {
11212
+ const session = await auth.api.getSession({ headers: await headers() });
11213
+ return NextResponse.json({
11214
+ message: session?.user.name ? \`Hello \${session.user.name}\` : 'Hello from Next',
11215
+ });
11216
+ }`
11217
+ }] };
11218
+ //#endregion
11219
+ //#region src/templates/deployment-standalone-web/index.ts
11220
+ const deploymentStandaloneWeb = { templates: [
11188
11221
  {
11189
11222
  filename: "Dockerfile",
11190
11223
  template: `FROM node:24-alpine AS base
@@ -11196,11 +11229,11 @@ FROM base AS build
11196
11229
  WORKDIR /app
11197
11230
  COPY . .
11198
11231
  RUN pnpm install --frozen-lockfile
11199
- RUN pnpm build --filter=web --filter=@<%= projectName %>/api --filter=@<%= projectName %>/auth
11232
+ RUN pnpm build --filter=web<% if (nest === 'di-only') { %> --filter=@<%= projectName %>/api<% } %> --filter=@<%= projectName %>/auth
11200
11233
 
11201
11234
  # --- web ---
11202
- # DI-only has no api entrypoint: Nest is wired into this image through the
11203
- # Next.js server, so there is no separate api stage.
11235
+ # One image: <% if (nest === 'di-only') { %>Nest is wired into the Next.js server rather than bootstrapped
11236
+ # on its own port<% } else { %>Next.js serves /api itself<% } %>, so there is no separate api stage.
11204
11237
  FROM base AS web
11205
11238
  WORKDIR /app
11206
11239
  ENV NODE_ENV=production
@@ -11285,11 +11318,11 @@ import { resolve } from 'path';
11285
11318
  dotenv.config({ path: resolve(process.cwd(), '../../.env') });
11286
11319
  dotenv.config({ path: resolve(process.cwd(), '.env') });
11287
11320
 
11288
- // No /api rewrite: DI-only runs Nest inside this process, so Next serves
11289
- // /api itself and there is no separate api container to proxy to.
11321
+ // No /api rewrite: Next serves /api itself, so there is no api container to
11322
+ // proxy to.
11290
11323
  /** @type {import('next').NextConfig} */
11291
11324
  const nextConfig = {
11292
- output: "standalone",
11325
+ output: "standalone",<% if (nest === 'di-only') { %>
11293
11326
  serverExternalPackages: [
11294
11327
  '@<%= projectName %>/api',
11295
11328
  '@<%= projectName %>/db',
@@ -11300,7 +11333,7 @@ const nextConfig = {
11300
11333
  '@thallesp/nestjs-better-auth',
11301
11334
  'reflect-metadata',
11302
11335
  'express',
11303
- ],
11336
+ ],<% } %>
11304
11337
  };
11305
11338
 
11306
11339
  export default nextConfig;`
@@ -11358,7 +11391,7 @@ describe('AppController', () => {
11358
11391
  });`
11359
11392
  },
11360
11393
  {
11361
- when: (s) => !s.nestDiOnly && !s.todoExample,
11394
+ when: (s) => s.nest === "on" && !s.todoExample,
11362
11395
  filename: "apps/api/src/app.module.ts",
11363
11396
  template: `<% if (deployment === 'spa') { %>import { join } from 'path';
11364
11397
  <% } %>import { Module } from '@nestjs/common';
@@ -11411,7 +11444,7 @@ void bootstrap();`
11411
11444
  //#endregion
11412
11445
  //#region src/templates/todo-example/templates/todos-module.ts
11413
11446
  var todos_module_default = {
11414
- when: (s) => s.nestDiOnly,
11447
+ when: (s) => s.nest === "di-only",
11415
11448
  filename: "apps/api/src/todos/todos.module.ts",
11416
11449
  template: `import { Module } from '@nestjs/common';
11417
11450
  import { TodosService } from './todos.service';
@@ -11671,7 +11704,7 @@ export class TodosModule {}`
11671
11704
  //#endregion
11672
11705
  //#region src/templates/todo-example/templates/app-module-controllers.ts
11673
11706
  var app_module_controllers_default = {
11674
- when: (s) => !s.nestDiOnly && s.todoExample,
11707
+ when: (s) => s.nest === "on" && s.todoExample,
11675
11708
  filename: "apps/api/src/app.module.ts",
11676
11709
  template: `<% if (deployment === 'spa') { %>import { join } from 'path';
11677
11710
  <% } %>import { Module } from '@nestjs/common';
@@ -11702,7 +11735,7 @@ export class AppModule {}`
11702
11735
  //#endregion
11703
11736
  //#region src/templates/todo-example/templates/app-module-di.ts
11704
11737
  var app_module_di_default = {
11705
- when: (s) => s.nestDiOnly && s.todoExample,
11738
+ when: (s) => s.nest === "di-only" && s.todoExample,
11706
11739
  filename: "apps/api/src/app.module.ts",
11707
11740
  template: `import { Module } from '@nestjs/common';
11708
11741
  import { AppService } from './app.service';
@@ -12306,35 +12339,36 @@ const E2E_FILES = [
12306
12339
  "apps/api/vitest.config.e2e.mts"
12307
12340
  ];
12308
12341
  function selectModules(selection) {
12309
- const { deployment, nestDiOnly: nestDiOnly$1, todoExample, shadcn, database, linter, testing, extras } = selection;
12342
+ const { deployment, nest, todoExample, shadcn, database, linter, testing, extras } = selection;
12310
12343
  const deploymentModule = deployment === "standalone" ? deploymentStandalone : deployment === "spa" ? singleProcessStaticExport : null;
12311
12344
  const webModule = deployment === "spa" ? {
12312
12345
  ...web$1,
12313
12346
  templates: web$1.templates.filter((t) => t.filename !== "apps/web/app/api/auth/[...all]/route.ts")
12314
12347
  } : web$1;
12315
12348
  const selectedTesting = testing === "vitest" ? testingVitest : testingJest;
12316
- const testingModule = nestDiOnly$1 ? {
12349
+ const testingModule = nest === "off" ? null : nest === "di-only" ? {
12317
12350
  ...selectedTesting,
12318
12351
  templates: selectedTesting.templates.filter((t) => !E2E_FILES.includes(t.filename)),
12319
12352
  scripts: selectedTesting.scripts?.filter((s) => s.name !== "test:e2e")
12320
12353
  } : selectedTesting;
12354
+ const nestModule = nest === "di-only" ? nestDiOnly : nest === "off" ? nestOff : apiControllers;
12321
12355
  return [
12322
12356
  root$2,
12323
12357
  webModule,
12324
- api$1,
12358
+ ...nest === "off" ? [] : [api$1],
12325
12359
  database === "postgres" ? dbPostgres : dbSqlite,
12326
12360
  auth,
12327
12361
  shadcn ? shadcnUi : ui$1,
12328
12362
  linter === "oxc" ? oxc : eslintConfig,
12329
12363
  ...extras.includes("anti-slop") ? [antiSlop] : [],
12330
12364
  typescriptConfig,
12331
- testingModule,
12365
+ ...testingModule ? [testingModule] : [],
12332
12366
  ...deploymentModule ? [deploymentModule] : [],
12333
- ...nestDiOnly$1 ? [nestDiOnly] : [apiControllers],
12334
- ...nestDiOnly$1 && deployment === "standalone" ? [deploymentStandaloneDi] : [],
12367
+ nestModule,
12368
+ ...nest !== "on" && deployment === "standalone" ? [deploymentStandaloneWeb] : [],
12335
12369
  ...todoExample ? [
12336
12370
  todoExampleApi,
12337
- ...nestDiOnly$1 ? [todoExampleDi] : [todoExampleControllers],
12371
+ ...nest === "di-only" ? [todoExampleDi] : [todoExampleControllers],
12338
12372
  shadcn ? todoExampleShadcn : todoExampleWeb
12339
12373
  ] : []
12340
12374
  ];
@@ -12442,10 +12476,21 @@ function validateExtrasCombo(extras, linter) {
12442
12476
  };
12443
12477
  return { valid: true };
12444
12478
  }
12445
- function validateDeploymentCombo(deployment, nestDiOnly) {
12446
- if (deployment === "spa" && nestDiOnly) return {
12479
+ function validateDeploymentCombo(deployment, nest) {
12480
+ if (deployment === "spa" && nest === "di-only") return {
12481
+ valid: false,
12482
+ error: "--deployment spa cannot be combined with --nest di-only.\nSPA mode statically exports Next.js (output: 'export'), which cannot include the\nAPI route handlers that di-only mode depends on. Pick one: --nest on to get SPA\nmode with NestJS controllers, or drop --deployment spa."
12483
+ };
12484
+ if (deployment === "spa" && nest === "off") return {
12447
12485
  valid: false,
12448
- error: "--deployment spa cannot be combined with --nest-di-only.\nSPA mode statically exports Next.js (output: 'export'), which cannot include the\nAPI route handlers that DI-only mode depends on. Pick one: drop --nest-di-only to\nget SPA mode with NestJS controllers, or drop --deployment spa."
12486
+ error: "--deployment spa cannot be combined with --nest off.\nSPA mode statically exports Next.js and hands the output to NestJS to serve, so\nthere is nothing left to serve it. Pick one: --nest on, or drop --deployment spa."
12487
+ };
12488
+ return { valid: true };
12489
+ }
12490
+ function validateExampleCombo(todoExample, nest) {
12491
+ if (todoExample && nest === "off") return {
12492
+ valid: false,
12493
+ error: "--include-example cannot be combined with --nest off.\nThe todo example is a Nest module: an @Injectable service plus either a controller\nor a Next.js route handler that resolves it. Pick one: --nest on or --nest di-only,\nor drop --include-example."
12449
12494
  };
12450
12495
  return { valid: true };
12451
12496
  }
@@ -12502,7 +12547,7 @@ async function scaffold(modules, options) {
12502
12547
  }
12503
12548
  const templateData = {
12504
12549
  projectName: options.name,
12505
- nestDiOnly: options.selection.nestDiOnly,
12550
+ nest: options.selection.nest,
12506
12551
  testing: options.testing,
12507
12552
  database: options.database,
12508
12553
  deployment: options.deployment,
@@ -12590,7 +12635,7 @@ function buildPayload(report) {
12590
12635
  database: selection.database,
12591
12636
  linter: selection.linter,
12592
12637
  deployment: selection.deployment,
12593
- nestDiOnly: selection.nestDiOnly,
12638
+ nest: selection.nest,
12594
12639
  todoExample: selection.todoExample,
12595
12640
  antiSlop: selection.extras.includes("anti-slop")
12596
12641
  };
@@ -12635,6 +12680,11 @@ const DEPLOYMENT_CHOICES = [
12635
12680
  "standalone",
12636
12681
  "spa"
12637
12682
  ];
12683
+ const NEST_CHOICES = [
12684
+ "on",
12685
+ "off",
12686
+ "di-only"
12687
+ ];
12638
12688
  const EXTRAS_CHOICES = ["anti-slop"];
12639
12689
  var TaskBuilder = class {
12640
12690
  tasks = [];
@@ -12654,7 +12704,28 @@ async function doInit(options) {
12654
12704
  message: "Use shadcn/ui?",
12655
12705
  initialValue: true
12656
12706
  }),
12657
- testing: () => p.select({
12707
+ nest: () => p.select({
12708
+ message: "NestJS?",
12709
+ options: [
12710
+ {
12711
+ value: "on",
12712
+ label: "On",
12713
+ hint: "apps/api on port 3001"
12714
+ },
12715
+ {
12716
+ value: "di-only",
12717
+ label: "DI only",
12718
+ hint: "no HTTP server; Next.js route handlers inject its services"
12719
+ },
12720
+ {
12721
+ value: "off",
12722
+ label: "Off",
12723
+ hint: "no apps/api; Next.js owns the backend"
12724
+ }
12725
+ ],
12726
+ initialValue: "on"
12727
+ }),
12728
+ testing: ({ results }) => results.nest === "off" ? void 0 : p.select({
12658
12729
  message: "Testing framework?",
12659
12730
  options: [{
12660
12731
  value: "jest",
@@ -12696,11 +12767,7 @@ async function doInit(options) {
12696
12767
  }],
12697
12768
  required: false
12698
12769
  }) : void 0,
12699
- nestDiOnly: () => p.confirm({
12700
- message: "Use NestJS for dependency injection only?",
12701
- initialValue: false
12702
- }),
12703
- todoExample: () => p.confirm({
12770
+ todoExample: ({ results }) => results.nest === "off" ? void 0 : p.confirm({
12704
12771
  message: "Include the todo example?",
12705
12772
  initialValue: true
12706
12773
  }),
@@ -12717,11 +12784,11 @@ async function doInit(options) {
12717
12784
  label: "Standalone + Dockerfile",
12718
12785
  hint: "Dockerfiles + docker-compose.yml"
12719
12786
  },
12720
- ...results.nestDiOnly ? [] : [{
12787
+ ...results.nest === "on" ? [{
12721
12788
  value: "spa",
12722
12789
  label: "SPA Mode",
12723
12790
  hint: "static export served by NestJS"
12724
- }]
12791
+ }] : []
12725
12792
  ],
12726
12793
  initialValue: "none"
12727
12794
  })
@@ -12746,16 +12813,18 @@ async function doInit(options) {
12746
12813
  const database = options.nonInteractive ? options.database : answers.database ?? "sqlite";
12747
12814
  const linter = options.nonInteractive ? options.linter : answers.linter ?? "eslint";
12748
12815
  const deployment = options.nonInteractive ? options.deployment : answers.deployment ?? "none";
12749
- const nestDiOnly = options.nonInteractive ? options.nestDiOnly : answers.nestDiOnly ?? false;
12750
- const todoExample = options.nonInteractive ? options.includeExample : answers.todoExample ?? true;
12816
+ const nest = options.nonInteractive ? options.nest : answers.nest ?? "on";
12817
+ const todoExample = options.nonInteractive ? options.includeExample : nest !== "off" && (answers.todoExample ?? true);
12751
12818
  const extras = options.nonInteractive ? options.extras : answers.extras ?? [];
12752
- const deploymentCombo = validateDeploymentCombo(deployment, nestDiOnly);
12819
+ const deploymentCombo = validateDeploymentCombo(deployment, nest);
12753
12820
  if (!deploymentCombo.valid) throw new Error(deploymentCombo.error);
12821
+ const exampleCombo = validateExampleCombo(todoExample, nest);
12822
+ if (!exampleCombo.valid) throw new Error(exampleCombo.error);
12754
12823
  const extrasCombo = validateExtrasCombo(extras, linter);
12755
12824
  if (!extrasCombo.valid) throw new Error(extrasCombo.error);
12756
12825
  const selection = {
12757
12826
  deployment,
12758
- nestDiOnly,
12827
+ nest,
12759
12828
  todoExample,
12760
12829
  shadcn: useShadcn,
12761
12830
  database,
@@ -12826,7 +12895,7 @@ async function doInit(options) {
12826
12895
  }
12827
12896
  }
12828
12897
  const program = new Command();
12829
- program.name("create-newt-app").version(version).description("Create a new newt-app monorepo").argument("[name]").option("-ni, --no-install", "Skip pnpm install", true).option("-ng, --no-git", "Skip git initialization", true).option("--shadcn", "Include shadcn/ui", false).option("--testing <framework>", "Testing framework: vitest or jest", "jest").option("--database <database>", "Database: sqlite or postgres", "sqlite").option("--linter <linter>", "Linter: eslint or oxc", "eslint").option("--deployment <strategy>", "Deployment: none, standalone, or spa", "none").option("--nest-di-only", "Use NestJS for dependency injection only", false).option("--include-example", "Include the todo example", false).option("--extras <list>", "Extras, comma-separated: anti-slop", "").action(async (name, options, command) => {
12898
+ program.name("create-newt-app").version(version).description("Create a new newt-app monorepo").argument("[name]").option("-ni, --no-install", "Skip pnpm install", true).option("-ng, --no-git", "Skip git initialization", true).option("--shadcn", "Include shadcn/ui", false).option("--testing <framework>", "Testing framework: vitest or jest", "jest").option("--database <database>", "Database: sqlite or postgres", "sqlite").option("--linter <linter>", "Linter: eslint or oxc", "eslint").option("--deployment <strategy>", "Deployment: none, standalone, or spa", "none").option("--nest <mode>", "NestJS: on, off, or di-only", "on").option("--include-example", "Include the todo example", false).option("--extras <list>", "Extras, comma-separated: anti-slop", "").action(async (name, options, command) => {
12830
12899
  intro(`Create a ${chalk.blue("newt")} app.`);
12831
12900
  const explicitFlags = Object.entries({
12832
12901
  shadcn: "--shadcn",
@@ -12834,7 +12903,7 @@ program.name("create-newt-app").version(version).description("Create a new newt-
12834
12903
  database: "--database",
12835
12904
  linter: "--linter",
12836
12905
  deployment: "--deployment",
12837
- nestDiOnly: "--nest-di-only",
12906
+ nest: "--nest",
12838
12907
  includeExample: "--include-example",
12839
12908
  extras: "--extras"
12840
12909
  }).filter(([option]) => command.getOptionValueSource(option) === "cli").map(([, flag]) => flag);
@@ -12861,6 +12930,11 @@ program.name("create-newt-app").version(version).description("Create a new newt-
12861
12930
  value: options.deployment,
12862
12931
  allowed: DEPLOYMENT_CHOICES
12863
12932
  },
12933
+ {
12934
+ flag: "--nest",
12935
+ value: options.nest,
12936
+ allowed: NEST_CHOICES
12937
+ },
12864
12938
  ...extras.map((extra) => ({
12865
12939
  flag: "--extras",
12866
12940
  value: extra,
@@ -12881,7 +12955,7 @@ program.name("create-newt-app").version(version).description("Create a new newt-
12881
12955
  database: options.database,
12882
12956
  linter: options.linter,
12883
12957
  deployment: options.deployment,
12884
- nestDiOnly: options.nestDiOnly,
12958
+ nest: options.nest,
12885
12959
  includeExample: options.includeExample,
12886
12960
  extras,
12887
12961
  explicitFlags