create-newt-app 0.31.10 → 0.32.1

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.10";
14
+ var version = "0.32.1";
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
  }
@@ -938,6 +941,7 @@ export type Auth = typeof auth;`
938
941
  filename: "packages/auth/tsconfig.json",
939
942
  template: `{
940
943
  "compilerOptions": {
944
+ "erasableSyntaxOnly": true,
941
945
  "esModuleInterop": true,
942
946
  "lib": ["es2022"],
943
947
  "module": "NodeNext",
@@ -958,6 +962,7 @@ var tsconfig_default$2 = {
958
962
  filename: "packages/db/tsconfig.json",
959
963
  template: `{
960
964
  "compilerOptions": {
965
+ "erasableSyntaxOnly": true,
961
966
  "esModuleInterop": true,
962
967
  "lib": ["es2022"],
963
968
  "module": "NodeNext",
@@ -10009,6 +10014,7 @@ export default nextJsConfig;`
10009
10014
  //#endregion
10010
10015
  //#region src/templates/api/templates/eslint-config.ts
10011
10016
  var eslint_config_default$1 = {
10017
+ when: (s) => s.nest !== "off",
10012
10018
  filename: "apps/api/eslint.config.mjs",
10013
10019
  template: `// @ts-check
10014
10020
  import eslint from '@eslint/js';
@@ -10732,7 +10738,7 @@ describe('AppController (e2e)', () => {
10732
10738
  //#region src/templates/deployment-standalone/index.ts
10733
10739
  const deploymentStandalone = { templates: [
10734
10740
  {
10735
- when: (s) => !s.nestDiOnly,
10741
+ when: (s) => s.nest === "on",
10736
10742
  filename: "Dockerfile",
10737
10743
  template: `FROM node:24-alpine AS base
10738
10744
  ENV PNPM_HOME="/pnpm"
@@ -10770,7 +10776,7 @@ WORKDIR /app
10770
10776
  CMD ["pnpm", "db:migrate"]`
10771
10777
  },
10772
10778
  {
10773
- when: (s) => !s.nestDiOnly,
10779
+ when: (s) => s.nest === "on",
10774
10780
  filename: "docker-compose.yml",
10775
10781
  template: `x-app-env: &app-env
10776
10782
  BETTER_AUTH_SECRET: \${BETTER_AUTH_SECRET}
@@ -10848,7 +10854,7 @@ volumes:
10848
10854
  db_data:`
10849
10855
  },
10850
10856
  {
10851
- when: (s) => !s.nestDiOnly,
10857
+ when: (s) => s.nest === "on",
10852
10858
  filename: "apps/web/next.config.js",
10853
10859
  template: `import dotenv from 'dotenv';
10854
10860
  import { resolve } from 'path';
@@ -11098,8 +11104,7 @@ export async function GET() {
11098
11104
  "scripts": {
11099
11105
  "dev": "next dev --port 3000",
11100
11106
  "build": "next build",
11101
- "start": "next start",
11102
- "db:migrate": "better-auth migrate"
11107
+ "start": "next start"
11103
11108
  },
11104
11109
  "dependencies": {
11105
11110
  "@<%= projectName %>/api": "workspace:*",
@@ -11183,8 +11188,38 @@ export default nextConfig;`
11183
11188
  }
11184
11189
  ] };
11185
11190
  //#endregion
11186
- //#region src/templates/deployment-standalone-di/index.ts
11187
- const deploymentStandaloneDi = { templates: [
11191
+ //#region src/templates/nest-off/index.ts
11192
+ const nestOff = { templates: [{
11193
+ when: (s) => s.deployment === "none",
11194
+ filename: "apps/web/next.config.js",
11195
+ template: `import dotenv from 'dotenv';
11196
+ import { resolve } from 'path';
11197
+
11198
+ // Load root .env first, then local .env (local takes precedence)
11199
+ dotenv.config({ path: resolve(process.cwd(), '../../.env') });
11200
+ dotenv.config({ path: resolve(process.cwd(), '.env') });
11201
+
11202
+ // No /api rewrite: there is no second process, so Next serves /api itself.
11203
+ /** @type {import('next').NextConfig} */
11204
+ const nextConfig = {};
11205
+
11206
+ export default nextConfig;`
11207
+ }, {
11208
+ filename: "apps/web/app/api/hello/route.ts",
11209
+ template: `import { NextResponse } from 'next/server';
11210
+ import { headers } from 'next/headers';
11211
+ import { auth } from '@<%= projectName %>/auth';
11212
+
11213
+ export async function GET() {
11214
+ const session = await auth.api.getSession({ headers: await headers() });
11215
+ return NextResponse.json({
11216
+ message: session?.user.name ? \`Hello \${session.user.name}\` : 'Hello from Next',
11217
+ });
11218
+ }`
11219
+ }] };
11220
+ //#endregion
11221
+ //#region src/templates/deployment-standalone-web/index.ts
11222
+ const deploymentStandaloneWeb = { templates: [
11188
11223
  {
11189
11224
  filename: "Dockerfile",
11190
11225
  template: `FROM node:24-alpine AS base
@@ -11196,11 +11231,11 @@ FROM base AS build
11196
11231
  WORKDIR /app
11197
11232
  COPY . .
11198
11233
  RUN pnpm install --frozen-lockfile
11199
- RUN pnpm build --filter=web --filter=@<%= projectName %>/api --filter=@<%= projectName %>/auth
11234
+ RUN pnpm build --filter=web<% if (nest === 'di-only') { %> --filter=@<%= projectName %>/api<% } %> --filter=@<%= projectName %>/auth
11200
11235
 
11201
11236
  # --- 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.
11237
+ # One image: <% if (nest === 'di-only') { %>Nest is wired into the Next.js server rather than bootstrapped
11238
+ # on its own port<% } else { %>Next.js serves /api itself<% } %>, so there is no separate api stage.
11204
11239
  FROM base AS web
11205
11240
  WORKDIR /app
11206
11241
  ENV NODE_ENV=production
@@ -11285,11 +11320,11 @@ import { resolve } from 'path';
11285
11320
  dotenv.config({ path: resolve(process.cwd(), '../../.env') });
11286
11321
  dotenv.config({ path: resolve(process.cwd(), '.env') });
11287
11322
 
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.
11323
+ // No /api rewrite: Next serves /api itself, so there is no api container to
11324
+ // proxy to.
11290
11325
  /** @type {import('next').NextConfig} */
11291
11326
  const nextConfig = {
11292
- output: "standalone",
11327
+ output: "standalone",<% if (nest === 'di-only') { %>
11293
11328
  serverExternalPackages: [
11294
11329
  '@<%= projectName %>/api',
11295
11330
  '@<%= projectName %>/db',
@@ -11300,7 +11335,7 @@ const nextConfig = {
11300
11335
  '@thallesp/nestjs-better-auth',
11301
11336
  'reflect-metadata',
11302
11337
  'express',
11303
- ],
11338
+ ],<% } %>
11304
11339
  };
11305
11340
 
11306
11341
  export default nextConfig;`
@@ -11358,7 +11393,7 @@ describe('AppController', () => {
11358
11393
  });`
11359
11394
  },
11360
11395
  {
11361
- when: (s) => !s.nestDiOnly && !s.todoExample,
11396
+ when: (s) => s.nest === "on" && !s.todoExample,
11362
11397
  filename: "apps/api/src/app.module.ts",
11363
11398
  template: `<% if (deployment === 'spa') { %>import { join } from 'path';
11364
11399
  <% } %>import { Module } from '@nestjs/common';
@@ -11411,7 +11446,7 @@ void bootstrap();`
11411
11446
  //#endregion
11412
11447
  //#region src/templates/todo-example/templates/todos-module.ts
11413
11448
  var todos_module_default = {
11414
- when: (s) => s.nestDiOnly,
11449
+ when: (s) => s.nest === "di-only",
11415
11450
  filename: "apps/api/src/todos/todos.module.ts",
11416
11451
  template: `import { Module } from '@nestjs/common';
11417
11452
  import { TodosService } from './todos.service';
@@ -11671,7 +11706,7 @@ export class TodosModule {}`
11671
11706
  //#endregion
11672
11707
  //#region src/templates/todo-example/templates/app-module-controllers.ts
11673
11708
  var app_module_controllers_default = {
11674
- when: (s) => !s.nestDiOnly && s.todoExample,
11709
+ when: (s) => s.nest === "on" && s.todoExample,
11675
11710
  filename: "apps/api/src/app.module.ts",
11676
11711
  template: `<% if (deployment === 'spa') { %>import { join } from 'path';
11677
11712
  <% } %>import { Module } from '@nestjs/common';
@@ -11702,7 +11737,7 @@ export class AppModule {}`
11702
11737
  //#endregion
11703
11738
  //#region src/templates/todo-example/templates/app-module-di.ts
11704
11739
  var app_module_di_default = {
11705
- when: (s) => s.nestDiOnly && s.todoExample,
11740
+ when: (s) => s.nest === "di-only" && s.todoExample,
11706
11741
  filename: "apps/api/src/app.module.ts",
11707
11742
  template: `import { Module } from '@nestjs/common';
11708
11743
  import { AppService } from './app.service';
@@ -12306,35 +12341,36 @@ const E2E_FILES = [
12306
12341
  "apps/api/vitest.config.e2e.mts"
12307
12342
  ];
12308
12343
  function selectModules(selection) {
12309
- const { deployment, nestDiOnly: nestDiOnly$1, todoExample, shadcn, database, linter, testing, extras } = selection;
12344
+ const { deployment, nest, todoExample, shadcn, database, linter, testing, extras } = selection;
12310
12345
  const deploymentModule = deployment === "standalone" ? deploymentStandalone : deployment === "spa" ? singleProcessStaticExport : null;
12311
12346
  const webModule = deployment === "spa" ? {
12312
12347
  ...web$1,
12313
12348
  templates: web$1.templates.filter((t) => t.filename !== "apps/web/app/api/auth/[...all]/route.ts")
12314
12349
  } : web$1;
12315
12350
  const selectedTesting = testing === "vitest" ? testingVitest : testingJest;
12316
- const testingModule = nestDiOnly$1 ? {
12351
+ const testingModule = nest === "off" ? null : nest === "di-only" ? {
12317
12352
  ...selectedTesting,
12318
12353
  templates: selectedTesting.templates.filter((t) => !E2E_FILES.includes(t.filename)),
12319
12354
  scripts: selectedTesting.scripts?.filter((s) => s.name !== "test:e2e")
12320
12355
  } : selectedTesting;
12356
+ const nestModule = nest === "di-only" ? nestDiOnly : nest === "off" ? nestOff : apiControllers;
12321
12357
  return [
12322
12358
  root$2,
12323
12359
  webModule,
12324
- api$1,
12360
+ ...nest === "off" ? [] : [api$1],
12325
12361
  database === "postgres" ? dbPostgres : dbSqlite,
12326
12362
  auth,
12327
12363
  shadcn ? shadcnUi : ui$1,
12328
12364
  linter === "oxc" ? oxc : eslintConfig,
12329
12365
  ...extras.includes("anti-slop") ? [antiSlop] : [],
12330
12366
  typescriptConfig,
12331
- testingModule,
12367
+ ...testingModule ? [testingModule] : [],
12332
12368
  ...deploymentModule ? [deploymentModule] : [],
12333
- ...nestDiOnly$1 ? [nestDiOnly] : [apiControllers],
12334
- ...nestDiOnly$1 && deployment === "standalone" ? [deploymentStandaloneDi] : [],
12369
+ nestModule,
12370
+ ...nest !== "on" && deployment === "standalone" ? [deploymentStandaloneWeb] : [],
12335
12371
  ...todoExample ? [
12336
12372
  todoExampleApi,
12337
- ...nestDiOnly$1 ? [todoExampleDi] : [todoExampleControllers],
12373
+ ...nest === "di-only" ? [todoExampleDi] : [todoExampleControllers],
12338
12374
  shadcn ? todoExampleShadcn : todoExampleWeb
12339
12375
  ] : []
12340
12376
  ];
@@ -12442,10 +12478,21 @@ function validateExtrasCombo(extras, linter) {
12442
12478
  };
12443
12479
  return { valid: true };
12444
12480
  }
12445
- function validateDeploymentCombo(deployment, nestDiOnly) {
12446
- if (deployment === "spa" && nestDiOnly) return {
12481
+ function validateDeploymentCombo(deployment, nest) {
12482
+ if (deployment === "spa" && nest === "di-only") return {
12483
+ valid: false,
12484
+ 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."
12485
+ };
12486
+ if (deployment === "spa" && nest === "off") return {
12447
12487
  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."
12488
+ 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."
12489
+ };
12490
+ return { valid: true };
12491
+ }
12492
+ function validateExampleCombo(todoExample, nest) {
12493
+ if (todoExample && nest === "off") return {
12494
+ valid: false,
12495
+ 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
12496
  };
12450
12497
  return { valid: true };
12451
12498
  }
@@ -12502,7 +12549,7 @@ async function scaffold(modules, options) {
12502
12549
  }
12503
12550
  const templateData = {
12504
12551
  projectName: options.name,
12505
- nestDiOnly: options.selection.nestDiOnly,
12552
+ nest: options.selection.nest,
12506
12553
  testing: options.testing,
12507
12554
  database: options.database,
12508
12555
  deployment: options.deployment,
@@ -12590,7 +12637,7 @@ function buildPayload(report) {
12590
12637
  database: selection.database,
12591
12638
  linter: selection.linter,
12592
12639
  deployment: selection.deployment,
12593
- nestDiOnly: selection.nestDiOnly,
12640
+ nest: selection.nest,
12594
12641
  todoExample: selection.todoExample,
12595
12642
  antiSlop: selection.extras.includes("anti-slop")
12596
12643
  };
@@ -12635,6 +12682,11 @@ const DEPLOYMENT_CHOICES = [
12635
12682
  "standalone",
12636
12683
  "spa"
12637
12684
  ];
12685
+ const NEST_CHOICES = [
12686
+ "on",
12687
+ "off",
12688
+ "di-only"
12689
+ ];
12638
12690
  const EXTRAS_CHOICES = ["anti-slop"];
12639
12691
  var TaskBuilder = class {
12640
12692
  tasks = [];
@@ -12654,7 +12706,28 @@ async function doInit(options) {
12654
12706
  message: "Use shadcn/ui?",
12655
12707
  initialValue: true
12656
12708
  }),
12657
- testing: () => p.select({
12709
+ nest: () => p.select({
12710
+ message: "NestJS?",
12711
+ options: [
12712
+ {
12713
+ value: "on",
12714
+ label: "On",
12715
+ hint: "apps/api on port 3001"
12716
+ },
12717
+ {
12718
+ value: "di-only",
12719
+ label: "DI only",
12720
+ hint: "no HTTP server; Next.js route handlers inject its services"
12721
+ },
12722
+ {
12723
+ value: "off",
12724
+ label: "Off",
12725
+ hint: "no apps/api; Next.js owns the backend"
12726
+ }
12727
+ ],
12728
+ initialValue: "on"
12729
+ }),
12730
+ testing: ({ results }) => results.nest === "off" ? void 0 : p.select({
12658
12731
  message: "Testing framework?",
12659
12732
  options: [{
12660
12733
  value: "jest",
@@ -12696,11 +12769,7 @@ async function doInit(options) {
12696
12769
  }],
12697
12770
  required: false
12698
12771
  }) : void 0,
12699
- nestDiOnly: () => p.confirm({
12700
- message: "Use NestJS for dependency injection only?",
12701
- initialValue: false
12702
- }),
12703
- todoExample: () => p.confirm({
12772
+ todoExample: ({ results }) => results.nest === "off" ? void 0 : p.confirm({
12704
12773
  message: "Include the todo example?",
12705
12774
  initialValue: true
12706
12775
  }),
@@ -12717,11 +12786,11 @@ async function doInit(options) {
12717
12786
  label: "Standalone + Dockerfile",
12718
12787
  hint: "Dockerfiles + docker-compose.yml"
12719
12788
  },
12720
- ...results.nestDiOnly ? [] : [{
12789
+ ...results.nest === "on" ? [{
12721
12790
  value: "spa",
12722
12791
  label: "SPA Mode",
12723
12792
  hint: "static export served by NestJS"
12724
- }]
12793
+ }] : []
12725
12794
  ],
12726
12795
  initialValue: "none"
12727
12796
  })
@@ -12746,16 +12815,18 @@ async function doInit(options) {
12746
12815
  const database = options.nonInteractive ? options.database : answers.database ?? "sqlite";
12747
12816
  const linter = options.nonInteractive ? options.linter : answers.linter ?? "eslint";
12748
12817
  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;
12818
+ const nest = options.nonInteractive ? options.nest : answers.nest ?? "on";
12819
+ const todoExample = options.nonInteractive ? options.includeExample : nest !== "off" && (answers.todoExample ?? true);
12751
12820
  const extras = options.nonInteractive ? options.extras : answers.extras ?? [];
12752
- const deploymentCombo = validateDeploymentCombo(deployment, nestDiOnly);
12821
+ const deploymentCombo = validateDeploymentCombo(deployment, nest);
12753
12822
  if (!deploymentCombo.valid) throw new Error(deploymentCombo.error);
12823
+ const exampleCombo = validateExampleCombo(todoExample, nest);
12824
+ if (!exampleCombo.valid) throw new Error(exampleCombo.error);
12754
12825
  const extrasCombo = validateExtrasCombo(extras, linter);
12755
12826
  if (!extrasCombo.valid) throw new Error(extrasCombo.error);
12756
12827
  const selection = {
12757
12828
  deployment,
12758
- nestDiOnly,
12829
+ nest,
12759
12830
  todoExample,
12760
12831
  shadcn: useShadcn,
12761
12832
  database,
@@ -12826,7 +12897,7 @@ async function doInit(options) {
12826
12897
  }
12827
12898
  }
12828
12899
  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) => {
12900
+ 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
12901
  intro(`Create a ${chalk.blue("newt")} app.`);
12831
12902
  const explicitFlags = Object.entries({
12832
12903
  shadcn: "--shadcn",
@@ -12834,7 +12905,7 @@ program.name("create-newt-app").version(version).description("Create a new newt-
12834
12905
  database: "--database",
12835
12906
  linter: "--linter",
12836
12907
  deployment: "--deployment",
12837
- nestDiOnly: "--nest-di-only",
12908
+ nest: "--nest",
12838
12909
  includeExample: "--include-example",
12839
12910
  extras: "--extras"
12840
12911
  }).filter(([option]) => command.getOptionValueSource(option) === "cli").map(([, flag]) => flag);
@@ -12861,6 +12932,11 @@ program.name("create-newt-app").version(version).description("Create a new newt-
12861
12932
  value: options.deployment,
12862
12933
  allowed: DEPLOYMENT_CHOICES
12863
12934
  },
12935
+ {
12936
+ flag: "--nest",
12937
+ value: options.nest,
12938
+ allowed: NEST_CHOICES
12939
+ },
12864
12940
  ...extras.map((extra) => ({
12865
12941
  flag: "--extras",
12866
12942
  value: extra,
@@ -12881,7 +12957,7 @@ program.name("create-newt-app").version(version).description("Create a new newt-
12881
12957
  database: options.database,
12882
12958
  linter: options.linter,
12883
12959
  deployment: options.deployment,
12884
- nestDiOnly: options.nestDiOnly,
12960
+ nest: options.nest,
12885
12961
  includeExample: options.includeExample,
12886
12962
  extras,
12887
12963
  explicitFlags