@appinit/cli 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (259) hide show
  1. package/LICENSE +68 -0
  2. package/README.md +27 -95
  3. package/dist/index.d.ts +371 -2
  4. package/dist/index.js +3795 -24
  5. package/dist/templates/backend-express/.appinit-generate/project/.appinit/project.json +6 -0
  6. package/dist/templates/backend-express/.appinit-generate/project/.appinit/template.json +6 -0
  7. package/dist/templates/backend-express/.appinit-generate/project/.env.example +4 -0
  8. package/dist/templates/backend-express/.appinit-generate/project/.husky/pre-commit +1 -0
  9. package/dist/templates/backend-express/.appinit-generate/project/.prettierignore +3 -0
  10. package/dist/templates/backend-express/.appinit-generate/project/.prettierrc +28 -0
  11. package/dist/templates/backend-express/.appinit-generate/project/.vscode/settings.json +6 -0
  12. package/dist/templates/backend-express/.appinit-generate/project/Dockerfile +14 -0
  13. package/dist/templates/backend-express/.appinit-generate/project/README.md +26 -0
  14. package/dist/templates/backend-express/.appinit-generate/project/eslint.config.js +76 -0
  15. package/dist/templates/backend-express/.appinit-generate/project/nodemon.json +8 -0
  16. package/dist/templates/backend-express/.appinit-generate/project/package.json +69 -0
  17. package/dist/templates/backend-express/.appinit-generate/project/src/__tests__/health.test.ts +19 -0
  18. package/dist/templates/backend-express/.appinit-generate/project/src/__tests__/validation.test.ts +36 -0
  19. package/dist/templates/backend-express/.appinit-generate/project/src/app.ts +72 -0
  20. package/dist/templates/backend-express/.appinit-generate/project/src/config/defaults.ts +5 -0
  21. package/dist/templates/backend-express/.appinit-generate/project/src/config/dev.ts +3 -0
  22. package/dist/templates/backend-express/.appinit-generate/project/src/config/env.ts +62 -0
  23. package/dist/templates/backend-express/.appinit-generate/project/src/config/prod.ts +3 -0
  24. package/dist/templates/backend-express/.appinit-generate/project/src/config/test.ts +3 -0
  25. package/dist/templates/backend-express/.appinit-generate/project/src/errors/app-error.ts +20 -0
  26. package/dist/templates/backend-express/.appinit-generate/project/src/errors/not-found.ts +16 -0
  27. package/dist/templates/backend-express/.appinit-generate/project/src/middleware/error-handler.ts +73 -0
  28. package/dist/templates/backend-express/.appinit-generate/project/src/middleware/http-logger.ts +5 -0
  29. package/dist/templates/backend-express/.appinit-generate/project/src/middleware/validate.ts +17 -0
  30. package/dist/templates/backend-express/.appinit-generate/project/src/routes/health.ts +13 -0
  31. package/dist/templates/backend-express/.appinit-generate/project/src/routes/users.ts +12 -0
  32. package/dist/templates/backend-express/.appinit-generate/project/src/schema/create-user.schema.ts +8 -0
  33. package/dist/templates/backend-express/.appinit-generate/project/src/server.ts +54 -0
  34. package/dist/templates/backend-express/.appinit-generate/project/src/utils/logger.ts +21 -0
  35. package/dist/templates/backend-express/.appinit-generate/project/tsconfig.json +30 -0
  36. package/dist/templates/backend-express/.appinit-generate/project/vitest.config.ts +15 -0
  37. package/dist/templates/backend-express/.appinit-preview/project/.appinit/project.json +6 -0
  38. package/dist/templates/backend-express/.appinit-preview/project/.appinit/template.json +6 -0
  39. package/dist/templates/backend-express/.appinit-preview/project/.env.example +4 -0
  40. package/dist/templates/backend-express/.appinit-preview/project/.husky/pre-commit +1 -0
  41. package/dist/templates/backend-express/.appinit-preview/project/.prettierignore +3 -0
  42. package/dist/templates/backend-express/.appinit-preview/project/.prettierrc +28 -0
  43. package/dist/templates/backend-express/.appinit-preview/project/.vscode/settings.json +6 -0
  44. package/dist/templates/backend-express/.appinit-preview/project/Dockerfile +14 -0
  45. package/dist/templates/backend-express/.appinit-preview/project/README.md +26 -0
  46. package/dist/templates/backend-express/.appinit-preview/project/eslint.config.js +76 -0
  47. package/dist/templates/backend-express/.appinit-preview/project/nodemon.json +8 -0
  48. package/dist/templates/backend-express/.appinit-preview/project/package.json +69 -0
  49. package/dist/templates/backend-express/.appinit-preview/project/src/__tests__/health.test.ts +19 -0
  50. package/dist/templates/backend-express/.appinit-preview/project/src/__tests__/validation.test.ts +36 -0
  51. package/dist/templates/backend-express/.appinit-preview/project/src/app.ts +72 -0
  52. package/dist/templates/backend-express/.appinit-preview/project/src/config/defaults.ts +5 -0
  53. package/dist/templates/backend-express/.appinit-preview/project/src/config/dev.ts +3 -0
  54. package/dist/templates/backend-express/.appinit-preview/project/src/config/env.ts +62 -0
  55. package/dist/templates/backend-express/.appinit-preview/project/src/config/prod.ts +3 -0
  56. package/dist/templates/backend-express/.appinit-preview/project/src/config/test.ts +3 -0
  57. package/dist/templates/backend-express/.appinit-preview/project/src/errors/app-error.ts +20 -0
  58. package/dist/templates/backend-express/.appinit-preview/project/src/errors/not-found.ts +16 -0
  59. package/dist/templates/backend-express/.appinit-preview/project/src/middleware/error-handler.ts +73 -0
  60. package/dist/templates/backend-express/.appinit-preview/project/src/middleware/http-logger.ts +5 -0
  61. package/dist/templates/backend-express/.appinit-preview/project/src/middleware/validate.ts +17 -0
  62. package/dist/templates/backend-express/.appinit-preview/project/src/routes/health.ts +13 -0
  63. package/dist/templates/backend-express/.appinit-preview/project/src/routes/users.ts +12 -0
  64. package/dist/templates/backend-express/.appinit-preview/project/src/schema/create-user.schema.ts +8 -0
  65. package/dist/templates/backend-express/.appinit-preview/project/src/server.ts +54 -0
  66. package/dist/templates/backend-express/.appinit-preview/project/src/utils/logger.ts +21 -0
  67. package/dist/templates/backend-express/.appinit-preview/project/tsconfig.json +30 -0
  68. package/dist/templates/backend-express/.appinit-preview/project/vitest.config.ts +15 -0
  69. package/dist/templates/backend-express/README.md +107 -0
  70. package/dist/templates/backend-express/appinit.template.json +25 -0
  71. package/dist/templates/backend-express/docs/README.md +11 -0
  72. package/dist/templates/backend-express/package.json +5 -0
  73. package/dist/templates/backend-express/template/.env.example +4 -0
  74. package/dist/templates/backend-express/template/.husky/pre-commit +1 -0
  75. package/dist/templates/backend-express/template/.prettierignore +3 -0
  76. package/dist/templates/backend-express/template/.prettierrc +28 -0
  77. package/dist/templates/backend-express/template/.vscode/settings.json +6 -0
  78. package/dist/templates/backend-express/template/Dockerfile +14 -0
  79. package/dist/templates/backend-express/template/README.md__tmpl +26 -0
  80. package/dist/templates/backend-express/template/eslint.config.js +76 -0
  81. package/dist/templates/backend-express/template/nodemon.json +8 -0
  82. package/dist/templates/backend-express/template/package.json__tmpl +69 -0
  83. package/dist/templates/backend-express/template/src/__tests__/health.test.ts +19 -0
  84. package/dist/templates/backend-express/template/src/__tests__/validation.test.ts +36 -0
  85. package/dist/templates/backend-express/template/src/app.ts +72 -0
  86. package/dist/templates/backend-express/template/src/config/defaults.ts +5 -0
  87. package/dist/templates/backend-express/template/src/config/dev.ts +3 -0
  88. package/dist/templates/backend-express/template/src/config/env.ts +62 -0
  89. package/dist/templates/backend-express/template/src/config/prod.ts +3 -0
  90. package/dist/templates/backend-express/template/src/config/test.ts +3 -0
  91. package/dist/templates/backend-express/template/src/errors/app-error.ts +20 -0
  92. package/dist/templates/backend-express/template/src/errors/not-found.ts +16 -0
  93. package/dist/templates/backend-express/template/src/middleware/error-handler.ts +73 -0
  94. package/dist/templates/backend-express/template/src/middleware/http-logger.ts +5 -0
  95. package/dist/templates/backend-express/template/src/middleware/validate.ts +17 -0
  96. package/dist/templates/backend-express/template/src/routes/health.ts +13 -0
  97. package/dist/templates/backend-express/template/src/routes/users.ts +12 -0
  98. package/dist/templates/backend-express/template/src/schema/create-user.schema.ts +8 -0
  99. package/dist/templates/backend-express/template/src/server.ts +54 -0
  100. package/dist/templates/backend-express/template/src/utils/logger.ts +21 -0
  101. package/dist/templates/backend-express/template/tsconfig.json +30 -0
  102. package/dist/templates/backend-express/template/vitest.config.ts +15 -0
  103. package/dist/templates/backend-express/template.config.ts +36 -0
  104. package/dist/templates/backend-express/variables/defaults.json +7 -0
  105. package/dist/templates/backend-express/variables/defaults.ts +4 -0
  106. package/dist/templates/backend-express/variables/schema.json +22 -0
  107. package/dist/templates/backend-express/variables/schema.ts +11 -0
  108. package/dist/templates/backend-express/variables/transform.ts +6 -0
  109. package/dist/templates/backend-fastify/.appinit-generate/project/.appinit/project.json +6 -0
  110. package/dist/templates/backend-fastify/.appinit-generate/project/.appinit/template.json +6 -0
  111. package/dist/templates/backend-fastify/.appinit-generate/project/README.md +26 -0
  112. package/dist/templates/backend-fastify/.appinit-generate/project/nodemon.json +8 -0
  113. package/dist/templates/backend-fastify/.appinit-generate/project/package-lock.json +3245 -0
  114. package/dist/templates/backend-fastify/.appinit-generate/project/package.json +24 -0
  115. package/dist/templates/backend-fastify/.appinit-generate/project/src/app.ts +13 -0
  116. package/dist/templates/backend-fastify/.appinit-generate/project/src/server.ts +15 -0
  117. package/dist/templates/backend-fastify/.appinit-generate/project/tsconfig.json +30 -0
  118. package/dist/templates/backend-fastify/README.md +27 -0
  119. package/dist/templates/backend-fastify/appinit.template.json +25 -0
  120. package/dist/templates/backend-fastify/docs/README.md +12 -0
  121. package/dist/templates/backend-fastify/package.json +5 -0
  122. package/dist/templates/backend-fastify/template/README.md__tmpl +26 -0
  123. package/dist/templates/backend-fastify/template/nodemon.json +8 -0
  124. package/dist/templates/backend-fastify/template/package.json__tmpl +24 -0
  125. package/dist/templates/backend-fastify/template/src/app.ts +13 -0
  126. package/dist/templates/backend-fastify/template/src/server.ts +15 -0
  127. package/dist/templates/backend-fastify/template/tsconfig.json +30 -0
  128. package/dist/templates/backend-fastify/template.config.ts +32 -0
  129. package/dist/templates/backend-fastify/variables/defaults.json +4 -0
  130. package/dist/templates/backend-fastify/variables/defaults.ts +3 -0
  131. package/dist/templates/backend-fastify/variables/schema.json +7 -0
  132. package/dist/templates/backend-fastify/variables/schema.ts +1 -0
  133. package/dist/templates/backend-fastify/variables/transform.ts +3 -0
  134. package/dist/templates/frontend-nextjs/.appinit-generate/project/.appinit/project.json +6 -0
  135. package/dist/templates/frontend-nextjs/.appinit-generate/project/.appinit/template.json +6 -0
  136. package/dist/templates/frontend-nextjs/.appinit-generate/project/README.md +33 -0
  137. package/dist/templates/frontend-nextjs/.appinit-generate/project/app/favicon.ico +0 -0
  138. package/dist/templates/frontend-nextjs/.appinit-generate/project/app/globals.css +42 -0
  139. package/dist/templates/frontend-nextjs/.appinit-generate/project/app/layout.tsx +33 -0
  140. package/dist/templates/frontend-nextjs/.appinit-generate/project/app/page.module.css +141 -0
  141. package/dist/templates/frontend-nextjs/.appinit-generate/project/app/page.tsx +67 -0
  142. package/dist/templates/frontend-nextjs/.appinit-generate/project/next-env.d.ts +6 -0
  143. package/dist/templates/frontend-nextjs/.appinit-generate/project/next.config.ts +8 -0
  144. package/dist/templates/frontend-nextjs/.appinit-generate/project/package.json +25 -0
  145. package/dist/templates/frontend-nextjs/.appinit-generate/project/public/file.svg +1 -0
  146. package/dist/templates/frontend-nextjs/.appinit-generate/project/public/globe.svg +1 -0
  147. package/dist/templates/frontend-nextjs/.appinit-generate/project/public/next.svg +1 -0
  148. package/dist/templates/frontend-nextjs/.appinit-generate/project/public/vercel.svg +1 -0
  149. package/dist/templates/frontend-nextjs/.appinit-generate/project/public/window.svg +1 -0
  150. package/dist/templates/frontend-nextjs/.appinit-generate/project/tsconfig.json +34 -0
  151. package/dist/templates/frontend-nextjs/.appinit-preview/project/.appinit/project.json +6 -0
  152. package/dist/templates/frontend-nextjs/.appinit-preview/project/.appinit/template.json +6 -0
  153. package/dist/templates/frontend-nextjs/.appinit-preview/project/README.md +33 -0
  154. package/dist/templates/frontend-nextjs/.appinit-preview/project/app/favicon.ico +0 -0
  155. package/dist/templates/frontend-nextjs/.appinit-preview/project/app/globals.css +42 -0
  156. package/dist/templates/frontend-nextjs/.appinit-preview/project/app/layout.tsx +33 -0
  157. package/dist/templates/frontend-nextjs/.appinit-preview/project/app/page.module.css +141 -0
  158. package/dist/templates/frontend-nextjs/.appinit-preview/project/app/page.tsx +67 -0
  159. package/dist/templates/frontend-nextjs/.appinit-preview/project/next-env.d.ts +6 -0
  160. package/dist/templates/frontend-nextjs/.appinit-preview/project/next.config.ts +8 -0
  161. package/dist/templates/frontend-nextjs/.appinit-preview/project/package.json +25 -0
  162. package/dist/templates/frontend-nextjs/.appinit-preview/project/public/file.svg +1 -0
  163. package/dist/templates/frontend-nextjs/.appinit-preview/project/public/globe.svg +1 -0
  164. package/dist/templates/frontend-nextjs/.appinit-preview/project/public/next.svg +1 -0
  165. package/dist/templates/frontend-nextjs/.appinit-preview/project/public/vercel.svg +1 -0
  166. package/dist/templates/frontend-nextjs/.appinit-preview/project/public/window.svg +1 -0
  167. package/dist/templates/frontend-nextjs/.appinit-preview/project/tsconfig.json +34 -0
  168. package/dist/templates/frontend-nextjs/README.md +27 -0
  169. package/dist/templates/frontend-nextjs/appinit.template.json +25 -0
  170. package/dist/templates/frontend-nextjs/docs/README.md +12 -0
  171. package/dist/templates/frontend-nextjs/package.json +5 -0
  172. package/dist/templates/frontend-nextjs/template/README.md__tmpl +33 -0
  173. package/dist/templates/frontend-nextjs/template/app/favicon.ico +0 -0
  174. package/dist/templates/frontend-nextjs/template/app/globals.css +42 -0
  175. package/dist/templates/frontend-nextjs/template/app/layout.tsx +33 -0
  176. package/dist/templates/frontend-nextjs/template/app/page.module.css +141 -0
  177. package/dist/templates/frontend-nextjs/template/app/page.tsx +67 -0
  178. package/dist/templates/frontend-nextjs/template/next-env.d.ts +6 -0
  179. package/dist/templates/frontend-nextjs/template/next.config.ts +8 -0
  180. package/dist/templates/frontend-nextjs/template/package.json__tmpl +25 -0
  181. package/dist/templates/frontend-nextjs/template/public/file.svg +1 -0
  182. package/dist/templates/frontend-nextjs/template/public/globe.svg +1 -0
  183. package/dist/templates/frontend-nextjs/template/public/next.svg +1 -0
  184. package/dist/templates/frontend-nextjs/template/public/vercel.svg +1 -0
  185. package/dist/templates/frontend-nextjs/template/public/window.svg +1 -0
  186. package/dist/templates/frontend-nextjs/template/tsconfig.json +34 -0
  187. package/dist/templates/frontend-nextjs/template.config.ts +28 -0
  188. package/dist/templates/frontend-nextjs/variables/defaults.json +6 -0
  189. package/dist/templates/frontend-nextjs/variables/defaults.ts +4 -0
  190. package/dist/templates/frontend-nextjs/variables/schema.json +22 -0
  191. package/dist/templates/frontend-nextjs/variables/schema.ts +7 -0
  192. package/dist/templates/frontend-nextjs/variables/transform.ts +3 -0
  193. package/dist/templates/frontend-react/.appinit-generate/project/.appinit/project.json +6 -0
  194. package/dist/templates/frontend-react/.appinit-generate/project/.appinit/template.json +6 -0
  195. package/dist/templates/frontend-react/.appinit-generate/project/README.md +14 -0
  196. package/dist/templates/frontend-react/.appinit-generate/project/index.html +12 -0
  197. package/dist/templates/frontend-react/.appinit-generate/project/package.json +26 -0
  198. package/dist/templates/frontend-react/.appinit-generate/project/public/vite.svg +30 -0
  199. package/dist/templates/frontend-react/.appinit-generate/project/src/App.tsx +16 -0
  200. package/dist/templates/frontend-react/.appinit-generate/project/src/assets/react.svg +1 -0
  201. package/dist/templates/frontend-react/.appinit-generate/project/src/index.css +9 -0
  202. package/dist/templates/frontend-react/.appinit-generate/project/src/main.tsx +10 -0
  203. package/dist/templates/frontend-react/.appinit-generate/project/tsconfig.app.json +31 -0
  204. package/dist/templates/frontend-react/.appinit-generate/project/tsconfig.json +7 -0
  205. package/dist/templates/frontend-react/.appinit-generate/project/tsconfig.node.json +26 -0
  206. package/dist/templates/frontend-react/.appinit-generate/project/vite.config.ts +16 -0
  207. package/dist/templates/frontend-react/appinit.template.json +26 -0
  208. package/dist/templates/frontend-react/docs/README.md +12 -0
  209. package/dist/templates/frontend-react/hooks/afterRender.ts +3 -0
  210. package/dist/templates/frontend-react/hooks/afterWrite.ts +3 -0
  211. package/dist/templates/frontend-react/hooks/beforeRender.ts +3 -0
  212. package/dist/templates/frontend-react/hooks/beforeWrite.ts +3 -0
  213. package/dist/templates/frontend-react/package.json +16 -0
  214. package/dist/templates/frontend-react/template/.env.example__tmpl +1 -0
  215. package/dist/templates/frontend-react/template/README.md__tmpl +14 -0
  216. package/dist/templates/frontend-react/template/_gitignore +41 -0
  217. package/dist/templates/frontend-react/template/index.html__tmpl +12 -0
  218. package/dist/templates/frontend-react/template/package.json__tmpl +26 -0
  219. package/dist/templates/frontend-react/template/public/vite.svg +30 -0
  220. package/dist/templates/frontend-react/template/src/App.tsx__tmpl +16 -0
  221. package/dist/templates/frontend-react/template/src/assets/react.svg +1 -0
  222. package/dist/templates/frontend-react/template/src/index.css__tmpl +9 -0
  223. package/dist/templates/frontend-react/template/src/main.tsx__tmpl +10 -0
  224. package/dist/templates/frontend-react/template/tsconfig.app.json__tmpl +31 -0
  225. package/dist/templates/frontend-react/template/tsconfig.json__tmpl +7 -0
  226. package/dist/templates/frontend-react/template/tsconfig.node.json__tmpl +26 -0
  227. package/dist/templates/frontend-react/template/vite.config.ts__tmpl +16 -0
  228. package/dist/templates/frontend-react/template.config.ts +26 -0
  229. package/dist/templates/frontend-react/template.meta.json +10 -0
  230. package/dist/templates/frontend-react/variables/defaults.json +6 -0
  231. package/dist/templates/frontend-react/variables/defaults.ts +6 -0
  232. package/dist/templates/frontend-react/variables/schema.json +15 -0
  233. package/dist/templates/frontend-react/variables/schema.ts +17 -0
  234. package/dist/templates/frontend-react/variables/transform.ts +10 -0
  235. package/dist/templates/frontend-vue/README.md +27 -0
  236. package/dist/templates/frontend-vue/appinit.template.json +25 -0
  237. package/dist/templates/frontend-vue/docs/README.md +12 -0
  238. package/dist/templates/frontend-vue/package.json +5 -0
  239. package/dist/templates/frontend-vue/template/README.md__tmpl +31 -0
  240. package/dist/templates/frontend-vue/template/index.html +13 -0
  241. package/dist/templates/frontend-vue/template/package.json__tmpl +25 -0
  242. package/dist/templates/frontend-vue/template/public/vite.svg +1 -0
  243. package/dist/templates/frontend-vue/template/src/App.vue +30 -0
  244. package/dist/templates/frontend-vue/template/src/assets/vue.svg +1 -0
  245. package/dist/templates/frontend-vue/template/src/components/HelloWorld.vue +42 -0
  246. package/dist/templates/frontend-vue/template/src/main.ts +6 -0
  247. package/dist/templates/frontend-vue/template/src/style.css +79 -0
  248. package/dist/templates/frontend-vue/template/tsconfig.app.json +16 -0
  249. package/dist/templates/frontend-vue/template/tsconfig.json +7 -0
  250. package/dist/templates/frontend-vue/template/tsconfig.node.json +26 -0
  251. package/dist/templates/frontend-vue/template/vite.config.ts +7 -0
  252. package/dist/templates/frontend-vue/template.config.ts +32 -0
  253. package/dist/templates/frontend-vue/variables/defaults.json +6 -0
  254. package/dist/templates/frontend-vue/variables/defaults.ts +3 -0
  255. package/dist/templates/frontend-vue/variables/schema.json +22 -0
  256. package/dist/templates/frontend-vue/variables/schema.ts +1 -0
  257. package/dist/templates/frontend-vue/variables/transform.ts +3 -0
  258. package/package.json +40 -29
  259. package/bin/appinit.js +0 -15
@@ -0,0 +1,73 @@
1
+ import type { NextFunction, Request, Response } from "express";
2
+ import { ZodError } from "zod";
3
+
4
+ import { env } from "../config/env.js";
5
+ import { AppError } from "../errors/app-error.js";
6
+ import { logger } from "../utils/logger.js";
7
+
8
+ export function errorHandler(
9
+ err: unknown,
10
+ _req: Request,
11
+ res: Response,
12
+ _next: NextFunction,
13
+ ) {
14
+ /**
15
+ * Zod validation errors (400)
16
+ */
17
+ if (err instanceof ZodError) {
18
+ const fieldErrors: Record<string, string[]> = {};
19
+
20
+ for (const issue of err.issues) {
21
+ const field = issue.path.join(".") || "root";
22
+ fieldErrors[field] ??= [];
23
+ fieldErrors[field].push(issue.message);
24
+ }
25
+
26
+ logger.warn({ fieldErrors }, "Request validation failed");
27
+
28
+ return res.status(400).json({
29
+ error: {
30
+ code: "VALIDATION_ERROR",
31
+ message: "Invalid request",
32
+ fields: fieldErrors,
33
+ },
34
+ });
35
+ }
36
+ // Normalize error
37
+ const error =
38
+ err instanceof AppError
39
+ ? err
40
+ : new AppError("Internal server error", {
41
+ statusCode: 500,
42
+ code: "INTERNAL_SERVER_ERROR",
43
+ isOperational: false,
44
+ });
45
+
46
+ // Log full error (always)
47
+ logger.error(
48
+ {
49
+ err,
50
+ statusCode: error.statusCode,
51
+ code: error.code,
52
+ },
53
+ "Unhandled application error",
54
+ );
55
+
56
+ // Response (safe for clients)
57
+ const response: Record<string, unknown> = {
58
+ error: {
59
+ code: error.code,
60
+ message: error.message,
61
+ },
62
+ };
63
+
64
+ // Dev-only details
65
+ if (env.nodeEnv !== "production") {
66
+ response.error = {
67
+ ...(response.error ?? {}),
68
+ details: err instanceof Error ? err.stack : err,
69
+ };
70
+ }
71
+
72
+ res.status(error.statusCode).json(response);
73
+ }
@@ -0,0 +1,5 @@
1
+ import pinoHttp from "pino-http";
2
+
3
+ import { logger } from "../utils/logger.js";
4
+
5
+ export const httpLogger = pinoHttp({ logger });
@@ -0,0 +1,17 @@
1
+ import type { NextFunction, Request, Response } from "express";
2
+ import type { ZodSchema } from "zod";
3
+
4
+ export const validate =
5
+ <T>(schema: ZodSchema<T>) =>
6
+ (req: Request, _res: Response, next: NextFunction) => {
7
+ try {
8
+ schema.parse({
9
+ body: req.body,
10
+ query: req.query,
11
+ params: req.params,
12
+ });
13
+ next();
14
+ } catch (err) {
15
+ next(err);
16
+ }
17
+ };
@@ -0,0 +1,13 @@
1
+ import { Router } from "express";
2
+
3
+ export const router = Router();
4
+
5
+ router.get("/", (_req, res) => {
6
+ res.status(200).json({ status: "ok" });
7
+ });
8
+
9
+ router.get("/ready", (_req, res) => {
10
+ res.status(200).json({ ready: true });
11
+ });
12
+
13
+ export { router as healthRouter };
@@ -0,0 +1,12 @@
1
+ import { Router } from "express";
2
+
3
+ import { validate } from "../middleware/validate";
4
+ import { createUserSchema } from "../schema/create-user.schema";
5
+
6
+ const router = Router();
7
+
8
+ router.post("/", validate(createUserSchema), (_req, res) => {
9
+ res.status(201).json({ ok: true });
10
+ });
11
+
12
+ export { router as userRouter };
@@ -0,0 +1,8 @@
1
+ import { z } from "zod";
2
+
3
+ export const createUserSchema = z.object({
4
+ body: z.object({
5
+ email: z.email(),
6
+ password: z.string().min(8),
7
+ }),
8
+ });
@@ -0,0 +1,54 @@
1
+ import { app } from "./app";
2
+ import { logger } from "./utils/logger";
3
+
4
+ // Assuming the Pino logger from before
5
+
6
+ const PORT = process.env.PORT || 3001;
7
+
8
+ const server = app.listen(PORT, () => {
9
+ logger.info(`🚀 Server version 1.0.0 started`);
10
+ logger.info(`📡 Listening on http://localhost:${PORT}`);
11
+ logger.info(`🌍 Environment: ${process.env.NODE_ENV || "development"}`);
12
+ });
13
+
14
+ /**
15
+ * GRACEFUL SHUTDOWN LOGIC
16
+ * Ensures the server closes existing connections before exiting.
17
+ */
18
+ const shutdown = (signal: string) => {
19
+ logger.info(`${signal} received. Starting graceful shutdown...`);
20
+
21
+ server.close(() => {
22
+ logger.info("⛔ HTTP server closed.");
23
+
24
+ // Close database connections here (e.g., prisma.$disconnect() or mongoose.connection.close())
25
+
26
+ process.exit(0);
27
+ });
28
+
29
+ // Force close after 10 seconds if graceful shutdown fails
30
+ setTimeout(() => {
31
+ logger.error(
32
+ "Could not close connections in time, forcefully shutting down",
33
+ );
34
+ process.exit(1);
35
+ }, 10000);
36
+ };
37
+
38
+ // Listen for termination signals
39
+ process.on("SIGTERM", () => shutdown("SIGTERM"));
40
+ process.on("SIGINT", () => shutdown("SIGINT"));
41
+
42
+ /**
43
+ * UNHANDLED REJECTION/EXCEPTION CATCHING
44
+ * Prevents the process from crashing silently.
45
+ */
46
+ process.on("unhandledRejection", (reason, promise) => {
47
+ logger.fatal({ promise, reason }, "Unhandled Rejection at Promise");
48
+ throw reason; // Let uncaughtException handle it
49
+ });
50
+
51
+ process.on("uncaughtException", (error) => {
52
+ logger.fatal(error, "Uncaught Exception thrown");
53
+ process.exit(1);
54
+ });
@@ -0,0 +1,21 @@
1
+ import pino from "pino";
2
+
3
+ import { env } from "../config/env.js";
4
+
5
+ const isProduction = process.env.NODE_ENV === "production";
6
+
7
+ export const logger = pino({
8
+ level: env.logLevel,
9
+ // Redact sensitive data from logs for security
10
+ redact: ["req.headers.authorization", "password", "confirmPassword"],
11
+ transport: isProduction
12
+ ? undefined // In production, output raw JSON for Datadog/ELK
13
+ : {
14
+ target: "pino-pretty",
15
+ options: {
16
+ colorize: true,
17
+ translateTime: "SYS:standard",
18
+ ignore: "pid,hostname",
19
+ },
20
+ },
21
+ });
@@ -0,0 +1,30 @@
1
+ {
2
+ "compilerOptions": {
3
+ /* Language & runtime */
4
+ "target": "ES2022",
5
+ "module": "ESNext",
6
+ "moduleResolution": "node",
7
+
8
+ /* Project structure */
9
+ "rootDir": "src",
10
+ "outDir": "dist",
11
+
12
+ /* Interop & correctness */
13
+ "esModuleInterop": true,
14
+ "allowSyntheticDefaultImports": true,
15
+
16
+ /* Safety */
17
+ "strict": true,
18
+ "forceConsistentCasingInFileNames": true,
19
+ "skipLibCheck": true,
20
+ "noEmitOnError": true,
21
+
22
+ /* DX & production debugging */
23
+ "sourceMap": true,
24
+
25
+ /* Node environment */
26
+ "types": ["node", "vitest/globals"]
27
+ },
28
+ "include": ["src"],
29
+ "exclude": ["node_modules", "dist", "__tests__"]
30
+ }
@@ -0,0 +1,15 @@
1
+ import { defineConfig } from "vitest/config";
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ environment: "node",
6
+ globals: true,
7
+ clearMocks: true,
8
+ restoreMocks: true,
9
+ coverage: {
10
+ provider: "v8",
11
+ reporter: ["text", "html"],
12
+ exclude: ["dist", "node_modules"],
13
+ },
14
+ },
15
+ });
@@ -0,0 +1,107 @@
1
+ # Backend Express — Reference Template (ATS 1.0)
2
+
3
+ **Template ID:** backend.backend-express.basic
4
+ **Status:** Reference Template
5
+ **ATS Version:** 1.0
6
+ **Purpose:** Canonical backend baseline for AppInit OS
7
+
8
+ ---
9
+
10
+ ## What This Template Is
11
+
12
+ This template is the **reference backend implementation** for ATS 1.0.
13
+
14
+ It demonstrates:
15
+
16
+ - correct ATS 1.0 structure
17
+ - deterministic rendering
18
+ - proper variable defaults
19
+ - correct Doctor interaction
20
+ - clean author vs user separation
21
+
22
+ All future backend templates **must align with this structure unless explicitly justified**.
23
+
24
+ ---
25
+
26
+ ## Scope (LOCKED)
27
+
28
+ Included:
29
+
30
+ - Node.js runtime
31
+ - Express
32
+ - TypeScript
33
+ - Minimal production-ready structure
34
+ - Deterministic configuration
35
+ - Tests
36
+ - Linting and formatting
37
+
38
+ Explicitly NOT included:
39
+
40
+ - Authentication
41
+ - Databases / ORM
42
+ - Docker orchestration
43
+ - Deployment presets
44
+ - Cloud configuration
45
+ - Monorepo support
46
+
47
+ If you need these features, use this template as a base and extend externally.
48
+
49
+ ---
50
+
51
+ ## ATS Guarantees
52
+
53
+ This template guarantees:
54
+
55
+ - `appinit template generate` runs with **no prompts**
56
+ - defaults are sufficient and deterministic
57
+ - output of `template generate` matches `appinit create`
58
+ - no runtime execution during authoring
59
+ - no SDK internals leakage
60
+
61
+ If any of these guarantees break, the template is considered invalid.
62
+
63
+ ---
64
+
65
+ ## Doctor Interaction
66
+
67
+ - Doctor runs in **strict** mode during `template generate`
68
+ - Doctor runs in **advisory** mode during `template dev`
69
+ - Doctor never mutates output
70
+
71
+ Doctor warnings should be treated as **author guidance**, not failures.
72
+
73
+ ---
74
+
75
+ ## Why This Template Exists
76
+
77
+ This template exists to:
78
+
79
+ - calibrate ATS 1.0 behavior
80
+ - serve as a structural reference
81
+ - reduce ambiguity for template authors
82
+ - provide a stable baseline for backend projects
83
+
84
+ This is a **boring template by design**.
85
+
86
+ ---
87
+
88
+ ## ⚙️ Template Engine
89
+
90
+ The rendering engine is defined in **`template.config.ts`**, not dynamically.
91
+
92
+ ### Engine: `liquid`
93
+
94
+ When `engine: "liquid"` is used:
95
+
96
+ - LiquidJS syntax is available
97
+ - Supports interpolation, conditionals, loops, filters
98
+
99
+ Examples:
100
+
101
+ ```liquid
102
+ {{ projectName }}
103
+
104
+ {% if useTypeScript %}
105
+ // TypeScript-only code
106
+ {% endif %}
107
+ ```
@@ -0,0 +1,25 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "id": "backend.backend-express.basic",
4
+ "version": "0.1.0",
5
+ "kind": "project",
6
+ "atsVersion": "1.0",
7
+ "name": "Express Backend",
8
+ "description": "TypeScript backend starter using Express.",
9
+ "category": "backend",
10
+ "language": "typescript",
11
+ "packageName": "@appinit/template-backend-express",
12
+ "renderer": {
13
+ "engine": "liquid"
14
+ },
15
+ "paths": {
16
+ "template": "template",
17
+ "variables": "variables"
18
+ },
19
+ "tags": [
20
+ "backend",
21
+ "api",
22
+ "express",
23
+ "typescript"
24
+ ]
25
+ }
@@ -0,0 +1,11 @@
1
+ # backend-express Template
2
+
3
+ This is a **backend AppInit template**.
4
+
5
+ ## What you should add
6
+ - Files inside /template
7
+ - Variables in /variables
8
+ - Optional hooks in /hooks
9
+
10
+ This scaffold does NOT include framework code.
11
+ You are expected to add it.
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "@appinit/template-backend-express",
3
+ "private": true,
4
+ "version": "0.1.0"
5
+ }
@@ -0,0 +1,4 @@
1
+ NODE_ENV=development
2
+ PORT=3001
3
+ LOG_LEVEL=debug
4
+ CORS_ORIGIN=*
@@ -0,0 +1 @@
1
+ npx lint-staged
@@ -0,0 +1,3 @@
1
+ # Ignore artifacts:
2
+ build
3
+ coverage
@@ -0,0 +1,28 @@
1
+ {
2
+ "arrowParens": "always",
3
+ "bracketSameLine": false,
4
+ "objectWrap": "preserve",
5
+ "bracketSpacing": true,
6
+ "semi": true,
7
+ "experimentalOperatorPosition": "end",
8
+ "experimentalTernaries": false,
9
+ "singleQuote": false,
10
+ "jsxSingleQuote": false,
11
+ "quoteProps": "as-needed",
12
+ "trailingComma": "all",
13
+ "singleAttributePerLine": false,
14
+ "htmlWhitespaceSensitivity": "css",
15
+ "vueIndentScriptAndStyle": false,
16
+ "proseWrap": "preserve",
17
+ "endOfLine": "lf",
18
+ "insertPragma": false,
19
+ "printWidth": 80,
20
+ "requirePragma": false,
21
+ "tabWidth": 2,
22
+ "useTabs": false,
23
+ "embeddedLanguageFormatting": "auto",
24
+ "importOrder": ["^@core/(.*)$", "^@server/(.*)$", "^@ui/(.*)$", "^[./]"],
25
+ "importOrderSeparation": true,
26
+ "importOrderSortSpecifiers": true,
27
+ "plugins": ["@trivago/prettier-plugin-sort-imports"]
28
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "editor.formatOnSave": true,
3
+ "editor.defaultFormatter": "esbenp.prettier-vscode",
4
+ "eslint.format.enable": false,
5
+ "prettier.requireConfig": true
6
+ }
@@ -0,0 +1,14 @@
1
+ FROM node:20-alpine AS builder
2
+ WORKDIR /app
3
+ COPY package*.json ./
4
+ RUN npm ci
5
+ COPY . .
6
+ RUN npm run build
7
+
8
+ FROM node:20-alpine
9
+ WORKDIR /app
10
+ ENV NODE_ENV=production
11
+ COPY --from=builder /app/dist ./dist
12
+ COPY --from=builder /app/node_modules ./node_modules
13
+ EXPOSE 3001
14
+ CMD ["node", "dist/server.js"]
@@ -0,0 +1,26 @@
1
+ # ⚛️ backend-express
2
+
3
+ This project was generated using **AppInit 1.0**.
4
+
5
+ ## 🚀 Quick Start
6
+
7
+ ```bash
8
+ pnpm install
9
+ pnpm dev
10
+ ```
11
+
12
+ ## 🛠️ Stack Configuration
13
+
14
+ - **Framework**: React 18+ (Vite)
15
+ - **Engine Used**: %%engine%%
16
+ - **Generated At**: %%timestamp%%
17
+
18
+ ## 📂 Project Structure
19
+
20
+ - `src/`: Your React components and logic.
21
+ - `public/`: Static assets (images, icons).
22
+ - `tailwind.config.js`: Styling configuration.
23
+
24
+ ---
25
+
26
+ _Built with speed using the AppInit Scaffolding Engine._
@@ -0,0 +1,76 @@
1
+ import js from "@eslint/js";
2
+ import tsPlugin from "@typescript-eslint/eslint-plugin";
3
+ import tsParser from "@typescript-eslint/parser";
4
+ import prettier from "eslint-config-prettier";
5
+
6
+ export default [
7
+ // ─────────────────────────────────────────────
8
+ // Global ignores (ESLint v9 way)
9
+ // ─────────────────────────────────────────────
10
+ {
11
+ ignores: ["dist/**", "node_modules/**", "coverage/**"],
12
+ },
13
+
14
+ // ─────────────────────────────────────────────
15
+ // Base JS rules
16
+ // ─────────────────────────────────────────────
17
+ js.configs.recommended,
18
+
19
+ // ─────────────────────────────────────────────
20
+ // TypeScript (Node backend)
21
+ // ─────────────────────────────────────────────
22
+ {
23
+ files: ["src/**/*.ts"],
24
+ languageOptions: {
25
+ parser: tsParser,
26
+ parserOptions: {
27
+ project: "./tsconfig.json",
28
+ sourceType: "module",
29
+ },
30
+ globals: {
31
+ process: "readonly",
32
+ console: "readonly",
33
+ setTimeout: "readonly",
34
+ clearTimeout: "readonly",
35
+ },
36
+ },
37
+ plugins: {
38
+ "@typescript-eslint": tsPlugin,
39
+ },
40
+ rules: {
41
+ /* Disable base JS rules */
42
+ "no-undef": "off",
43
+ "no-unused-vars": "off",
44
+
45
+ /* TypeScript correctness */
46
+ "@typescript-eslint/no-unused-vars": [
47
+ "warn",
48
+ { argsIgnorePattern: "^_" },
49
+ ],
50
+ "@typescript-eslint/no-floating-promises": "error",
51
+ "@typescript-eslint/no-misused-promises": "error",
52
+
53
+ /* Production discipline */
54
+ "no-console": "error",
55
+ "no-debugger": "error",
56
+
57
+ /* Reality */
58
+ "@typescript-eslint/no-explicit-any": "off",
59
+ },
60
+ },
61
+
62
+ // ─────────────────────────────────────────────
63
+ // Allow console ONLY in env bootstrap
64
+ // ─────────────────────────────────────────────
65
+ {
66
+ files: ["src/config/env.ts"],
67
+ rules: {
68
+ "no-console": "off",
69
+ },
70
+ },
71
+
72
+ // ─────────────────────────────────────────────
73
+ // Disable formatting rules (Prettier owns formatting)
74
+ // ─────────────────────────────────────────────
75
+ prettier,
76
+ ];
@@ -0,0 +1,8 @@
1
+ {
2
+ "watch": ["src"],
3
+ "ext": "ts",
4
+ "ignore": ["dist", "node_modules"],
5
+ "exec": "tsx src/server.ts",
6
+ "signal": "SIGTERM",
7
+ "delay": "100"
8
+ }
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "{{ projectName }}",
3
+ "description": "{{ description | default: 'Backend API built with AppInit' }}",
4
+ "author": "{{ author }}",
5
+ "license": "{{ licenseType }}",
6
+ "version": "0.0.0",
7
+ "private": true,
8
+ "type": "module",
9
+ "scripts": {
10
+ "dev": "nodemon",
11
+ "clean": "rimraf dist",
12
+ "build": "npm run clean && tsc",
13
+ "start": "node dist/server.js",
14
+ "format": "prettier --write .",
15
+ "format:check": "prettier --check .",
16
+ "typecheck": "tsc --noEmit",
17
+ "lint": "eslint .",
18
+ "lint:fix": "eslint . --fix",
19
+ "test": "vitest",
20
+ "test:run": "vitest run",
21
+ "test:watch": "vitest watch",
22
+ "test:coverage": "vitest run --coverage",
23
+ "prepare": "husky"
24
+ },
25
+ "lint-staged": {
26
+ "**/*": "prettier --write --ignore-unknown"
27
+ },
28
+ "main": "index.js",
29
+ "keywords": [],
30
+ "dependencies": {
31
+ "compression": "^1.8.1",
32
+ "cors": "^2.8.5",
33
+ "dotenv": "^17.2.3",
34
+ "express": "^5.2.1",
35
+ "helmet": "^8.1.0",
36
+ "http-errors": "^2.0.1",
37
+ "pino": "^10.1.0",
38
+ "pino-http": "^11.0.0",
39
+ "uuid": "^13.0.0",
40
+ "zod": "^4.2.1"
41
+ },
42
+ "devDependencies": {
43
+ "@trivago/prettier-plugin-sort-imports": "^6.0.0",
44
+ "@types/compression": "^1.8.1",
45
+ "@types/cors": "^2.8.19",
46
+ "@types/express": "^5.0.6",
47
+ "@types/morgan": "^1.9.10",
48
+ "@types/node": "^25.0.2",
49
+ "@types/supertest": "^6.0.3",
50
+ "@typescript-eslint/eslint-plugin": "^8.50.0",
51
+ "@typescript-eslint/parser": "^8.50.0",
52
+ "eslint": "^9.39.2",
53
+ "eslint-config-prettier": "^10.1.8",
54
+ "husky": "^9.1.7",
55
+ "lint-staged": "^16.2.7",
56
+ "morgan": "^1.10.1",
57
+ "nodemon": "^3.1.11",
58
+ "pino-pretty": "^13.1.3",
59
+ "prettier": "3.7.4",
60
+ "rimraf": "^6.1.2",
61
+ "supertest": "^7.1.4",
62
+ "tsx": "^4.21.0",
63
+ "typescript": "^5.9.3",
64
+ "vitest": "^4.0.16"
65
+ },
66
+ "engines": {
67
+ "node": ">=18"
68
+ }
69
+ }