create-init-mtv-app 1.0.3 → 1.0.5

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.
Files changed (2) hide show
  1. package/dist/index.mjs +405 -152
  2. package/package.json +2 -2
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { execa } from "execa";
3
2
  import fs from "fs-extra";
4
3
  import path from "path";
4
+ import { execa } from "execa";
5
5
  import inquirer from "inquirer";
6
6
 
7
7
  //#region src/enum/db_provider.ts
@@ -41,134 +41,6 @@ let UI_LIB = /* @__PURE__ */ function(UI_LIB$1) {
41
41
  return UI_LIB$1;
42
42
  }({});
43
43
 
44
- //#endregion
45
- //#region src/installers/expressjs/expressjs.ts
46
- async function createExpressApp(projectName) {
47
- await fs.ensureDir(projectName);
48
- await execa("npm", ["init", "-y"], {
49
- cwd: projectName,
50
- stdio: "inherit"
51
- });
52
- const dtosDir = path.join(projectName, "src", "dtos");
53
- const handlersDir = path.join(projectName, "src", "handlers");
54
- const repositoriesDir = path.join(projectName, "src", "repositories");
55
- const servicesDir = path.join(projectName, "src", "services");
56
- const routesDir = path.join(projectName, "src", "routes");
57
- const middlewareDir = path.join(projectName, "src", "middleware");
58
- await Promise.all([
59
- fs.ensureDir(dtosDir),
60
- fs.ensureDir(handlersDir),
61
- fs.ensureDir(repositoriesDir),
62
- fs.ensureDir(servicesDir),
63
- fs.ensureDir(routesDir),
64
- fs.ensureDir(middlewareDir)
65
- ]);
66
- const idParamDtoPath = path.join(dtosDir, "idParam.dto.ts");
67
- const paginationDtoPath = path.join(dtosDir, "pagination.dto.ts");
68
- const responseDtoPath = path.join(dtosDir, "response.dto.ts");
69
- await Promise.all([
70
- fs.ensureFile(idParamDtoPath),
71
- fs.ensureFile(paginationDtoPath),
72
- fs.ensureFile(responseDtoPath)
73
- ]);
74
- await Promise.all([
75
- fs.writeFile(idParamDtoPath, idParamDtoTemplate),
76
- fs.writeFile(paginationDtoPath, paginationDtoTemplate),
77
- fs.writeFile(responseDtoPath, responseDtoTemplate)
78
- ]);
79
- const appFilePath = path.join(projectName, "src", "app.ts");
80
- const indexFilePath = path.join(projectName, "index.ts");
81
- await Promise.all([fs.ensureFile(appFilePath), fs.ensureFile(indexFilePath)]);
82
- await Promise.all([fs.writeFile(appFilePath, appTemplate), fs.writeFile(indexFilePath, indexTemplate)]);
83
- }
84
- const appTemplate = `import express from "express";
85
- import helmet from "helmet";
86
- import cors from "cors";
87
- import cookieParser from "cookie-parser";
88
- import "dotenv/config";
89
- import swaggerUi from "swagger-ui-express";
90
- import swaggerDocument from "./swagger.json";
91
- import morgan from "morgan";
92
-
93
- const app = express();
94
- app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerDocument)); // mabe AI will help to generate the json file
95
- app.use(helmet());
96
- app.use(cors());
97
- app.use(express.json());
98
- app.use(express.urlencoded({ extended: true }));
99
- app.use(cookieParser());
100
- app.use(morgan("dev"));
101
-
102
- app.get("/health", (_req, res) => {
103
- res.json({ status: "ok" });
104
- });
105
-
106
- export default app;`;
107
- const indexTemplate = `import app from "./src/app";
108
-
109
- const port = process.env.PORT || 8080;
110
- app.listen(port, () => {
111
- console.log(\`Server is running on port \${ port }\`);
112
- });`;
113
- const idParamDtoTemplate = `export type IdParam = {
114
- id: string;
115
- };`;
116
- const paginationDtoTemplate = `export type Pagination = {
117
- page: number;
118
- limit: number;
119
- };`;
120
- const responseDtoTemplate = `export type Response<T> = {
121
- data?: T;
122
- message: string;
123
- statusCode: number;
124
- success: boolean;
125
- };`;
126
-
127
- //#endregion
128
- //#region src/installers/expressjs/dependencies.ts
129
- async function installDependencies$1(projectName, dependencies) {
130
- await execa("npm", ["install", ...dependencies], {
131
- cwd: projectName,
132
- stdio: "inherit"
133
- });
134
- }
135
-
136
- //#endregion
137
- //#region src/installers/expressjs/devDependencies.ts
138
- async function installDevDependencies$1(projectName, devDependencies) {
139
- await execa("npm", [
140
- "install",
141
- "-D",
142
- ...devDependencies
143
- ], {
144
- cwd: projectName,
145
- stdio: "inherit"
146
- });
147
- }
148
-
149
- //#endregion
150
- //#region src/installers/nestjs.ts
151
- async function createNestApp(projectName) {
152
- await execa("npx", [
153
- "@nestjs/cli",
154
- "new",
155
- projectName
156
- ], { stdio: "inherit" });
157
- }
158
-
159
- //#endregion
160
- //#region src/installers/react.ts
161
- async function createReactApp(projectName) {
162
- await execa("npm", [
163
- "create",
164
- "vite@latest",
165
- projectName,
166
- "--",
167
- "--template",
168
- "react"
169
- ], { stdio: "inherit" });
170
- }
171
-
172
44
  //#endregion
173
45
  //#region src/configs/husky_lint-staged.ts
174
46
  async function setupHuskyLintStaged(projectName) {
@@ -323,7 +195,7 @@ async function setupDrizzle(projectName) {
323
195
  fs.ensureDir(migrationsDir),
324
196
  fs.ensureFile(drizzleConfigPath)
325
197
  ]);
326
- await fs.writeFile(drizzleConfigPath, drizzleConfigTemplate$1);
198
+ await fs.writeFile(drizzleConfigPath, drizzleConfigTemplate$2);
327
199
  const packageJsonPath = path.join(projectName, "package.json");
328
200
  const packageJson = await fs.readJson(packageJsonPath);
329
201
  packageJson.scripts["db:generate"] = "npx drizzle-kit generate --config=./src/backend/db/drizzle.config.ts";
@@ -333,7 +205,7 @@ async function setupDrizzle(projectName) {
333
205
  packageJson.scripts["db:check"] = "npx drizzle-kit check --config=./src/backend/db/drizzle.config.ts";
334
206
  await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
335
207
  }
336
- const drizzleConfigTemplate$1 = `import "server-only";
208
+ const drizzleConfigTemplate$2 = `import "server-only";
337
209
  import { defineConfig } from "drizzle-kit";
338
210
  import { serverEnv } from "../env.server";
339
211
 
@@ -504,7 +376,7 @@ export const env = parsed.data;
504
376
 
505
377
  //#endregion
506
378
  //#region src/configs/expressjs/supabase_client.ts
507
- async function configSupabaseClient(projectName) {
379
+ async function configSupabaseClient$1(projectName) {
508
380
  const supabaseDir = path.join(projectName, "src", "db", "supabase");
509
381
  await fs.ensureDir(supabaseDir);
510
382
  const supabaseClientPath = path.join(supabaseDir, "client.ts");
@@ -536,7 +408,7 @@ export default supabaseAdmin;
536
408
 
537
409
  //#endregion
538
410
  //#region src/configs/expressjs/supabase_local.ts
539
- async function configSupabaseLocal(projectDir) {
411
+ async function configSupabaseLocal$1(projectDir) {
540
412
  execa("npx", ["supabase", "init"], {
541
413
  cwd: projectDir,
542
414
  stdio: "inherit"
@@ -551,7 +423,7 @@ async function configSupabaseLocal(projectDir) {
551
423
 
552
424
  //#endregion
553
425
  //#region src/configs/expressjs/drizzle.ts
554
- async function configDrizzle(projectName) {
426
+ async function configDrizzle$1(projectName) {
555
427
  const schemasDir = path.join(projectName, "src", "db", "schemas");
556
428
  const migrationsDir = path.join(projectName, "src", "db", "migrations");
557
429
  const drizzleConfigPath = path.join(projectName, "drizzle.config.ts");
@@ -560,7 +432,7 @@ async function configDrizzle(projectName) {
560
432
  fs.ensureDir(migrationsDir),
561
433
  fs.ensureFile(drizzleConfigPath)
562
434
  ]);
563
- await fs.writeFile(drizzleConfigPath, drizzleConfigTemplate);
435
+ await fs.writeFile(drizzleConfigPath, drizzleConfigTemplate$1);
564
436
  const packageJsonPath = path.join(projectName, "package.json");
565
437
  const packageJson = await fs.readJson(packageJsonPath);
566
438
  packageJson.scripts["db:generate"] = "npx drizzle-kit generate --config=./drizzle.config.ts";
@@ -570,7 +442,7 @@ async function configDrizzle(projectName) {
570
442
  packageJson.scripts["db:check"] = "npx drizzle-kit check --config=./drizzle.config.ts";
571
443
  await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
572
444
  }
573
- const drizzleConfigTemplate = `import { defineConfig } from "drizzle-kit";
445
+ const drizzleConfigTemplate$1 = `import { defineConfig } from "drizzle-kit";
574
446
  import { env } from "./src/env";
575
447
 
576
448
  export default defineConfig({
@@ -587,7 +459,7 @@ export default defineConfig({
587
459
 
588
460
  //#endregion
589
461
  //#region src/configs/expressjs/biome.ts
590
- async function configBiome(projectName) {
462
+ async function configBiome$1(projectName) {
591
463
  execa("npx", ["biome", "init"], {
592
464
  cwd: projectName,
593
465
  stdio: "inherit"
@@ -673,6 +545,111 @@ async function configNodemon(projectName) {
673
545
  await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
674
546
  }
675
547
 
548
+ //#endregion
549
+ //#region src/installers/expressjs/expressjs.ts
550
+ async function createExpressApp(projectName) {
551
+ await fs.ensureDir(projectName);
552
+ await execa("npm", ["init", "-y"], {
553
+ cwd: projectName,
554
+ stdio: "inherit"
555
+ });
556
+ const dtosDir = path.join(projectName, "src", "dtos");
557
+ const handlersDir = path.join(projectName, "src", "handlers");
558
+ const repositoriesDir = path.join(projectName, "src", "repositories");
559
+ const servicesDir = path.join(projectName, "src", "services");
560
+ const routesDir = path.join(projectName, "src", "routes");
561
+ const middlewareDir = path.join(projectName, "src", "middleware");
562
+ await Promise.all([
563
+ fs.ensureDir(dtosDir),
564
+ fs.ensureDir(handlersDir),
565
+ fs.ensureDir(repositoriesDir),
566
+ fs.ensureDir(servicesDir),
567
+ fs.ensureDir(routesDir),
568
+ fs.ensureDir(middlewareDir)
569
+ ]);
570
+ const idParamDtoPath = path.join(dtosDir, "idParam.dto.ts");
571
+ const paginationDtoPath = path.join(dtosDir, "pagination.dto.ts");
572
+ const responseDtoPath = path.join(dtosDir, "response.dto.ts");
573
+ await Promise.all([
574
+ fs.ensureFile(idParamDtoPath),
575
+ fs.ensureFile(paginationDtoPath),
576
+ fs.ensureFile(responseDtoPath)
577
+ ]);
578
+ await Promise.all([
579
+ fs.writeFile(idParamDtoPath, idParamDtoTemplate),
580
+ fs.writeFile(paginationDtoPath, paginationDtoTemplate),
581
+ fs.writeFile(responseDtoPath, responseDtoTemplate)
582
+ ]);
583
+ const appFilePath = path.join(projectName, "src", "app.ts");
584
+ const indexFilePath = path.join(projectName, "index.ts");
585
+ await Promise.all([fs.ensureFile(appFilePath), fs.ensureFile(indexFilePath)]);
586
+ await Promise.all([fs.writeFile(appFilePath, appTemplate), fs.writeFile(indexFilePath, indexTemplate)]);
587
+ }
588
+ const appTemplate = `import express from "express";
589
+ import helmet from "helmet";
590
+ import cors from "cors";
591
+ import cookieParser from "cookie-parser";
592
+ import "dotenv/config";
593
+ import swaggerUi from "swagger-ui-express";
594
+ import swaggerDocument from "./swagger.json";
595
+ import morgan from "morgan";
596
+
597
+ const app = express();
598
+ app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerDocument)); // mabe AI will help to generate the json file
599
+ app.use(helmet());
600
+ app.use(cors());
601
+ app.use(express.json());
602
+ app.use(express.urlencoded({ extended: true }));
603
+ app.use(cookieParser());
604
+ app.use(morgan("dev"));
605
+
606
+ app.get("/health", (_req, res) => {
607
+ res.json({ status: "ok" });
608
+ });
609
+
610
+ export default app;`;
611
+ const indexTemplate = `import app from "./src/app";
612
+
613
+ const port = process.env.PORT || 8080;
614
+ app.listen(port, () => {
615
+ console.log(\`Server is running on port \${ port }\`);
616
+ });`;
617
+ const idParamDtoTemplate = `export type IdParam = {
618
+ id: string;
619
+ };`;
620
+ const paginationDtoTemplate = `export type Pagination = {
621
+ page: number;
622
+ limit: number;
623
+ };`;
624
+ const responseDtoTemplate = `export type Response<T> = {
625
+ data?: T;
626
+ message: string;
627
+ statusCode: number;
628
+ success: boolean;
629
+ };`;
630
+
631
+ //#endregion
632
+ //#region src/installers/expressjs/dependencies.ts
633
+ async function installDependencies$2(projectName, dependencies) {
634
+ await execa("npm", ["install", ...dependencies], {
635
+ cwd: projectName,
636
+ stdio: "inherit"
637
+ });
638
+ }
639
+
640
+ //#endregion
641
+ //#region src/installers/expressjs/devDependencies.ts
642
+ async function installDevDependencies$2(projectName, devDependencies) {
643
+ await execa("npm", [
644
+ "install",
645
+ "-D",
646
+ ...devDependencies
647
+ ], {
648
+ cwd: projectName,
649
+ stdio: "inherit"
650
+ });
651
+ }
652
+
676
653
  //#endregion
677
654
  //#region src/setup/expressjs.ts
678
655
  async function setupExpressjs(projectName, dbProvider, dbTool, isNeverThrow) {
@@ -712,18 +689,275 @@ async function setupExpressjs(projectName, dbProvider, dbTool, isNeverThrow) {
712
689
  devDependencies.push("drizzle-kit");
713
690
  }
714
691
  if (isNeverThrow) dependencies.push("neverthrow");
692
+ await installDependencies$2(projectName, dependencies);
693
+ await installDevDependencies$2(projectName, devDependencies);
694
+ await setupHuskyLintStaged(projectName);
695
+ await configEnv(projectName, dbProvider === DB_PROVIDERS.SUPABASE);
696
+ if (dbProvider === DB_PROVIDERS.DOCKER) await setupDockerPostgres(projectName);
697
+ if (dbProvider === DB_PROVIDERS.SUPABASE) await configSupabaseClient$1(projectName);
698
+ if (dbTool === DB_TOOLS.SUPABASE_JS_SDK) await configSupabaseLocal$1(projectName);
699
+ if (dbTool === DB_TOOLS.DRIZZLE_ORM) await configDrizzle$1(projectName);
700
+ await configBiome$1(projectName);
701
+ await configJest(projectName);
702
+ await configTypescript(projectName);
703
+ await configNodemon(projectName);
704
+ }
705
+
706
+ //#endregion
707
+ //#region src/configs/nestjs/biome.ts
708
+ async function configBiome(projectName) {
709
+ const eslintConfigPath = path.join(projectName, "eslint.config.mjs");
710
+ const prettierConfigPath = path.join(projectName, ".prettierrc");
711
+ await Promise.all([
712
+ execa("npx", ["biome", "init"], {
713
+ cwd: projectName,
714
+ stdio: "inherit"
715
+ }),
716
+ execa("npm", [
717
+ "remove",
718
+ "@eslint/eslintrc",
719
+ "@eslint/js",
720
+ "eslint",
721
+ "eslint-config-prettier",
722
+ "eslint-plugin-prettier",
723
+ "typescript-eslint",
724
+ "prettier"
725
+ ], {
726
+ cwd: projectName,
727
+ stdio: "inherit"
728
+ }),
729
+ fs.remove(eslintConfigPath),
730
+ fs.remove(prettierConfigPath)
731
+ ]);
732
+ }
733
+
734
+ //#endregion
735
+ //#region src/configs/nestjs/drizzle.ts
736
+ async function configDrizzle(projectName) {
737
+ const schemasDir = path.join(projectName, "src", "drizzle", "schemas");
738
+ const migrationsDir = path.join(projectName, "src", "drizzle", "migrations");
739
+ const drizzleConfigPath = path.join(projectName, "drizzle.config.ts");
740
+ const drizzleModulePath = path.join(projectName, "src", "drizzle", "drizzle.module.ts");
741
+ await Promise.all([
742
+ fs.ensureDir(schemasDir),
743
+ fs.ensureDir(migrationsDir),
744
+ fs.ensureFile(drizzleConfigPath),
745
+ fs.ensureFile(drizzleModulePath)
746
+ ]);
747
+ await fs.writeFile(drizzleConfigPath, drizzleConfigTemplate);
748
+ await fs.writeFile(drizzleModulePath, drizzleModuleTemplate);
749
+ const packageJsonPath = path.join(projectName, "package.json");
750
+ const packageJson = await fs.readJson(packageJsonPath);
751
+ packageJson.scripts["db:generate"] = "npx drizzle-kit generate --config=./drizzle.config.ts";
752
+ packageJson.scripts["db:migrate"] = "npx drizzle-kit push --config=./drizzle.config.ts";
753
+ packageJson.scripts["db:studio"] = "npx drizzle-kit studio --verbose --config=./drizzle.config.ts";
754
+ packageJson.scripts["db:pull"] = "npx drizzle-kit pull --config=./drizzle.config.ts";
755
+ packageJson.scripts["db:check"] = "npx drizzle-kit check --config=./drizzle.config.ts";
756
+ await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
757
+ }
758
+ const drizzleConfigTemplate = `import { defineConfig } from "drizzle-kit";
759
+ import { env } from "./src/env";
760
+
761
+ export default defineConfig({
762
+ dialect: "postgresql",
763
+ schema: "./src/db/schemas/*",
764
+ out: "./src/db/migrations",
765
+ dbCredentials: {
766
+ url: env.DATABASE_URL,
767
+ },
768
+ verbose: true,
769
+ strict: true,
770
+ });
771
+ `.trimStart();
772
+ const drizzleModuleTemplate = `import { Module } from '@nestjs/common';
773
+ import { ConfigService } from '@nestjs/config';
774
+ import postgres from 'postgres';
775
+ import { drizzle } from "drizzle-orm/postgres-js";
776
+
777
+ const DRIZZLE=Symbol("drizzle")
778
+ @Module({
779
+ providers:[
780
+ {
781
+ provide: DRIZZLE,
782
+ inject: [ConfigService],
783
+ useFactory: (configService: ConfigService) => {
784
+ const databaseUrl = configService.get<string>("DATABASE_URL");
785
+ if(!databaseUrl) {
786
+ throw new Error("DATABASE_URL is not set in the environment variables");
787
+ }
788
+ const client = postgres(databaseUrl);
789
+ return drizzle({client});
790
+ },
791
+ }
792
+ ],
793
+ exports: [DRIZZLE],
794
+ })
795
+ export class DrizzleModule {
796
+ }
797
+ `.trimStart();
798
+
799
+ //#endregion
800
+ //#region src/configs/nestjs/supabase_client.ts
801
+ async function configSupabaseClient(projectName) {
802
+ const supabaseDir = path.join(projectName, "src", "supabase");
803
+ await fs.ensureDir(supabaseDir);
804
+ const supabaseModulePath = path.join(supabaseDir, "supabase.module.ts");
805
+ await fs.ensureFile(supabaseModulePath);
806
+ await fs.writeFile(supabaseModulePath, supabaseModuleTemplate);
807
+ }
808
+ const supabaseModuleTemplate = `import { Module, Scope } from '@nestjs/common';
809
+ import { ConfigService } from '@nestjs/config';
810
+ import { REQUEST } from '@nestjs/core';
811
+ import { createClient } from '@supabase/supabase-js';
812
+ import { Request } from 'express';
813
+
814
+ export const SUPABASE_CLIENT=Symbol("supabase-client")
815
+ export const SUPABASE_ADMIN=Symbol("supabase-admin")
816
+ @Module({
817
+ providers: [
818
+ {
819
+ provide: SUPABASE_CLIENT,
820
+ inject: [ConfigService,REQUEST],
821
+ scope: Scope.REQUEST,
822
+ useFactory: (configService: ConfigService, request: Request) => {
823
+ const supabaseUrl = configService.get<string>("SUPABASE_URL");
824
+ const supabaseAnonKey = configService.get<string>("SUPABASE_ANON_KEY");
825
+ if(!supabaseUrl || !supabaseAnonKey) {
826
+ throw new Error("SUPABASE_URL or SUPABASE_ANON_KEY is not set in the environment variables");
827
+ }
828
+ return createClient(supabaseUrl, supabaseAnonKey,{global:{headers:{
829
+ Authorization: request.headers.authorization as string,
830
+ }}});
831
+ },
832
+ },
833
+ {
834
+ provide: SUPABASE_ADMIN,
835
+ inject: [ConfigService],
836
+ useFactory: (configService: ConfigService) => {
837
+ const supabaseUrl = configService.get<string>("SUPABASE_URL");
838
+ const supabaseServiceRoleKey = configService.get<string>("SUPABASE_SERVICE_ROLE_KEY");
839
+ if(!supabaseUrl || !supabaseServiceRoleKey) {
840
+ throw new Error("SUPABASE_URL or SUPABASE_SERVICE_ROLE_KEY is not set in the environment variables");
841
+ }
842
+ return createClient(supabaseUrl, supabaseServiceRoleKey);
843
+ },
844
+ },
845
+ ],
846
+ exports:[SUPABASE_CLIENT, SUPABASE_ADMIN]
847
+ })
848
+ export class SupabaseModule {}
849
+ `;
850
+
851
+ //#endregion
852
+ //#region src/configs/nestjs/supabase_local.ts
853
+ async function configSupabaseLocal(projectDir) {
854
+ execa("npx", ["supabase", "init"], {
855
+ cwd: projectDir,
856
+ stdio: "inherit"
857
+ });
858
+ const migrationsDir = path.join(projectDir, "supabase", "migrations");
859
+ const schemaDir = path.join(projectDir, "supabase", "schemas");
860
+ const dbDir = path.join(schemaDir, "db");
861
+ const storageDir = path.join(schemaDir, "storage");
862
+ await Promise.all([fs.ensureDir(migrationsDir), fs.ensureDir(schemaDir)]);
863
+ await Promise.all([fs.ensureDir(dbDir), fs.ensureDir(storageDir)]);
864
+ }
865
+
866
+ //#endregion
867
+ //#region src/installers/nestjs/nestjs.ts
868
+ async function createNestApp(projectName) {
869
+ await execa("npx", [
870
+ "@nestjs/cli",
871
+ "new",
872
+ projectName,
873
+ "-p",
874
+ "npm"
875
+ ], { stdio: "inherit" });
876
+ const mainPath = path.join(projectName, "src", "main.ts");
877
+ await fs.writeFile(mainPath, mainTemplate);
878
+ }
879
+ const mainTemplate = `import { NestFactory } from "@nestjs/core";
880
+ import { AppModule } from "./app.module";
881
+ import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
882
+ import helmet from 'helmet';
883
+ import cookieParser from 'cookie-parser';
884
+
885
+ async function bootstrap() {
886
+ const app = await NestFactory.create(AppModule);
887
+
888
+ const config = new DocumentBuilder()
889
+ .setTitle('My Project API')
890
+ .setDescription('The my project API description')
891
+ .setVersion('1.0')
892
+ .addTag('my project')
893
+ .build();
894
+
895
+ const documentFactory = () => SwaggerModule.createDocument(app, config);
896
+ SwaggerModule.setup('api-docs', app, documentFactory);
897
+
898
+ app.enableCors();
899
+ app.use(helmet());
900
+ app.use(cookieParser());
901
+
902
+ await app.listen(process.env.PORT ?? 8080);
903
+ }
904
+ bootstrap();
905
+ `.trimStart();
906
+
907
+ //#endregion
908
+ //#region src/installers/nestjs/dependencies.ts
909
+ async function installDependencies$1(projectName, dependencies) {
910
+ await execa("npm", ["install", ...dependencies], {
911
+ cwd: projectName,
912
+ stdio: "inherit"
913
+ });
914
+ }
915
+
916
+ //#endregion
917
+ //#region src/installers/nestjs/devDependencies.ts
918
+ async function installDevDependencies$1(projectName, devDependencies) {
919
+ await execa("npm", [
920
+ "install",
921
+ "-D",
922
+ ...devDependencies
923
+ ], {
924
+ cwd: projectName,
925
+ stdio: "inherit"
926
+ });
927
+ }
928
+
929
+ //#endregion
930
+ //#region src/setup/nestjs.ts
931
+ async function setupNestjs(projectName, dbProvider, dbTool, isNeverThrow) {
932
+ await createNestApp(projectName);
933
+ const dependencies = [
934
+ "@nestjs/config",
935
+ "@nestjs/swagger",
936
+ "class-transformer",
937
+ "class-validator",
938
+ "cookie-parser",
939
+ "helmet"
940
+ ];
941
+ const devDependencies = [
942
+ "@biomejs/biome",
943
+ "@types/cookie-parser",
944
+ "husky",
945
+ "lint-staged"
946
+ ];
947
+ if (dbProvider === DB_PROVIDERS.SUPABASE) dependencies.push("@supabase/supabase-js");
948
+ if (dbTool === DB_TOOLS.DRIZZLE_ORM) {
949
+ dependencies.push("drizzle-orm", "postgres");
950
+ devDependencies.push("drizzle-kit");
951
+ }
952
+ if (isNeverThrow) dependencies.push("neverthrow");
715
953
  await installDependencies$1(projectName, dependencies);
716
954
  await installDevDependencies$1(projectName, devDependencies);
717
955
  await setupHuskyLintStaged(projectName);
718
- await configEnv(projectName, dbProvider === DB_PROVIDERS.SUPABASE);
719
956
  if (dbProvider === DB_PROVIDERS.DOCKER) await setupDockerPostgres(projectName);
720
957
  if (dbProvider === DB_PROVIDERS.SUPABASE) await configSupabaseClient(projectName);
721
958
  if (dbTool === DB_TOOLS.SUPABASE_JS_SDK) await configSupabaseLocal(projectName);
722
959
  if (dbTool === DB_TOOLS.DRIZZLE_ORM) await configDrizzle(projectName);
723
960
  await configBiome(projectName);
724
- await configJest(projectName);
725
- await configTypescript(projectName);
726
- await configNodemon(projectName);
727
961
  }
728
962
 
729
963
  //#endregion
@@ -801,6 +1035,28 @@ async function setupNextjs(projectName, dbProvider, dbTool, uiLibrary, isNeverTh
801
1035
  await setupJest(projectName);
802
1036
  }
803
1037
 
1038
+ //#endregion
1039
+ //#region src/installers/reactTSRouter/reactTSRouter.ts
1040
+ async function createReactTSRouterApp(projectName) {
1041
+ await execa("npx", [
1042
+ "create-tsrouter-app@latest",
1043
+ projectName,
1044
+ "--template",
1045
+ "file-router",
1046
+ "--tailwind",
1047
+ "--toolchain",
1048
+ "biome",
1049
+ "--add-ons",
1050
+ "shadcn,tanstack-query,compiler,form"
1051
+ ], { stdio: "inherit" });
1052
+ }
1053
+
1054
+ //#endregion
1055
+ //#region src/setup/reactTSRouter.ts
1056
+ async function setupReactTSRouter(projectName) {
1057
+ await createReactTSRouterApp(projectName);
1058
+ }
1059
+
804
1060
  //#endregion
805
1061
  //#region src/create.ts
806
1062
  async function createProject(answers) {
@@ -813,16 +1069,13 @@ async function createProject(answers) {
813
1069
  await Promise.all([setupNextjs(projectName + "-fe", DB_PROVIDERS.NONE, DB_TOOLS.NONE, uiLibrary, isNeverThrow), setupExpressjs(projectName + "-be", dbProvider, dbTool, isNeverThrow)]);
814
1070
  break;
815
1071
  case FRAMEWORKS.NEXT_NEST:
816
- await setupNextjs(projectName + "-fe", DB_PROVIDERS.NONE, DB_TOOLS.NONE, uiLibrary, isNeverThrow);
817
- createNestApp(projectName + "-be");
1072
+ await Promise.all([setupNextjs(projectName + "-fe", DB_PROVIDERS.NONE, DB_TOOLS.NONE, uiLibrary, isNeverThrow), setupNestjs(projectName + "-be", dbProvider, dbTool, isNeverThrow)]);
818
1073
  break;
819
1074
  case FRAMEWORKS.REACT_EXPRESS:
820
- createReactApp(projectName + "-fe");
821
- createExpressApp(projectName + "-be");
1075
+ await Promise.all([setupReactTSRouter(projectName + "-fe"), setupExpressjs(projectName + "-be", dbProvider, dbTool, isNeverThrow)]);
822
1076
  break;
823
1077
  case FRAMEWORKS.REACT_NEST:
824
- createReactApp(projectName + "-fe");
825
- createNestApp(projectName + "-be");
1078
+ await Promise.all([setupReactTSRouter(projectName + "-fe"), setupNestjs(projectName + "-be", dbProvider, dbTool, isNeverThrow)]);
826
1079
  break;
827
1080
  }
828
1081
  }
@@ -860,16 +1113,16 @@ async function ask() {
860
1113
  name: "Next.js + Express",
861
1114
  value: FRAMEWORKS.NEXT_EXPRESS
862
1115
  },
863
- {
864
- name: "React.js + Express",
865
- value: FRAMEWORKS.REACT_EXPRESS
866
- },
867
1116
  {
868
1117
  name: "Next.js + NestJS",
869
1118
  value: FRAMEWORKS.NEXT_NEST
870
1119
  },
871
1120
  {
872
- name: "React.js + NestJS",
1121
+ name: "React.js (tanstack router) + Express",
1122
+ value: FRAMEWORKS.REACT_EXPRESS
1123
+ },
1124
+ {
1125
+ name: "React.js (tanstack router) + NestJS",
873
1126
  value: FRAMEWORKS.REACT_NEST
874
1127
  }
875
1128
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-init-mtv-app",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "CLI for create init app",
5
5
  "keywords": [
6
6
  "create-init-app"
@@ -30,7 +30,6 @@
30
30
  "prepublishOnly": "npm run build"
31
31
  },
32
32
  "dependencies": {
33
- "@types/fs-extra": "^11.0.4",
34
33
  "chalk": "^5.6.2",
35
34
  "commander": "^14.0.2",
36
35
  "execa": "^9.6.1",
@@ -39,6 +38,7 @@
39
38
  "ora": "^9.0.0"
40
39
  },
41
40
  "devDependencies": {
41
+ "@types/fs-extra": "^11.0.4",
42
42
  "@types/node": "^25.0.3",
43
43
  "tsdown": "^0.18.2",
44
44
  "typescript": "^5.9.3"