better-ts-stack 2.0.0 → 2.0.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.
Files changed (165) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -1
  3. package/dist/args.js +2 -2
  4. package/dist/builder/buildPlanner.js +71 -0
  5. package/dist/builder/configGenerator.js +9 -7
  6. package/dist/builder/dependencyInstaller.js +0 -1
  7. package/dist/builder/fileProcessor.js +47 -44
  8. package/dist/builder/gitInitializer.js +20 -1
  9. package/dist/builder/index.js +19 -38
  10. package/dist/builder/moduleSelector.js +0 -1
  11. package/dist/builder/templateContext.js +0 -22
  12. package/dist/index.js +4 -3
  13. package/dist/modules/registry.js +4 -6
  14. package/dist/output/nextSteps.js +0 -1
  15. package/dist/prompts/index.js +0 -1
  16. package/dist/prompts/stack.js +4 -1
  17. package/dist/types/index.js +7 -3
  18. package/dist/ui/index.js +0 -1
  19. package/dist/ui/messages.js +25 -1
  20. package/dist/ui/prompts.js +0 -1
  21. package/dist/ui/theme.js +0 -1
  22. package/dist/validators/index.js +10 -41
  23. package/package.json +2 -1
  24. package/templates/backend/express/.prettierrc +2 -2
  25. package/templates/backend/express/config.json +1 -5
  26. package/templates/backend/express/eslint.config.mjs +40 -40
  27. package/templates/backend/express/gitignore +36 -36
  28. package/templates/backend/express/src/{index.ts → index.ts.hbs} +28 -29
  29. package/templates/backend/express/src/routes/health.ts +12 -12
  30. package/templates/backend/express/tsconfig.json +25 -25
  31. package/templates/backend/nestjs/.prettierrc +16 -16
  32. package/templates/backend/nestjs/config.json +1 -4
  33. package/templates/backend/nestjs/eslint.config.mjs +40 -40
  34. package/templates/backend/nestjs/gitignore +36 -36
  35. package/templates/backend/nestjs/nest-cli.json +9 -9
  36. package/templates/backend/nestjs/src/app.module.ts.hbs +34 -34
  37. package/templates/backend/nestjs/src/health/health.controller.ts +12 -12
  38. package/templates/backend/nestjs/src/main.ts +23 -23
  39. package/templates/backend/nestjs/tsconfig.json +25 -25
  40. package/templates/frontend/nextjs/components.json +19 -19
  41. package/templates/frontend/nextjs/config.json +1 -2
  42. package/templates/frontend/nextjs/gitignore +42 -42
  43. package/templates/frontend/nextjs/lib/utils.ts +6 -6
  44. package/templates/frontend/nextjs/proxy.ts.hbs +24 -24
  45. package/templates/frontend/nextjs/tsconfig.json +34 -34
  46. package/templates/frontend/tanstack/config.json +1 -4
  47. package/templates/frontend/tanstack/src/routeTree.gen.ts +68 -68
  48. package/templates/frontend/tanstack/src/styles/app.css +85 -85
  49. package/templates/modules/auth/express/config.json +1 -8
  50. package/templates/modules/auth/express/src/controllers/authController.ts.hbs +116 -116
  51. package/templates/modules/auth/express/src/middleware/requireAuth.ts.hbs +26 -26
  52. package/templates/modules/auth/express/src/services/userStore.ts.hbs +117 -117
  53. package/templates/modules/auth/nestjs/config.json +1 -5
  54. package/templates/modules/auth/nestjs/src/auth/auth.controller.ts +46 -46
  55. package/templates/modules/auth/nestjs/src/auth/auth.guard.ts +36 -36
  56. package/templates/modules/auth/nestjs/src/auth/auth.module.ts.hbs +22 -22
  57. package/templates/modules/auth/nestjs/src/auth/auth.schemas.ts +35 -35
  58. package/templates/modules/auth/nestjs/src/auth/auth.service.ts +70 -70
  59. package/templates/modules/auth/nestjs/src/auth/jwt.ts +27 -27
  60. package/templates/modules/auth/nestjs/src/auth/users.service.ts.hbs +144 -144
  61. package/templates/modules/auth/nestjs/src/auth/zod-validation.pipe.ts +16 -16
  62. package/templates/modules/auth/nextjs/app/dashboard/page.tsx +96 -96
  63. package/templates/modules/auth/nextjs/app/sign-in/page.tsx +35 -35
  64. package/templates/modules/auth/nextjs/app/sign-up/page.tsx +35 -35
  65. package/templates/modules/auth/nextjs/components/auth/sign-in-form.tsx +132 -132
  66. package/templates/modules/auth/nextjs/components/auth/sign-out-button.tsx +50 -50
  67. package/templates/modules/auth/nextjs/components/auth/sign-up-form.tsx +152 -152
  68. package/templates/modules/auth/nextjs/config.json +2 -15
  69. package/templates/modules/auth/nextjs/lib/auth-schema.ts +39 -39
  70. package/templates/modules/auth/nextjs/lib/auth.ts.hbs +37 -37
  71. package/templates/modules/auth/tanstack/config.json +2 -16
  72. package/templates/modules/auth/tanstack/src/lib/auth-functions.ts +4 -4
  73. package/templates/modules/auth/tanstack/src/routeTree.gen.ts +140 -140
  74. package/templates/modules/docker/.dockerignore +14 -14
  75. package/templates/modules/docker/Dockerfile.hbs +1 -3
  76. package/templates/modules/docker/config.json +1 -5
  77. package/templates/modules/docker/docker-compose.yml.hbs +9 -9
  78. package/templates/modules/drizzle/express/config.json +1 -2
  79. package/templates/modules/drizzle/express/drizzle.config.ts +13 -13
  80. package/templates/modules/drizzle/express/src/lib/db.ts +13 -13
  81. package/templates/modules/drizzle/express/src/lib/schema.ts +10 -10
  82. package/templates/modules/drizzle/nestjs/config.json +1 -2
  83. package/templates/modules/drizzle/nestjs/drizzle.config.ts +13 -13
  84. package/templates/modules/drizzle/nestjs/src/database/database.module.ts +30 -30
  85. package/templates/modules/drizzle/nestjs/src/database/schema.ts +10 -10
  86. package/templates/modules/drizzle/nextjs/config.json +1 -4
  87. package/templates/modules/drizzle/nextjs/lib/db.ts +13 -13
  88. package/templates/modules/drizzle/nextjs/lib/schema.ts.hbs +84 -84
  89. package/templates/modules/drizzle/tanstack/config.json +5 -5
  90. package/templates/modules/mongoose/express/config.json +1 -2
  91. package/templates/modules/mongoose/nestjs/config.json +1 -2
  92. package/templates/modules/mongoose/nestjs/src/users/user.schema.ts +21 -21
  93. package/templates/modules/mongoose/nextjs/config.json +1 -2
  94. package/templates/modules/mongoose/nextjs/lib/db.ts +36 -36
  95. package/templates/modules/mongoose/tanstack/config.json +1 -2
  96. package/templates/modules/mongoose/tanstack/src/lib/db.ts +37 -37
  97. package/templates/modules/prisma/express/config.json +0 -1
  98. package/templates/modules/prisma/express/prisma/schema.prisma +1 -1
  99. package/templates/modules/prisma/express/prisma.config.ts +12 -12
  100. package/templates/modules/prisma/express/src/lib/prisma.ts +24 -24
  101. package/templates/modules/prisma/nestjs/config.json +0 -1
  102. package/templates/modules/prisma/nestjs/prisma/schema.prisma +23 -23
  103. package/templates/modules/prisma/nestjs/prisma.config.ts +12 -12
  104. package/templates/modules/prisma/nestjs/src/prisma/prisma.module.ts +11 -11
  105. package/templates/modules/prisma/nestjs/src/prisma/prisma.service.ts +17 -17
  106. package/templates/modules/prisma/nextjs/config.json +0 -1
  107. package/templates/modules/prisma/nextjs/prisma/schema.prisma.hbs +91 -91
  108. package/templates/modules/prisma/tanstack/config.json +0 -1
  109. package/dist/args.d.ts +0 -12
  110. package/dist/args.d.ts.map +0 -1
  111. package/dist/args.js.map +0 -1
  112. package/dist/builder/configGenerator.d.ts +0 -7
  113. package/dist/builder/configGenerator.d.ts.map +0 -1
  114. package/dist/builder/configGenerator.js.map +0 -1
  115. package/dist/builder/dependencyInstaller.d.ts +0 -3
  116. package/dist/builder/dependencyInstaller.d.ts.map +0 -1
  117. package/dist/builder/dependencyInstaller.js.map +0 -1
  118. package/dist/builder/fileProcessor.d.ts +0 -6
  119. package/dist/builder/fileProcessor.d.ts.map +0 -1
  120. package/dist/builder/fileProcessor.js.map +0 -1
  121. package/dist/builder/gitInitializer.d.ts +0 -2
  122. package/dist/builder/gitInitializer.d.ts.map +0 -1
  123. package/dist/builder/gitInitializer.js.map +0 -1
  124. package/dist/builder/index.d.ts +0 -3
  125. package/dist/builder/index.d.ts.map +0 -1
  126. package/dist/builder/index.js.map +0 -1
  127. package/dist/builder/moduleSelector.d.ts +0 -6
  128. package/dist/builder/moduleSelector.d.ts.map +0 -1
  129. package/dist/builder/moduleSelector.js.map +0 -1
  130. package/dist/builder/templateContext.d.ts +0 -6
  131. package/dist/builder/templateContext.d.ts.map +0 -1
  132. package/dist/builder/templateContext.js.map +0 -1
  133. package/dist/index.d.ts +0 -2
  134. package/dist/index.d.ts.map +0 -1
  135. package/dist/index.js.map +0 -1
  136. package/dist/modules/registry.d.ts +0 -6
  137. package/dist/modules/registry.d.ts.map +0 -1
  138. package/dist/modules/registry.js.map +0 -1
  139. package/dist/output/nextSteps.d.ts +0 -3
  140. package/dist/output/nextSteps.d.ts.map +0 -1
  141. package/dist/output/nextSteps.js.map +0 -1
  142. package/dist/prompts/index.d.ts +0 -4
  143. package/dist/prompts/index.d.ts.map +0 -1
  144. package/dist/prompts/index.js.map +0 -1
  145. package/dist/prompts/stack.d.ts +0 -4
  146. package/dist/prompts/stack.d.ts.map +0 -1
  147. package/dist/prompts/stack.js.map +0 -1
  148. package/dist/types/index.d.ts +0 -137
  149. package/dist/types/index.d.ts.map +0 -1
  150. package/dist/types/index.js.map +0 -1
  151. package/dist/ui/index.d.ts +0 -3
  152. package/dist/ui/index.d.ts.map +0 -1
  153. package/dist/ui/index.js.map +0 -1
  154. package/dist/ui/messages.d.ts +0 -9
  155. package/dist/ui/messages.d.ts.map +0 -1
  156. package/dist/ui/messages.js.map +0 -1
  157. package/dist/ui/prompts.d.ts +0 -20
  158. package/dist/ui/prompts.d.ts.map +0 -1
  159. package/dist/ui/prompts.js.map +0 -1
  160. package/dist/ui/theme.d.ts +0 -9
  161. package/dist/ui/theme.d.ts.map +0 -1
  162. package/dist/ui/theme.js.map +0 -1
  163. package/dist/validators/index.d.ts +0 -6
  164. package/dist/validators/index.d.ts.map +0 -1
  165. package/dist/validators/index.js.map +0 -1
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.error = exports.warn = exports.info = exports.success = void 0;
7
7
  exports.showBanner = showBanner;
8
8
  exports.showSummary = showSummary;
9
+ exports.showPlan = showPlan;
9
10
  exports.showNextSteps = showNextSteps;
10
11
  // Everything the CLI prints outside of prompts
11
12
  const node_path_1 = __importDefault(require("node:path"));
@@ -85,6 +86,30 @@ function showSummary(config, targetDir) {
85
86
  write(` ${(0, theme_1.pink)("Path ")} ${node_path_1.default.relative((0, node_process_1.cwd)(), targetDir) || "."}`);
86
87
  write();
87
88
  }
89
+ // Prints a titled list, or nothing when the list is empty
90
+ function showSection(title, lines) {
91
+ if (lines.length === 0)
92
+ return;
93
+ write(` ${(0, theme_1.amber)((0, theme_1.bold)(title))} ${(0, theme_1.dim)(`(${lines.length})`)}`);
94
+ for (const line of lines)
95
+ write(` ${line}`);
96
+ write();
97
+ }
98
+ // Formats name/value pairs as two aligned columns
99
+ function toColumns(entries) {
100
+ const width = Math.max(0, ...Object.keys(entries).map((key) => key.length));
101
+ return Object.entries(entries).map(([key, value]) => `${key.padEnd(width)} ${(0, theme_1.dim)(value)}`);
102
+ }
103
+ // Shows everything a build would produce, for --dry-run
104
+ function showPlan(plan) {
105
+ showSection("Files", plan.files);
106
+ showSection("Dependencies", toColumns(plan.dependencies));
107
+ showSection("Dev dependencies", toColumns(plan.devDependencies));
108
+ showSection("Overrides", toColumns(plan.overrides));
109
+ showSection("Scripts", toColumns(plan.scripts));
110
+ showSection("Environment variables", Object.entries(plan.envVars).map(([key, value]) => `${key}=${(0, theme_1.dim)(value)}`));
111
+ showSection("Commands", plan.commands.map(theme_1.lime));
112
+ }
88
113
  // Shows the numbered next steps, with the commands to run highlighted
89
114
  function showNextSteps(steps) {
90
115
  write();
@@ -97,4 +122,3 @@ function showNextSteps(steps) {
97
122
  write(` ${(0, theme_1.dim)(`Your app will run at http://localhost:${types_1.DEFAULT_PORT}`)}`);
98
123
  write();
99
124
  }
100
- //# sourceMappingURL=messages.js.map
@@ -68,4 +68,3 @@ function confirm(options) {
68
68
  },
69
69
  }).prompt();
70
70
  }
71
- //# sourceMappingURL=prompts.js.map
package/dist/ui/theme.js CHANGED
@@ -21,4 +21,3 @@ const dim = (text) => (0, node_util_1.styleText)("dim", text);
21
21
  exports.dim = dim;
22
22
  const inverse = (text) => (0, node_util_1.styleText)("inverse", text);
23
23
  exports.inverse = inverse;
24
- //# sourceMappingURL=theme.js.map
@@ -1,44 +1,14 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
35
5
  Object.defineProperty(exports, "__esModule", { value: true });
36
6
  exports.projectNameSchema = void 0;
37
7
  exports.validateProjectName = validateProjectName;
38
8
  exports.validateProjectPath = validateProjectPath;
39
9
  exports.validateDirectoryEmpty = validateDirectoryEmpty;
40
- const fs = __importStar(require("fs-extra"));
41
- const path = __importStar(require("path"));
10
+ const fs_extra_1 = __importDefault(require("fs-extra"));
11
+ const node_path_1 = __importDefault(require("node:path"));
42
12
  const zod_1 = require("zod");
43
13
  // Validates project name: lowercase letters, numbers, and hyphens
44
14
  exports.projectNameSchema = zod_1.z
@@ -60,20 +30,19 @@ function validateProjectName(name) {
60
30
  // Checks a project path such as "my-app", "apps/api", or "."; the last folder
61
31
  // name becomes the package name
62
32
  function validateProjectPath(projectPath) {
63
- return validateProjectName(path.basename(path.resolve(projectPath)));
33
+ return validateProjectName(node_path_1.default.basename(node_path_1.default.resolve(projectPath)));
64
34
  }
65
35
  // Ensures a directory is empty or does not exist before starting build
66
36
  async function validateDirectoryEmpty(dirPath) {
67
- const exists = await fs.pathExists(dirPath);
37
+ const exists = await fs_extra_1.default.pathExists(dirPath);
68
38
  if (!exists)
69
39
  return null;
70
- const stats = await fs.stat(dirPath);
40
+ const stats = await fs_extra_1.default.stat(dirPath);
71
41
  if (!stats.isDirectory()) {
72
42
  return `Path "${dirPath}" exists but is not a directory`;
73
43
  }
74
- const files = await fs.readdir(dirPath);
44
+ const files = await fs_extra_1.default.readdir(dirPath);
75
45
  if (files.length === 0)
76
46
  return null;
77
- return `Directory "${path.basename(dirPath)}" already exists and is not empty`;
47
+ return `Directory "${node_path_1.default.basename(dirPath)}" already exists and is not empty`;
78
48
  }
79
- //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "better-ts-stack",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "A CLI that scaffolds Express, NestJS, Next.js, and TanStack Start projects with a database, authentication, and Docker already set up.",
5
5
  "keywords": [
6
6
  "cli",
@@ -37,6 +37,7 @@
37
37
  ],
38
38
  "scripts": {
39
39
  "dev": "tsx src/index.ts",
40
+ "prebuild": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
40
41
  "build": "tsc",
41
42
  "postbuild": "node -e \"const fs=require('fs');const p='dist/index.js';fs.writeFileSync(p,'#!/usr/bin/env node\\n'+fs.readFileSync(p,'utf8'))\"",
42
43
  "prepack": "npm run build",
@@ -7,8 +7,8 @@
7
7
  "useTabs": false,
8
8
  "arrowParens": "always",
9
9
  "endOfLine": "lf",
10
- "plugins": ["@trivago/prettier-plugin-sort-imports", "prettier-plugin-tailwindcss"],
11
- "importOrder": ["^react", "^next", "<THIRD_PARTY_MODULES>", "^@repo/(.*)$", "^@/(.*)$", "^[./]"],
10
+ "plugins": ["@trivago/prettier-plugin-sort-imports"],
11
+ "importOrder": ["<THIRD_PARTY_MODULES>", "^[./]"],
12
12
  "importOrderSeparation": true,
13
13
  "importOrderSortSpecifiers": true,
14
14
  "importOrderGroupNamespaceSpecifiers": true,
@@ -30,15 +30,11 @@
30
30
  "eslint": "^10.10.0",
31
31
  "eslint-config-prettier": "^10.1.8",
32
32
  "prettier": "^3.9.6",
33
- "prettier-plugin-tailwindcss": "^0.8.1",
34
33
  "tsx": "^4.23.13",
35
34
  "typescript": "^6.0.3",
36
35
  "typescript-eslint": "^8.69.0"
37
36
  },
38
37
  "envVars": {
39
38
  "PORT": "3000"
40
- },
41
- "templateFiles": [
42
- "src/index.ts"
43
- ]
39
+ }
44
40
  }
@@ -1,40 +1,40 @@
1
- import eslint from "@eslint/js";
2
- import path from "node:path";
3
- import { fileURLToPath } from "node:url";
4
- import tseslint from "typescript-eslint";
5
-
6
- const __filename = fileURLToPath(import.meta.url);
7
- const __dirname = path.dirname(__filename);
8
-
9
- export default tseslint.config(
10
- {
11
- ignores: [
12
- "dist",
13
- "node_modules",
14
- "templates/**/*",
15
- "bin/**/*",
16
- "src/generated/**",
17
- ],
18
- },
19
- eslint.configs.recommended,
20
- ...tseslint.configs.recommended,
21
- ...tseslint.configs.recommendedTypeChecked,
22
- {
23
- languageOptions: {
24
- parserOptions: {
25
- project: "./tsconfig.eslint.json",
26
- tsconfigRootDir: __dirname,
27
- },
28
- },
29
- rules: {
30
- "@typescript-eslint/explicit-function-return-type": "off",
31
- "@typescript-eslint/no-explicit-any": "warn",
32
- "@typescript-eslint/no-unused-vars": [
33
- "error",
34
- { argsIgnorePattern: "^_" },
35
- ],
36
- "@typescript-eslint/no-floating-promises": "error",
37
- "no-console": "off",
38
- },
39
- }
40
- );
1
+ import eslint from "@eslint/js";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import tseslint from "typescript-eslint";
5
+
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+
9
+ export default tseslint.config(
10
+ {
11
+ ignores: [
12
+ "dist",
13
+ "node_modules",
14
+ "templates/**/*",
15
+ "bin/**/*",
16
+ "src/generated/**",
17
+ ],
18
+ },
19
+ eslint.configs.recommended,
20
+ ...tseslint.configs.recommended,
21
+ ...tseslint.configs.recommendedTypeChecked,
22
+ {
23
+ languageOptions: {
24
+ parserOptions: {
25
+ project: "./tsconfig.eslint.json",
26
+ tsconfigRootDir: __dirname,
27
+ },
28
+ },
29
+ rules: {
30
+ "@typescript-eslint/explicit-function-return-type": "off",
31
+ "@typescript-eslint/no-explicit-any": "warn",
32
+ "@typescript-eslint/no-unused-vars": [
33
+ "error",
34
+ { argsIgnorePattern: "^_" },
35
+ ],
36
+ "@typescript-eslint/no-floating-promises": "error",
37
+ "no-console": "off",
38
+ },
39
+ }
40
+ );
@@ -1,36 +1,36 @@
1
- # Dependencies
2
- node_modules/
3
-
4
- # Build output
5
- dist/
6
- build/
7
-
8
- # Environment variables
9
- .env
10
- .env.local
11
- .env.*.local
12
-
13
- # Logs
14
- logs/
15
- *.log
16
- npm-debug.log*
17
- yarn-debug.log*
18
- yarn-error.log*
19
-
20
- # IDE
21
- .vscode/
22
- .idea/
23
- *.swp
24
- *.swo
25
- *~
26
-
27
- # OS
28
- .DS_Store
29
- Thumbs.db
30
-
31
- # Testing
32
- coverage/
33
- .nyc_output/
34
-
35
- # Misc
36
- *.tsbuildinfo
1
+ # Dependencies
2
+ node_modules/
3
+
4
+ # Build output
5
+ dist/
6
+ build/
7
+
8
+ # Environment variables
9
+ .env
10
+ .env.local
11
+ .env.*.local
12
+
13
+ # Logs
14
+ logs/
15
+ *.log
16
+ npm-debug.log*
17
+ yarn-debug.log*
18
+ yarn-error.log*
19
+
20
+ # IDE
21
+ .vscode/
22
+ .idea/
23
+ *.swp
24
+ *.swo
25
+ *~
26
+
27
+ # OS
28
+ .DS_Store
29
+ Thumbs.db
30
+
31
+ # Testing
32
+ coverage/
33
+ .nyc_output/
34
+
35
+ # Misc
36
+ *.tsbuildinfo
@@ -1,37 +1,35 @@
1
- import 'dotenv/config';
2
- import express, { Express, Request, Response, NextFunction } from 'express';
3
- import cors from 'cors';
4
- import helmet from 'helmet';
5
- import morgan from 'morgan';
1
+ import "dotenv/config";
2
+ import express, { Express, Request, Response, NextFunction } from "express";
3
+ import cors from "cors";
4
+ import helmet from "helmet";
5
+ import morgan from "morgan";
6
6
  {{#if (eq database 'mongoose')}}
7
- import { connectDB } from './lib/db';
7
+ import { connectDB } from "./lib/db";
8
8
  {{/if}}
9
- import healthRouter from './routes/health';
9
+ import healthRouter from "./routes/health";
10
10
  {{#if useAuth}}
11
- import authRouter from './routes/auth';
11
+ import authRouter from "./routes/auth";
12
12
  {{/if}}
13
13
 
14
-
15
-
16
14
  const app: Express = express();
17
15
  const port = process.env.PORT || 3000;
18
16
 
19
17
  // Middleware
20
18
  app.use(helmet());
21
19
  app.use(cors());
22
- app.use(morgan('dev'));
20
+ app.use(morgan("dev"));
23
21
  app.use(express.json());
24
22
  app.use(express.urlencoded({ extended: true }));
25
23
 
26
24
  // Routes
27
- app.use('/health', healthRouter);
25
+ app.use("/health", healthRouter);
28
26
  {{#if useAuth}}
29
- app.use('/auth', authRouter);
27
+ app.use("/auth", authRouter);
30
28
  {{/if}}
31
29
 
32
30
  // 404 handler
33
31
  app.use((_req: Request, res: Response) => {
34
- res.status(404).json({ error: 'Not Found' });
32
+ res.status(404).json({ error: "Not Found" });
35
33
  });
36
34
 
37
35
  // Error handler
@@ -46,31 +44,32 @@ app.use(
46
44
  const status = err.status ?? err.statusCode ?? 500;
47
45
 
48
46
  if (status >= 400 && status < 500) {
49
- res.status(status).json({ error: err.expose ? err.message : 'Bad Request' });
47
+ res.status(status).json({ error: err.expose ? err.message : "Bad Request" });
50
48
  return;
51
49
  }
52
50
 
53
51
  console.error(err.stack);
54
- res.status(500).json({ error: 'Internal Server Error' });
52
+ res.status(500).json({ error: "Internal Server Error" });
55
53
  },
56
54
  );
57
55
 
58
- {{#if (eq database 'mongoose')}}
59
- void awaitDatabase().catch((error: unknown) => {
60
- console.error(error);
61
- process.exitCode = 1;
62
- });
63
- async function awaitDatabase(): Promise<void> {
64
- await connectDB();
65
- app.listen(port);
66
- }
67
- {{else}}
68
- app.listen(port, () => {
69
- console.log(`Server is running on http://localhost:${port}
56
+ function listen(): void {
57
+ app.listen(port, () => {
58
+ console.log(`Server is running on http://localhost:${port}
70
59
  Health: http://localhost:${port}/health
71
60
  `);
72
- });
61
+ });
62
+ }
73
63
 
64
+ {{#if (eq database 'mongoose')}}
65
+ void connectDB()
66
+ .then(listen)
67
+ .catch((error: unknown) => {
68
+ console.error(error);
69
+ process.exitCode = 1;
70
+ });
71
+ {{else}}
72
+ listen();
74
73
  {{/if}}
75
74
 
76
75
  export default app;
@@ -1,12 +1,12 @@
1
- import { Request, Response, Router } from "express";
2
-
3
- const router: Router = Router();
4
-
5
- router.get("/", (_req: Request, res: Response) => {
6
- res.status(200).json({
7
- status: "ok",
8
- timestamp: new Date().toISOString(),
9
- });
10
- });
11
-
12
- export default router;
1
+ import { Request, Response, Router } from "express";
2
+
3
+ const router: Router = Router();
4
+
5
+ router.get("/", (_req: Request, res: Response) => {
6
+ res.status(200).json({
7
+ status: "ok",
8
+ timestamp: new Date().toISOString(),
9
+ });
10
+ });
11
+
12
+ export default router;
@@ -1,25 +1,25 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2020",
4
- "module": "NodeNext",
5
- "lib": ["ES2020"],
6
- "outDir": "./dist",
7
- "rootDir": "./src",
8
- "strict": true,
9
- "esModuleInterop": true,
10
- "skipLibCheck": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "resolveJsonModule": true,
13
- "declaration": true,
14
- "declarationMap": true,
15
- "sourceMap": true,
16
- "noUnusedLocals": true,
17
- "noUnusedParameters": true,
18
- "noImplicitReturns": true,
19
- "noFallthroughCasesInSwitch": true,
20
- "moduleResolution": "NodeNext",
21
- "types": ["node"]
22
- },
23
- "include": ["src/**/*"],
24
- "exclude": ["node_modules", "dist"]
25
- }
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "NodeNext",
5
+ "lib": ["ES2020"],
6
+ "outDir": "./dist",
7
+ "rootDir": "./src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "resolveJsonModule": true,
13
+ "declaration": true,
14
+ "declarationMap": true,
15
+ "sourceMap": true,
16
+ "noUnusedLocals": true,
17
+ "noUnusedParameters": true,
18
+ "noImplicitReturns": true,
19
+ "noFallthroughCasesInSwitch": true,
20
+ "moduleResolution": "NodeNext",
21
+ "types": ["node"]
22
+ },
23
+ "include": ["src/**/*"],
24
+ "exclude": ["node_modules", "dist"]
25
+ }
@@ -1,16 +1,16 @@
1
- {
2
- "semi": true,
3
- "trailingComma": "es5",
4
- "singleQuote": false,
5
- "printWidth": 80,
6
- "tabWidth": 2,
7
- "useTabs": false,
8
- "arrowParens": "always",
9
- "endOfLine": "lf",
10
- "plugins": ["@trivago/prettier-plugin-sort-imports"],
11
- "importOrder": ["<THIRD_PARTY_MODULES>", "^[./]"],
12
- "importOrderSeparation": true,
13
- "importOrderSortSpecifiers": true,
14
- "importOrderCaseInsensitive": true,
15
- "importOrderParserPlugins": ["typescript", "decorators-legacy"]
16
- }
1
+ {
2
+ "semi": true,
3
+ "trailingComma": "es5",
4
+ "singleQuote": false,
5
+ "printWidth": 80,
6
+ "tabWidth": 2,
7
+ "useTabs": false,
8
+ "arrowParens": "always",
9
+ "endOfLine": "lf",
10
+ "plugins": ["@trivago/prettier-plugin-sort-imports"],
11
+ "importOrder": ["<THIRD_PARTY_MODULES>", "^[./]"],
12
+ "importOrderSeparation": true,
13
+ "importOrderSortSpecifiers": true,
14
+ "importOrderCaseInsensitive": true,
15
+ "importOrderParserPlugins": ["typescript", "decorators-legacy"]
16
+ }
@@ -37,8 +37,5 @@
37
37
  },
38
38
  "envVars": {
39
39
  "PORT": "3000"
40
- },
41
- "templateFiles": [
42
- "src/app.module.ts.hbs"
43
- ]
40
+ }
44
41
  }
@@ -1,40 +1,40 @@
1
- import eslint from "@eslint/js";
2
- import path from "node:path";
3
- import { fileURLToPath } from "node:url";
4
- import tseslint from "typescript-eslint";
5
-
6
- const __filename = fileURLToPath(import.meta.url);
7
- const __dirname = path.dirname(__filename);
8
-
9
- export default tseslint.config(
10
- {
11
- ignores: [
12
- "dist",
13
- "node_modules",
14
- "templates/**/*",
15
- "bin/**/*",
16
- "src/generated/**",
17
- ],
18
- },
19
- eslint.configs.recommended,
20
- ...tseslint.configs.recommended,
21
- ...tseslint.configs.recommendedTypeChecked,
22
- {
23
- languageOptions: {
24
- parserOptions: {
25
- project: "./tsconfig.eslint.json",
26
- tsconfigRootDir: __dirname,
27
- },
28
- },
29
- rules: {
30
- "@typescript-eslint/explicit-function-return-type": "off",
31
- "@typescript-eslint/no-explicit-any": "warn",
32
- "@typescript-eslint/no-unused-vars": [
33
- "error",
34
- { argsIgnorePattern: "^_" },
35
- ],
36
- "@typescript-eslint/no-floating-promises": "error",
37
- "no-console": "off",
38
- },
39
- }
40
- );
1
+ import eslint from "@eslint/js";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import tseslint from "typescript-eslint";
5
+
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+
9
+ export default tseslint.config(
10
+ {
11
+ ignores: [
12
+ "dist",
13
+ "node_modules",
14
+ "templates/**/*",
15
+ "bin/**/*",
16
+ "src/generated/**",
17
+ ],
18
+ },
19
+ eslint.configs.recommended,
20
+ ...tseslint.configs.recommended,
21
+ ...tseslint.configs.recommendedTypeChecked,
22
+ {
23
+ languageOptions: {
24
+ parserOptions: {
25
+ project: "./tsconfig.eslint.json",
26
+ tsconfigRootDir: __dirname,
27
+ },
28
+ },
29
+ rules: {
30
+ "@typescript-eslint/explicit-function-return-type": "off",
31
+ "@typescript-eslint/no-explicit-any": "warn",
32
+ "@typescript-eslint/no-unused-vars": [
33
+ "error",
34
+ { argsIgnorePattern: "^_" },
35
+ ],
36
+ "@typescript-eslint/no-floating-promises": "error",
37
+ "no-console": "off",
38
+ },
39
+ }
40
+ );