create-newt-app 0.23.0 → 0.23.2
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 +8 -4
- package/dist/index.js +253 -52
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
declare const TESTING_CHOICES: readonly ["jest", "vitest"];
|
|
3
|
+
declare const DATABASE_CHOICES: readonly ["sqlite", "postgres"];
|
|
4
|
+
declare const LINTER_CHOICES: readonly ["eslint", "oxc"];
|
|
5
|
+
declare const DEPLOYMENT_CHOICES: readonly ["none", "standalone", "custom-server", "spa"];
|
|
6
|
+
type Testing = (typeof TESTING_CHOICES)[number];
|
|
7
|
+
type Database = (typeof DATABASE_CHOICES)[number];
|
|
8
|
+
type Linter = (typeof LINTER_CHOICES)[number];
|
|
9
|
+
type Deployment = (typeof DEPLOYMENT_CHOICES)[number];
|
|
6
10
|
type Options = {
|
|
7
11
|
name?: string;
|
|
8
12
|
install: boolean;
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import chalk from "chalk";
|
|
|
7
7
|
// package.json
|
|
8
8
|
var package_default = {
|
|
9
9
|
name: "create-newt-app",
|
|
10
|
-
version: "0.23.
|
|
10
|
+
version: "0.23.2",
|
|
11
11
|
license: "MIT",
|
|
12
12
|
private: false,
|
|
13
13
|
type: "module",
|
|
@@ -10183,12 +10183,11 @@ var api_package_json_default = {
|
|
|
10183
10183
|
"private": true,
|
|
10184
10184
|
"license": "UNLICENSED",
|
|
10185
10185
|
"exports": {
|
|
10186
|
-
".": "./
|
|
10186
|
+
".": "./dist/index.js"
|
|
10187
10187
|
},
|
|
10188
10188
|
"scripts": {
|
|
10189
10189
|
"build": "nest build",
|
|
10190
10190
|
"start": "nest start",
|
|
10191
|
-
"dev": "nest start --watch",
|
|
10192
10191
|
"start:dev": "nest start --watch",
|
|
10193
10192
|
"start:debug": "nest start --debug --watch",
|
|
10194
10193
|
"start:prod": "node dist/main"
|
|
@@ -10251,6 +10250,8 @@ async function main() {
|
|
|
10251
10250
|
await nextApp.prepare();
|
|
10252
10251
|
|
|
10253
10252
|
const nestApp = await NestFactory.create(AppModule);
|
|
10253
|
+
// apps/api/src/main.ts never runs here, so its prefix is set again
|
|
10254
|
+
nestApp.setGlobalPrefix('api');
|
|
10254
10255
|
await nestApp.init();
|
|
10255
10256
|
|
|
10256
10257
|
const nestListener = nestApp
|
|
@@ -10283,14 +10284,15 @@ var web_package_json_default = {
|
|
|
10283
10284
|
"private": true,
|
|
10284
10285
|
"scripts": {
|
|
10285
10286
|
"dev": "tsx watch --tsconfig tsconfig.server.json server.ts",
|
|
10286
|
-
"build": "next build",
|
|
10287
|
-
"start": "
|
|
10287
|
+
"build": "next build && tsc -p tsconfig.server.json",
|
|
10288
|
+
"start": "node dist/server.js",
|
|
10288
10289
|
"db:migrate": "better-auth migrate"
|
|
10289
10290
|
},
|
|
10290
10291
|
"dependencies": {
|
|
10291
10292
|
"@<%= projectName %>/api": "workspace:*",
|
|
10292
10293
|
"@<%= projectName %>/auth": "workspace:*",
|
|
10293
10294
|
"@<%= projectName %>/ui": "workspace:*",
|
|
10295
|
+
"@nestjs/core": "^11.0.1",
|
|
10294
10296
|
"@tailwindcss/postcss": "^4.2.1",
|
|
10295
10297
|
"dotenv": "^17.3.1",
|
|
10296
10298
|
"@tanstack/react-form": "^1.28.5",
|
|
@@ -10299,6 +10301,7 @@ var web_package_json_default = {
|
|
|
10299
10301
|
"next": "16.2.10",
|
|
10300
10302
|
"react": "^19.2.4",
|
|
10301
10303
|
"react-dom": "^19.2.4",
|
|
10304
|
+
"reflect-metadata": "^0.2.2",
|
|
10302
10305
|
"tailwindcss": "^4.2.1"
|
|
10303
10306
|
},
|
|
10304
10307
|
"devDependencies": {
|
|
@@ -10322,10 +10325,10 @@ import { resolve } from 'path';
|
|
|
10322
10325
|
dotenv.config({ path: resolve(process.cwd(), '../../.env') });
|
|
10323
10326
|
dotenv.config({ path: resolve(process.cwd(), '.env') });
|
|
10324
10327
|
|
|
10328
|
+
// No output setting: server.ts is the server, so Next runs in-process rather
|
|
10329
|
+
// than through its own standalone entrypoint.
|
|
10325
10330
|
/** @type {import('next').NextConfig} */
|
|
10326
|
-
const nextConfig = {
|
|
10327
|
-
output: "standalone",
|
|
10328
|
-
};
|
|
10331
|
+
const nextConfig = {};
|
|
10329
10332
|
|
|
10330
10333
|
export default nextConfig;`
|
|
10331
10334
|
};
|
|
@@ -10362,8 +10365,9 @@ var web_tsconfig_server_default = {
|
|
|
10362
10365
|
filename: "apps/web/tsconfig.server.json",
|
|
10363
10366
|
template: `{
|
|
10364
10367
|
"compilerOptions": {
|
|
10365
|
-
"module": "
|
|
10366
|
-
"moduleResolution": "
|
|
10368
|
+
"module": "esnext",
|
|
10369
|
+
"moduleResolution": "bundler",
|
|
10370
|
+
"outDir": "dist",
|
|
10367
10371
|
"target": "ES2023",
|
|
10368
10372
|
"esModuleInterop": true,
|
|
10369
10373
|
"emitDecoratorMetadata": true,
|
|
@@ -10378,6 +10382,42 @@ var web_tsconfig_server_default = {
|
|
|
10378
10382
|
}`
|
|
10379
10383
|
};
|
|
10380
10384
|
|
|
10385
|
+
// src/templates/single-process-custom-server/templates/turbo-json.ts
|
|
10386
|
+
var turbo_json_default3 = {
|
|
10387
|
+
filename: "turbo.json",
|
|
10388
|
+
template: `{
|
|
10389
|
+
"$schema": "https://turborepo.dev/schema.json",
|
|
10390
|
+
"ui": "tui",
|
|
10391
|
+
"tasks": {
|
|
10392
|
+
"build": {
|
|
10393
|
+
"dependsOn": ["^build"],
|
|
10394
|
+
"inputs": ["$TURBO_DEFAULT$", ".env*"],
|
|
10395
|
+
"outputs": [".next/**", "!.next/cache/**", "dist/**"]
|
|
10396
|
+
},
|
|
10397
|
+
"lint": {
|
|
10398
|
+
"dependsOn": ["^lint"],
|
|
10399
|
+
"env": ["NODE_ENV"]
|
|
10400
|
+
},
|
|
10401
|
+
"test": {
|
|
10402
|
+
"dependsOn": ["^build"],
|
|
10403
|
+
"outputs": ["coverage/**"]
|
|
10404
|
+
},
|
|
10405
|
+
"dev": {
|
|
10406
|
+
"dependsOn": ["^migrate", "^build"],
|
|
10407
|
+
"cache": false,
|
|
10408
|
+
"persistent": true
|
|
10409
|
+
},
|
|
10410
|
+
"migrate": {
|
|
10411
|
+
"dependsOn": ["^migrate"],
|
|
10412
|
+
"cache": false
|
|
10413
|
+
},
|
|
10414
|
+
"generate": {
|
|
10415
|
+
"cache": false
|
|
10416
|
+
}
|
|
10417
|
+
}
|
|
10418
|
+
}`
|
|
10419
|
+
};
|
|
10420
|
+
|
|
10381
10421
|
// src/templates/single-process-custom-server/index.ts
|
|
10382
10422
|
var singleProcessCustomServer = {
|
|
10383
10423
|
templates: [
|
|
@@ -10387,38 +10427,12 @@ var singleProcessCustomServer = {
|
|
|
10387
10427
|
web_package_json_default,
|
|
10388
10428
|
web_next_config_default,
|
|
10389
10429
|
web_tsconfig_default,
|
|
10390
|
-
web_tsconfig_server_default
|
|
10430
|
+
web_tsconfig_server_default,
|
|
10431
|
+
turbo_json_default3
|
|
10391
10432
|
]
|
|
10392
10433
|
};
|
|
10393
10434
|
var single_process_custom_server_default = singleProcessCustomServer;
|
|
10394
10435
|
|
|
10395
|
-
// src/templates/single-process-static-export/templates/api-app-module.ts
|
|
10396
|
-
var api_app_module_default = {
|
|
10397
|
-
filename: "apps/api/src/app.module.ts",
|
|
10398
|
-
template: `import { join } from 'path';
|
|
10399
|
-
import { Module } from '@nestjs/common';
|
|
10400
|
-
import { APP_GUARD } from '@nestjs/core';
|
|
10401
|
-
import { ServeStaticModule } from '@nestjs/serve-static';
|
|
10402
|
-
import { AuthGuard, AuthModule } from '@thallesp/nestjs-better-auth';
|
|
10403
|
-
import { auth } from '@<%= projectName %>/auth';
|
|
10404
|
-
import { AppController } from './app.controller';
|
|
10405
|
-
import { TodosModule } from './todos/todos.module';
|
|
10406
|
-
|
|
10407
|
-
@Module({
|
|
10408
|
-
imports: [
|
|
10409
|
-
ServeStaticModule.forRoot({
|
|
10410
|
-
rootPath: join(process.cwd(), '../web/out'),
|
|
10411
|
-
exclude: ['/api/(.*)'],
|
|
10412
|
-
}),
|
|
10413
|
-
AuthModule.forRoot({ auth }),
|
|
10414
|
-
TodosModule,
|
|
10415
|
-
],
|
|
10416
|
-
controllers: [AppController],
|
|
10417
|
-
providers: [{ provide: APP_GUARD, useClass: AuthGuard }],
|
|
10418
|
-
})
|
|
10419
|
-
export class AppModule {}`
|
|
10420
|
-
};
|
|
10421
|
-
|
|
10422
10436
|
// src/templates/single-process-static-export/templates/api-package-json.ts
|
|
10423
10437
|
var api_package_json_default2 = {
|
|
10424
10438
|
filename: "apps/api/package.json",
|
|
@@ -10500,7 +10514,7 @@ export default nextConfig;`
|
|
|
10500
10514
|
|
|
10501
10515
|
// src/templates/single-process-static-export/index.ts
|
|
10502
10516
|
var singleProcessStaticExport = {
|
|
10503
|
-
templates: [
|
|
10517
|
+
templates: [api_package_json_default2, web_next_config_default2]
|
|
10504
10518
|
};
|
|
10505
10519
|
var single_process_static_export_default = singleProcessStaticExport;
|
|
10506
10520
|
|
|
@@ -10732,6 +10746,126 @@ var nestDiOnly = {
|
|
|
10732
10746
|
};
|
|
10733
10747
|
var nest_di_only_default = nestDiOnly;
|
|
10734
10748
|
|
|
10749
|
+
// src/templates/deployment-standalone-di/templates/dockerfile.ts
|
|
10750
|
+
var dockerfile_default2 = {
|
|
10751
|
+
filename: "Dockerfile",
|
|
10752
|
+
template: `FROM node:22-alpine AS base
|
|
10753
|
+
ENV PNPM_HOME="/pnpm"
|
|
10754
|
+
ENV PATH="$PNPM_HOME:$PATH"
|
|
10755
|
+
RUN corepack enable
|
|
10756
|
+
|
|
10757
|
+
FROM base AS build
|
|
10758
|
+
WORKDIR /app
|
|
10759
|
+
COPY . .
|
|
10760
|
+
RUN pnpm install --frozen-lockfile
|
|
10761
|
+
RUN pnpm build --filter=web --filter=api --filter=@<%= projectName %>/auth
|
|
10762
|
+
|
|
10763
|
+
# --- web ---
|
|
10764
|
+
# DI-only has no api entrypoint: Nest is wired into this image through the
|
|
10765
|
+
# Next.js server, so there is no separate api stage.
|
|
10766
|
+
FROM base AS web
|
|
10767
|
+
WORKDIR /app
|
|
10768
|
+
ENV NODE_ENV=production
|
|
10769
|
+
COPY --from=build /app/apps/web/.next/standalone ./
|
|
10770
|
+
COPY --from=build /app/apps/web/.next/static ./apps/web/.next/static
|
|
10771
|
+
COPY --from=build /app/apps/web/public ./apps/web/public
|
|
10772
|
+
EXPOSE 3000
|
|
10773
|
+
CMD ["node", "apps/web/server.js"]
|
|
10774
|
+
|
|
10775
|
+
# --- migrate ---
|
|
10776
|
+
FROM build AS migrate
|
|
10777
|
+
WORKDIR /app
|
|
10778
|
+
CMD ["pnpm", "db:migrate"]`
|
|
10779
|
+
};
|
|
10780
|
+
|
|
10781
|
+
// src/templates/deployment-standalone-di/templates/docker-compose.ts
|
|
10782
|
+
var docker_compose_default2 = {
|
|
10783
|
+
filename: "docker-compose.yml",
|
|
10784
|
+
template: `x-app-env: &app-env
|
|
10785
|
+
BETTER_AUTH_SECRET: \${BETTER_AUTH_SECRET}
|
|
10786
|
+
DATABASE_URL: postgresql://postgres:\${POSTGRES_PASSWORD:-postgres}@db:5432/postgres
|
|
10787
|
+
|
|
10788
|
+
services:
|
|
10789
|
+
web:
|
|
10790
|
+
build:
|
|
10791
|
+
context: .
|
|
10792
|
+
target: web
|
|
10793
|
+
ports:
|
|
10794
|
+
- "3000:3000"
|
|
10795
|
+
environment:
|
|
10796
|
+
<<: *app-env
|
|
10797
|
+
depends_on:
|
|
10798
|
+
db:
|
|
10799
|
+
condition: service_healthy
|
|
10800
|
+
migrate:
|
|
10801
|
+
condition: service_completed_successfully
|
|
10802
|
+
|
|
10803
|
+
migrate:
|
|
10804
|
+
build:
|
|
10805
|
+
context: .
|
|
10806
|
+
target: migrate
|
|
10807
|
+
environment:
|
|
10808
|
+
<<: *app-env
|
|
10809
|
+
depends_on:
|
|
10810
|
+
db:
|
|
10811
|
+
condition: service_healthy
|
|
10812
|
+
restart: "no"
|
|
10813
|
+
|
|
10814
|
+
db:
|
|
10815
|
+
image: postgres:17-alpine
|
|
10816
|
+
ports:
|
|
10817
|
+
- "5432:5432"
|
|
10818
|
+
environment:
|
|
10819
|
+
- POSTGRES_PASSWORD=\${POSTGRES_PASSWORD:-postgres}
|
|
10820
|
+
volumes:
|
|
10821
|
+
- db_data:/var/lib/postgresql/data
|
|
10822
|
+
healthcheck:
|
|
10823
|
+
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
|
10824
|
+
interval: 5s
|
|
10825
|
+
timeout: 5s
|
|
10826
|
+
retries: 5
|
|
10827
|
+
|
|
10828
|
+
volumes:
|
|
10829
|
+
db_data:`
|
|
10830
|
+
};
|
|
10831
|
+
|
|
10832
|
+
// src/templates/deployment-standalone-di/templates/next-config.ts
|
|
10833
|
+
var next_config_default3 = {
|
|
10834
|
+
filename: "apps/web/next.config.js",
|
|
10835
|
+
template: `import dotenv from 'dotenv';
|
|
10836
|
+
import { resolve } from 'path';
|
|
10837
|
+
|
|
10838
|
+
// Load root .env first, then local .env (local takes precedence)
|
|
10839
|
+
dotenv.config({ path: resolve(process.cwd(), '../../.env') });
|
|
10840
|
+
dotenv.config({ path: resolve(process.cwd(), '.env') });
|
|
10841
|
+
|
|
10842
|
+
// No /api rewrite: DI-only runs Nest inside this process, so Next serves
|
|
10843
|
+
// /api itself and there is no separate api container to proxy to.
|
|
10844
|
+
/** @type {import('next').NextConfig} */
|
|
10845
|
+
const nextConfig = {
|
|
10846
|
+
output: "standalone",
|
|
10847
|
+
serverExternalPackages: [
|
|
10848
|
+
'@<%= projectName %>/api',
|
|
10849
|
+
'@<%= projectName %>/db',
|
|
10850
|
+
'@nestjs/core',
|
|
10851
|
+
'@nestjs/common',
|
|
10852
|
+
'@nestjs/microservices',
|
|
10853
|
+
'@nestjs/websockets',
|
|
10854
|
+
'@thallesp/nestjs-better-auth',
|
|
10855
|
+
'reflect-metadata',
|
|
10856
|
+
'express',
|
|
10857
|
+
],
|
|
10858
|
+
};
|
|
10859
|
+
|
|
10860
|
+
export default nextConfig;`
|
|
10861
|
+
};
|
|
10862
|
+
|
|
10863
|
+
// src/templates/deployment-standalone-di/index.ts
|
|
10864
|
+
var deploymentStandaloneDi = {
|
|
10865
|
+
templates: [dockerfile_default2, docker_compose_default2, next_config_default3]
|
|
10866
|
+
};
|
|
10867
|
+
var deployment_standalone_di_default = deploymentStandaloneDi;
|
|
10868
|
+
|
|
10735
10869
|
// src/templates/api-controllers/templates/app-controller.ts
|
|
10736
10870
|
var app_controller_default = {
|
|
10737
10871
|
filename: "apps/api/src/app.controller.ts",
|
|
@@ -10787,15 +10921,26 @@ describe('AppController', () => {
|
|
|
10787
10921
|
// src/templates/api-controllers/templates/app-module.ts
|
|
10788
10922
|
var app_module_default2 = {
|
|
10789
10923
|
filename: "apps/api/src/app.module.ts",
|
|
10790
|
-
template:
|
|
10924
|
+
template: `<% if (deployment === 'spa') { %>import { join } from 'path';
|
|
10925
|
+
<% } %>import { Module } from '@nestjs/common';
|
|
10791
10926
|
import { APP_GUARD } from '@nestjs/core';
|
|
10792
|
-
import {
|
|
10927
|
+
<% if (deployment === 'spa') { %>import { ServeStaticModule } from '@nestjs/serve-static';
|
|
10928
|
+
<% } %>import { AuthGuard, AuthModule } from '@thallesp/nestjs-better-auth';
|
|
10793
10929
|
import { auth } from '@<%= projectName %>/auth';
|
|
10794
10930
|
import { AppController } from './app.controller';
|
|
10795
10931
|
import { AppService } from './app.service';
|
|
10796
10932
|
|
|
10797
10933
|
@Module({
|
|
10798
|
-
imports: [
|
|
10934
|
+
<% if (deployment === 'spa') { %> imports: [
|
|
10935
|
+
// serves apps/web's static export; the api runs from apps/api
|
|
10936
|
+
ServeStaticModule.forRoot({
|
|
10937
|
+
rootPath: join(process.cwd(), '../web/out'),
|
|
10938
|
+
exclude: ['/api/{*splat}'],
|
|
10939
|
+
}),
|
|
10940
|
+
AuthModule.forRoot({ auth }),
|
|
10941
|
+
],
|
|
10942
|
+
<% } else { %> imports: [AuthModule.forRoot({ auth })],
|
|
10943
|
+
<% } -%>
|
|
10799
10944
|
controllers: [AppController],
|
|
10800
10945
|
providers: [AppService, { provide: APP_GUARD, useClass: AuthGuard }],
|
|
10801
10946
|
})
|
|
@@ -11099,16 +11244,28 @@ export class TodosModule {}`
|
|
|
11099
11244
|
// src/templates/todo-example/templates/app-module-controllers.ts
|
|
11100
11245
|
var app_module_controllers_default = {
|
|
11101
11246
|
filename: "apps/api/src/app.module.ts",
|
|
11102
|
-
template:
|
|
11247
|
+
template: `<% if (deployment === 'spa') { %>import { join } from 'path';
|
|
11248
|
+
<% } %>import { Module } from '@nestjs/common';
|
|
11103
11249
|
import { APP_GUARD } from '@nestjs/core';
|
|
11104
|
-
import {
|
|
11250
|
+
<% if (deployment === 'spa') { %>import { ServeStaticModule } from '@nestjs/serve-static';
|
|
11251
|
+
<% } %>import { AuthGuard, AuthModule } from '@thallesp/nestjs-better-auth';
|
|
11105
11252
|
import { auth } from '@<%= projectName %>/auth';
|
|
11106
11253
|
import { AppController } from './app.controller';
|
|
11107
11254
|
import { AppService } from './app.service';
|
|
11108
11255
|
import { TodosModule } from './todos/todos.module';
|
|
11109
11256
|
|
|
11110
11257
|
@Module({
|
|
11111
|
-
|
|
11258
|
+
<% if (deployment === 'spa') { %> imports: [
|
|
11259
|
+
// serves apps/web's static export; the api runs from apps/api
|
|
11260
|
+
ServeStaticModule.forRoot({
|
|
11261
|
+
rootPath: join(process.cwd(), '../web/out'),
|
|
11262
|
+
exclude: ['/api/{*splat}'],
|
|
11263
|
+
}),
|
|
11264
|
+
AuthModule.forRoot({ auth }),
|
|
11265
|
+
TodosModule,
|
|
11266
|
+
],
|
|
11267
|
+
<% } else { %> imports: [AuthModule.forRoot({ auth }), TodosModule],
|
|
11268
|
+
<% } -%>
|
|
11112
11269
|
controllers: [AppController],
|
|
11113
11270
|
providers: [AppService, { provide: APP_GUARD, useClass: AuthGuard }],
|
|
11114
11271
|
})
|
|
@@ -11730,6 +11887,7 @@ var templates = {
|
|
|
11730
11887
|
deploymentCustomServer: single_process_custom_server_default,
|
|
11731
11888
|
deploymentSpa: single_process_static_export_default,
|
|
11732
11889
|
nestDiOnly: nest_di_only_default,
|
|
11890
|
+
deploymentStandaloneDi: deployment_standalone_di_default,
|
|
11733
11891
|
apiControllers: api_controllers_default,
|
|
11734
11892
|
todoExampleApi,
|
|
11735
11893
|
todoExampleControllers,
|
|
@@ -11853,6 +12011,24 @@ async function sortPackageJsons(destDir) {
|
|
|
11853
12011
|
})
|
|
11854
12012
|
);
|
|
11855
12013
|
}
|
|
12014
|
+
function validateFlagValue(flag, value, allowed) {
|
|
12015
|
+
if (allowed.includes(value)) {
|
|
12016
|
+
return { valid: true };
|
|
12017
|
+
}
|
|
12018
|
+
return {
|
|
12019
|
+
valid: false,
|
|
12020
|
+
error: `Invalid value "${value}" for ${flag}. Valid choices: ${allowed.join(", ")}.`
|
|
12021
|
+
};
|
|
12022
|
+
}
|
|
12023
|
+
function validateDeploymentCombo(deployment, nestDiOnly2) {
|
|
12024
|
+
if (deployment === "spa" && nestDiOnly2) {
|
|
12025
|
+
return {
|
|
12026
|
+
valid: false,
|
|
12027
|
+
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."
|
|
12028
|
+
};
|
|
12029
|
+
}
|
|
12030
|
+
return { valid: true };
|
|
12031
|
+
}
|
|
11856
12032
|
function validateProjectName(projectName) {
|
|
11857
12033
|
if (!projectName) {
|
|
11858
12034
|
return { valid: false, error: "Project name is required" };
|
|
@@ -11891,6 +12067,7 @@ async function scaffold(modules, options) {
|
|
|
11891
12067
|
projectName: options.name,
|
|
11892
12068
|
testing: options.testing,
|
|
11893
12069
|
database: options.database,
|
|
12070
|
+
deployment: options.deployment,
|
|
11894
12071
|
authSecret: randomBytes(32).toString("base64url")
|
|
11895
12072
|
};
|
|
11896
12073
|
await renderTemplatesToDisk(modules, options.name, templateData);
|
|
@@ -11927,6 +12104,10 @@ async function initGit(cwd) {
|
|
|
11927
12104
|
}
|
|
11928
12105
|
|
|
11929
12106
|
// src/index.ts
|
|
12107
|
+
var TESTING_CHOICES = ["jest", "vitest"];
|
|
12108
|
+
var DATABASE_CHOICES = ["sqlite", "postgres"];
|
|
12109
|
+
var LINTER_CHOICES = ["eslint", "oxc"];
|
|
12110
|
+
var DEPLOYMENT_CHOICES = ["none", "standalone", "custom-server", "spa"];
|
|
11930
12111
|
var TaskBuilder = class {
|
|
11931
12112
|
tasks = [];
|
|
11932
12113
|
add(task) {
|
|
@@ -11983,13 +12164,15 @@ async function doInit(options) {
|
|
|
11983
12164
|
message: "Include the todo example?",
|
|
11984
12165
|
initialValue: true
|
|
11985
12166
|
}),
|
|
11986
|
-
deployment: () => p.select({
|
|
12167
|
+
deployment: ({ results }) => p.select({
|
|
11987
12168
|
message: "Deployment extras?",
|
|
11988
12169
|
options: [
|
|
11989
12170
|
{ value: "none", label: "None", hint: "skip" },
|
|
11990
12171
|
{ value: "standalone", label: "Standalone + Dockerfile", hint: "Dockerfiles + docker-compose.yml" },
|
|
11991
12172
|
{ value: "custom-server", label: "Custom Server", hint: "single process, single port" },
|
|
11992
|
-
|
|
12173
|
+
// SPA statically exports Next.js, which can't hold the route
|
|
12174
|
+
// handlers DI-only mode runs on
|
|
12175
|
+
...results.nestDiOnly ? [] : [{ value: "spa", label: "SPA Mode", hint: "static export served by NestJS" }]
|
|
11993
12176
|
],
|
|
11994
12177
|
initialValue: "none"
|
|
11995
12178
|
})
|
|
@@ -12009,6 +12192,10 @@ async function doInit(options) {
|
|
|
12009
12192
|
const deployment = options.nonInteractive ? options.deployment : group2.deployment ?? "none";
|
|
12010
12193
|
const nestDiOnly2 = options.nonInteractive ? options.nestDiOnly : group2.nestDiOnly ?? false;
|
|
12011
12194
|
const todoExample = options.nonInteractive ? !options.bare : group2.todoExample ?? true;
|
|
12195
|
+
const deploymentCombo = validateDeploymentCombo(deployment, nestDiOnly2);
|
|
12196
|
+
if (!deploymentCombo.valid) {
|
|
12197
|
+
throw new Error(deploymentCombo.error);
|
|
12198
|
+
}
|
|
12012
12199
|
const deploymentModule = deployment === "standalone" ? templates.deploymentStandalone : deployment === "custom-server" ? templates.deploymentCustomServer : deployment === "spa" ? templates.deploymentSpa : null;
|
|
12013
12200
|
const webModule = deployment === "spa" ? {
|
|
12014
12201
|
...templates.web,
|
|
@@ -12028,6 +12215,9 @@ async function doInit(options) {
|
|
|
12028
12215
|
testing === "vitest" ? templates.testingVitest : templates.testingJest,
|
|
12029
12216
|
...deploymentModule ? [deploymentModule] : [],
|
|
12030
12217
|
...nestDiOnly2 ? [templates.nestDiOnly] : [templates.apiControllers],
|
|
12218
|
+
// nest-di-only overwrites the standalone next.config.js and leaves the
|
|
12219
|
+
// Dockerfile pointing at an api entrypoint DI-only never emits
|
|
12220
|
+
...nestDiOnly2 && deployment === "standalone" ? [templates.deploymentStandaloneDi] : [],
|
|
12031
12221
|
...todoExample ? [
|
|
12032
12222
|
templates.todoExampleApi,
|
|
12033
12223
|
...nestDiOnly2 ? [templates.todoExampleDi] : [templates.todoExampleControllers],
|
|
@@ -12039,7 +12229,7 @@ async function doInit(options) {
|
|
|
12039
12229
|
taskBuilder.add({
|
|
12040
12230
|
title: "Scaffolding project",
|
|
12041
12231
|
task: async () => {
|
|
12042
|
-
await scaffold(allModules, { name, testing, database });
|
|
12232
|
+
await scaffold(allModules, { name, testing, database, deployment });
|
|
12043
12233
|
return "Scaffolded.";
|
|
12044
12234
|
}
|
|
12045
12235
|
});
|
|
@@ -12102,16 +12292,27 @@ program.name("create-newt-app").version(package_default.version).description("Cr
|
|
|
12102
12292
|
const nonInteractive = configFlags.some(
|
|
12103
12293
|
(flag) => command.getOptionValueSource(flag) === "cli"
|
|
12104
12294
|
);
|
|
12295
|
+
const choices = [
|
|
12296
|
+
{ flag: "--testing", value: options.testing, allowed: TESTING_CHOICES },
|
|
12297
|
+
{ flag: "--database", value: options.database, allowed: DATABASE_CHOICES },
|
|
12298
|
+
{ flag: "--linter", value: options.linter, allowed: LINTER_CHOICES },
|
|
12299
|
+
{ flag: "--deployment", value: options.deployment, allowed: DEPLOYMENT_CHOICES }
|
|
12300
|
+
];
|
|
12301
|
+
const invalid = choices.map(({ flag, value, allowed }) => validateFlagValue(flag, value, allowed)).find((result) => !result.valid);
|
|
12302
|
+
if (invalid) {
|
|
12303
|
+
console.error(`Error: ${invalid.error}`);
|
|
12304
|
+
process.exit(1);
|
|
12305
|
+
}
|
|
12105
12306
|
await doInit({
|
|
12106
12307
|
name,
|
|
12107
12308
|
install: options.install,
|
|
12108
12309
|
git: options.git,
|
|
12109
12310
|
nonInteractive,
|
|
12110
12311
|
shadcn: options.shadcn,
|
|
12111
|
-
testing: options.testing
|
|
12112
|
-
database: options.database
|
|
12113
|
-
linter: options.linter
|
|
12114
|
-
deployment:
|
|
12312
|
+
testing: options.testing,
|
|
12313
|
+
database: options.database,
|
|
12314
|
+
linter: options.linter,
|
|
12315
|
+
deployment: options.deployment,
|
|
12115
12316
|
nestDiOnly: options.nestDiOnly,
|
|
12116
12317
|
bare: options.bare
|
|
12117
12318
|
});
|