@imksh/create 1.0.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 (441) hide show
  1. package/README.md +88 -0
  2. package/bin/index.js +3 -0
  3. package/package.json +43 -0
  4. package/src/commands/create.js +90 -0
  5. package/src/index.js +41 -0
  6. package/src/utils/askTemplate.js +25 -0
  7. package/src/utils/copyTemplate.js +36 -0
  8. package/src/utils/installPackages.js +25 -0
  9. package/src/utils/logger.js +17 -0
  10. package/src/utils/runGit.js +11 -0
  11. package/templates/mern/_gitignore +2 -0
  12. package/templates/mern/client/_gitignore +24 -0
  13. package/templates/mern/client/index.html +14 -0
  14. package/templates/mern/client/package.json +39 -0
  15. package/templates/mern/client/public/_redirects +1 -0
  16. package/templates/mern/client/public/favicon.ico +0 -0
  17. package/templates/mern/client/public/favicon.svg +1 -0
  18. package/templates/mern/client/public/logo.png +0 -0
  19. package/templates/mern/client/public/manifest.json +24 -0
  20. package/templates/mern/client/public/sw.js +56 -0
  21. package/templates/mern/client/src/App.jsx +68 -0
  22. package/templates/mern/client/src/assets/animations/loading.json +1 -0
  23. package/templates/mern/client/src/assets/data/navigation.js +29 -0
  24. package/templates/mern/client/src/assets/images/logo.png +0 -0
  25. package/templates/mern/client/src/components/common/Breadcrumbs.jsx +27 -0
  26. package/templates/mern/client/src/components/common/Loading.jsx +19 -0
  27. package/templates/mern/client/src/components/common/LottieIcon.jsx +36 -0
  28. package/templates/mern/client/src/components/common/NotFound.jsx +78 -0
  29. package/templates/mern/client/src/components/common/PwaInstallPrompt.jsx +72 -0
  30. package/templates/mern/client/src/components/common/SEO.jsx +67 -0
  31. package/templates/mern/client/src/components/common/Scroll.jsx +25 -0
  32. package/templates/mern/client/src/components/common/Table.jsx +110 -0
  33. package/templates/mern/client/src/components/common/ToggleSwitch.jsx +38 -0
  34. package/templates/mern/client/src/components/common/Unauthorized.jsx +76 -0
  35. package/templates/mern/client/src/components/layout/ProtectedRoute.jsx +17 -0
  36. package/templates/mern/client/src/components/layout/PublicLayout.jsx +13 -0
  37. package/templates/mern/client/src/components/layout/SidebarLayout.jsx +37 -0
  38. package/templates/mern/client/src/components/modals/ConfirmModal.jsx +135 -0
  39. package/templates/mern/client/src/components/modals/Modal.jsx +94 -0
  40. package/templates/mern/client/src/components/skeletons/common/CardSkeleton.jsx +23 -0
  41. package/templates/mern/client/src/components/skeletons/common/DashboardSkeleton.jsx +19 -0
  42. package/templates/mern/client/src/components/skeletons/common/ListSkeleton.jsx +24 -0
  43. package/templates/mern/client/src/components/skeletons/common/PageSkeleton.jsx +26 -0
  44. package/templates/mern/client/src/components/skeletons/common/ProfileSkeleton.jsx +23 -0
  45. package/templates/mern/client/src/components/skeletons/common/Skeleton.jsx +18 -0
  46. package/templates/mern/client/src/components/skeletons/common/TableSkeleton.jsx +33 -0
  47. package/templates/mern/client/src/components/ui/Header.jsx +230 -0
  48. package/templates/mern/client/src/components/ui/SidebarHeader.jsx +27 -0
  49. package/templates/mern/client/src/components/ui/sidebar.jsx +152 -0
  50. package/templates/mern/client/src/config/api.js +22 -0
  51. package/templates/mern/client/src/config/appConfig.js +44 -0
  52. package/templates/mern/client/src/config/navigation.js +14 -0
  53. package/templates/mern/client/src/hooks/useLenis.js +28 -0
  54. package/templates/mern/client/src/hooks/usePwaInstall.js +45 -0
  55. package/templates/mern/client/src/hooks/useWindowSize.js +25 -0
  56. package/templates/mern/client/src/index.css +158 -0
  57. package/templates/mern/client/src/main.jsx +24 -0
  58. package/templates/mern/client/src/pages/Home.jsx +154 -0
  59. package/templates/mern/client/src/pages/Login.jsx +196 -0
  60. package/templates/mern/client/src/pages/Profile.jsx +9 -0
  61. package/templates/mern/client/src/services/authService.js +16 -0
  62. package/templates/mern/client/src/store/useAuthStore.js +98 -0
  63. package/templates/mern/client/src/store/useUiStore.js +54 -0
  64. package/templates/mern/client/src/utils/getInitials.js +10 -0
  65. package/templates/mern/client/vite.config.js +8 -0
  66. package/templates/mern/package.json +18 -0
  67. package/templates/mern/server/.env.example +62 -0
  68. package/templates/mern/server/README.md +65 -0
  69. package/templates/mern/server/_gitignore +24 -0
  70. package/templates/mern/server/package.json +32 -0
  71. package/templates/mern/server/src/app.js +42 -0
  72. package/templates/mern/server/src/config/cloudinary.js +9 -0
  73. package/templates/mern/server/src/config/db.js +14 -0
  74. package/templates/mern/server/src/config/dotenv.js +2 -0
  75. package/templates/mern/server/src/config/email.js +30 -0
  76. package/templates/mern/server/src/config/socket.js +54 -0
  77. package/templates/mern/server/src/config/webPush.js +9 -0
  78. package/templates/mern/server/src/controllers/auth.controller.js +153 -0
  79. package/templates/mern/server/src/controllers/upload.controller.js +26 -0
  80. package/templates/mern/server/src/index.js +24 -0
  81. package/templates/mern/server/src/middleware/auth.middleware.js +43 -0
  82. package/templates/mern/server/src/middleware/errorHandler.js +22 -0
  83. package/templates/mern/server/src/middleware/multer.js +21 -0
  84. package/templates/mern/server/src/middleware/rateLimiter.js +57 -0
  85. package/templates/mern/server/src/models/otp.model.js +21 -0
  86. package/templates/mern/server/src/models/pushSubscription.model.js +32 -0
  87. package/templates/mern/server/src/models/user.model.js +43 -0
  88. package/templates/mern/server/src/routes/auth.route.js +22 -0
  89. package/templates/mern/server/src/routes/index.js +10 -0
  90. package/templates/mern/server/src/routes/upload.route.js +12 -0
  91. package/templates/mern/server/src/services/auth.service.js +162 -0
  92. package/templates/mern/server/src/services/auth.service.ts +0 -0
  93. package/templates/mern/server/src/utils/authToken.js +26 -0
  94. package/templates/mern/server/src/utils/cloudinary.js +27 -0
  95. package/templates/mern/server/src/utils/cloudinaryUpload.js +87 -0
  96. package/templates/mern/server/src/utils/emailOtp.js +190 -0
  97. package/templates/mern/server/src/utils/genOtpToken.js +20 -0
  98. package/templates/mern/server/src/utils/generateVapidKeys.js +12 -0
  99. package/templates/mern/server/src/utils/jwt.js +25 -0
  100. package/templates/mern/server/src/utils/logger.js +25 -0
  101. package/templates/mern-ts/_gitignore +2 -0
  102. package/templates/mern-ts/client/_gitignore +24 -0
  103. package/templates/mern-ts/client/index.html +14 -0
  104. package/templates/mern-ts/client/package.json +45 -0
  105. package/templates/mern-ts/client/public/_redirects +1 -0
  106. package/templates/mern-ts/client/public/favicon.ico +0 -0
  107. package/templates/mern-ts/client/public/favicon.svg +1 -0
  108. package/templates/mern-ts/client/public/logo.png +0 -0
  109. package/templates/mern-ts/client/public/manifest.json +24 -0
  110. package/templates/mern-ts/client/public/sw.js +56 -0
  111. package/templates/mern-ts/client/src/App.tsx +68 -0
  112. package/templates/mern-ts/client/src/assets/animations/loading.json +1 -0
  113. package/templates/mern-ts/client/src/assets/data/navigation.ts +29 -0
  114. package/templates/mern-ts/client/src/assets/images/logo.png +0 -0
  115. package/templates/mern-ts/client/src/components/common/Breadcrumbs.tsx +27 -0
  116. package/templates/mern-ts/client/src/components/common/Loading.tsx +19 -0
  117. package/templates/mern-ts/client/src/components/common/LottieIcon.tsx +36 -0
  118. package/templates/mern-ts/client/src/components/common/NotFound.tsx +78 -0
  119. package/templates/mern-ts/client/src/components/common/PwaInstallPrompt.tsx +72 -0
  120. package/templates/mern-ts/client/src/components/common/SEO.tsx +67 -0
  121. package/templates/mern-ts/client/src/components/common/Scroll.tsx +25 -0
  122. package/templates/mern-ts/client/src/components/common/Table.tsx +118 -0
  123. package/templates/mern-ts/client/src/components/common/ToggleSwitch.tsx +38 -0
  124. package/templates/mern-ts/client/src/components/common/Unauthorized.tsx +76 -0
  125. package/templates/mern-ts/client/src/components/layout/ProtectedRoute.tsx +23 -0
  126. package/templates/mern-ts/client/src/components/layout/PublicLayout.tsx +13 -0
  127. package/templates/mern-ts/client/src/components/layout/SidebarLayout.tsx +37 -0
  128. package/templates/mern-ts/client/src/components/modals/ConfirmModal.tsx +135 -0
  129. package/templates/mern-ts/client/src/components/modals/Modal.tsx +94 -0
  130. package/templates/mern-ts/client/src/components/skeletons/common/CardSkeleton.tsx +23 -0
  131. package/templates/mern-ts/client/src/components/skeletons/common/DashboardSkeleton.tsx +19 -0
  132. package/templates/mern-ts/client/src/components/skeletons/common/ListSkeleton.tsx +24 -0
  133. package/templates/mern-ts/client/src/components/skeletons/common/PageSkeleton.tsx +26 -0
  134. package/templates/mern-ts/client/src/components/skeletons/common/ProfileSkeleton.tsx +23 -0
  135. package/templates/mern-ts/client/src/components/skeletons/common/Skeleton.tsx +18 -0
  136. package/templates/mern-ts/client/src/components/skeletons/common/TableSkeleton.tsx +33 -0
  137. package/templates/mern-ts/client/src/components/ui/Header.tsx +230 -0
  138. package/templates/mern-ts/client/src/components/ui/SidebarHeader.tsx +27 -0
  139. package/templates/mern-ts/client/src/components/ui/sidebar.tsx +152 -0
  140. package/templates/mern-ts/client/src/config/api.ts +22 -0
  141. package/templates/mern-ts/client/src/config/appConfig.ts +44 -0
  142. package/templates/mern-ts/client/src/config/navigation.ts +14 -0
  143. package/templates/mern-ts/client/src/hooks/useLenis.ts +28 -0
  144. package/templates/mern-ts/client/src/hooks/usePwaInstall.ts +45 -0
  145. package/templates/mern-ts/client/src/hooks/useWindowSize.ts +25 -0
  146. package/templates/mern-ts/client/src/index.css +158 -0
  147. package/templates/mern-ts/client/src/main.tsx +24 -0
  148. package/templates/mern-ts/client/src/pages/Home.tsx +154 -0
  149. package/templates/mern-ts/client/src/pages/Login.tsx +196 -0
  150. package/templates/mern-ts/client/src/pages/Profile.tsx +9 -0
  151. package/templates/mern-ts/client/src/services/authService.ts +16 -0
  152. package/templates/mern-ts/client/src/store/useAuthStore.ts +98 -0
  153. package/templates/mern-ts/client/src/store/useUiStore.ts +54 -0
  154. package/templates/mern-ts/client/src/utils/getInitials.ts +10 -0
  155. package/templates/mern-ts/client/tsconfig.json +25 -0
  156. package/templates/mern-ts/client/tsconfig.node.json +10 -0
  157. package/templates/mern-ts/client/vite.config.ts +8 -0
  158. package/templates/mern-ts/package.json +19 -0
  159. package/templates/mern-ts/server/.env.example +62 -0
  160. package/templates/mern-ts/server/README.md +69 -0
  161. package/templates/mern-ts/server/_gitignore +24 -0
  162. package/templates/mern-ts/server/package.json +47 -0
  163. package/templates/mern-ts/server/src/app.ts +36 -0
  164. package/templates/mern-ts/server/src/config/cloudinary.ts +9 -0
  165. package/templates/mern-ts/server/src/config/db.ts +15 -0
  166. package/templates/mern-ts/server/src/config/dotenv.ts +2 -0
  167. package/templates/mern-ts/server/src/config/email.ts +28 -0
  168. package/templates/mern-ts/server/src/config/socket.ts +54 -0
  169. package/templates/mern-ts/server/src/config/webPush.ts +9 -0
  170. package/templates/mern-ts/server/src/controllers/auth.controller.ts +126 -0
  171. package/templates/mern-ts/server/src/controllers/upload.controller.ts +22 -0
  172. package/templates/mern-ts/server/src/index.ts +17 -0
  173. package/templates/mern-ts/server/src/middleware/auth.middleware.ts +38 -0
  174. package/templates/mern-ts/server/src/middleware/errorHandler.ts +16 -0
  175. package/templates/mern-ts/server/src/middleware/multer.ts +20 -0
  176. package/templates/mern-ts/server/src/middleware/rateLimiter.ts +53 -0
  177. package/templates/mern-ts/server/src/models/otp.model.ts +21 -0
  178. package/templates/mern-ts/server/src/models/pushSubscription.model.ts +32 -0
  179. package/templates/mern-ts/server/src/models/user.model.ts +43 -0
  180. package/templates/mern-ts/server/src/routes/auth.route.ts +22 -0
  181. package/templates/mern-ts/server/src/routes/index.ts +10 -0
  182. package/templates/mern-ts/server/src/routes/upload.route.ts +11 -0
  183. package/templates/mern-ts/server/src/services/auth.service.ts +115 -0
  184. package/templates/mern-ts/server/src/types/express.d.ts +10 -0
  185. package/templates/mern-ts/server/src/utils/cloudinaryUpload.ts +44 -0
  186. package/templates/mern-ts/server/src/utils/emailOtp.ts +30 -0
  187. package/templates/mern-ts/server/src/utils/genOtpToken.ts +22 -0
  188. package/templates/mern-ts/server/src/utils/generateVapidKeys.ts +12 -0
  189. package/templates/mern-ts/server/src/utils/jwt.ts +27 -0
  190. package/templates/mern-ts/server/src/utils/logger.ts +27 -0
  191. package/templates/mern-ts/server/tsconfig.json +14 -0
  192. package/templates/next/_gitignore +24 -0
  193. package/templates/next/package.json +20 -0
  194. package/templates/next/src/app/layout.js +7 -0
  195. package/templates/next/src/app/page.js +218 -0
  196. package/templates/next-ts/_gitignore +24 -0
  197. package/templates/next-ts/package.json +24 -0
  198. package/templates/next-ts/src/app/layout.tsx +9 -0
  199. package/templates/next-ts/src/app/page.tsx +218 -0
  200. package/templates/next-ts/tsconfig.json +27 -0
  201. package/templates/node/.env.example +62 -0
  202. package/templates/node/README.md +65 -0
  203. package/templates/node/_gitignore +24 -0
  204. package/templates/node/package.json +32 -0
  205. package/templates/node/src/app.js +42 -0
  206. package/templates/node/src/config/cloudinary.js +9 -0
  207. package/templates/node/src/config/db.js +14 -0
  208. package/templates/node/src/config/dotenv.js +2 -0
  209. package/templates/node/src/config/email.js +30 -0
  210. package/templates/node/src/config/socket.js +54 -0
  211. package/templates/node/src/config/webPush.js +9 -0
  212. package/templates/node/src/controllers/auth.controller.js +153 -0
  213. package/templates/node/src/controllers/upload.controller.js +26 -0
  214. package/templates/node/src/index.js +24 -0
  215. package/templates/node/src/middleware/auth.middleware.js +43 -0
  216. package/templates/node/src/middleware/errorHandler.js +22 -0
  217. package/templates/node/src/middleware/multer.js +21 -0
  218. package/templates/node/src/middleware/rateLimiter.js +57 -0
  219. package/templates/node/src/models/otp.model.js +21 -0
  220. package/templates/node/src/models/pushSubscription.model.js +32 -0
  221. package/templates/node/src/models/user.model.js +43 -0
  222. package/templates/node/src/routes/auth.route.js +22 -0
  223. package/templates/node/src/routes/index.js +10 -0
  224. package/templates/node/src/routes/upload.route.js +12 -0
  225. package/templates/node/src/services/auth.service.js +162 -0
  226. package/templates/node/src/services/auth.service.ts +0 -0
  227. package/templates/node/src/utils/authToken.js +26 -0
  228. package/templates/node/src/utils/cloudinary.js +27 -0
  229. package/templates/node/src/utils/cloudinaryUpload.js +87 -0
  230. package/templates/node/src/utils/emailOtp.js +190 -0
  231. package/templates/node/src/utils/genOtpToken.js +20 -0
  232. package/templates/node/src/utils/generateVapidKeys.js +12 -0
  233. package/templates/node/src/utils/jwt.js +25 -0
  234. package/templates/node/src/utils/logger.js +25 -0
  235. package/templates/node-prisma/.env.example +63 -0
  236. package/templates/node-prisma/README.md +69 -0
  237. package/templates/node-prisma/_gitignore +24 -0
  238. package/templates/node-prisma/package.json +35 -0
  239. package/templates/node-prisma/prisma/schema.prisma +41 -0
  240. package/templates/node-prisma/src/app.js +42 -0
  241. package/templates/node-prisma/src/config/cloudinary.js +9 -0
  242. package/templates/node-prisma/src/config/db.js +16 -0
  243. package/templates/node-prisma/src/config/dotenv.js +2 -0
  244. package/templates/node-prisma/src/config/email.js +30 -0
  245. package/templates/node-prisma/src/config/socket.js +54 -0
  246. package/templates/node-prisma/src/config/webPush.js +9 -0
  247. package/templates/node-prisma/src/controllers/auth.controller.js +146 -0
  248. package/templates/node-prisma/src/controllers/upload.controller.js +26 -0
  249. package/templates/node-prisma/src/index.js +24 -0
  250. package/templates/node-prisma/src/middleware/auth.middleware.js +44 -0
  251. package/templates/node-prisma/src/middleware/errorHandler.js +22 -0
  252. package/templates/node-prisma/src/middleware/multer.js +21 -0
  253. package/templates/node-prisma/src/middleware/rateLimiter.js +57 -0
  254. package/templates/node-prisma/src/routes/auth.route.js +22 -0
  255. package/templates/node-prisma/src/routes/index.js +10 -0
  256. package/templates/node-prisma/src/routes/upload.route.js +12 -0
  257. package/templates/node-prisma/src/services/auth.service.js +163 -0
  258. package/templates/node-prisma/src/services/auth.service.ts +0 -0
  259. package/templates/node-prisma/src/utils/authToken.js +26 -0
  260. package/templates/node-prisma/src/utils/cloudinary.js +27 -0
  261. package/templates/node-prisma/src/utils/cloudinaryUpload.js +87 -0
  262. package/templates/node-prisma/src/utils/emailOtp.js +190 -0
  263. package/templates/node-prisma/src/utils/genOtpToken.js +20 -0
  264. package/templates/node-prisma/src/utils/generateVapidKeys.js +12 -0
  265. package/templates/node-prisma/src/utils/jwt.js +25 -0
  266. package/templates/node-prisma/src/utils/logger.js +25 -0
  267. package/templates/node-prisma-ts/.env.example +63 -0
  268. package/templates/node-prisma-ts/README.md +73 -0
  269. package/templates/node-prisma-ts/_gitignore +24 -0
  270. package/templates/node-prisma-ts/package.json +48 -0
  271. package/templates/node-prisma-ts/prisma/schema.prisma +41 -0
  272. package/templates/node-prisma-ts/src/app.ts +36 -0
  273. package/templates/node-prisma-ts/src/config/cloudinary.ts +9 -0
  274. package/templates/node-prisma-ts/src/config/db.ts +16 -0
  275. package/templates/node-prisma-ts/src/config/dotenv.ts +2 -0
  276. package/templates/node-prisma-ts/src/config/email.ts +28 -0
  277. package/templates/node-prisma-ts/src/config/socket.ts +54 -0
  278. package/templates/node-prisma-ts/src/config/webPush.ts +9 -0
  279. package/templates/node-prisma-ts/src/controllers/auth.controller.ts +124 -0
  280. package/templates/node-prisma-ts/src/controllers/upload.controller.ts +22 -0
  281. package/templates/node-prisma-ts/src/index.ts +17 -0
  282. package/templates/node-prisma-ts/src/middleware/auth.middleware.ts +45 -0
  283. package/templates/node-prisma-ts/src/middleware/errorHandler.ts +16 -0
  284. package/templates/node-prisma-ts/src/middleware/multer.ts +20 -0
  285. package/templates/node-prisma-ts/src/middleware/rateLimiter.ts +53 -0
  286. package/templates/node-prisma-ts/src/routes/auth.route.ts +22 -0
  287. package/templates/node-prisma-ts/src/routes/index.ts +10 -0
  288. package/templates/node-prisma-ts/src/routes/upload.route.ts +11 -0
  289. package/templates/node-prisma-ts/src/services/auth.service.ts +163 -0
  290. package/templates/node-prisma-ts/src/types/express.d.ts +10 -0
  291. package/templates/node-prisma-ts/src/utils/cloudinaryUpload.ts +44 -0
  292. package/templates/node-prisma-ts/src/utils/emailOtp.ts +30 -0
  293. package/templates/node-prisma-ts/src/utils/genOtpToken.ts +22 -0
  294. package/templates/node-prisma-ts/src/utils/generateVapidKeys.ts +12 -0
  295. package/templates/node-prisma-ts/src/utils/jwt.ts +27 -0
  296. package/templates/node-prisma-ts/src/utils/logger.ts +27 -0
  297. package/templates/node-prisma-ts/tsconfig.json +14 -0
  298. package/templates/node-ts/.env.example +62 -0
  299. package/templates/node-ts/README.md +69 -0
  300. package/templates/node-ts/_gitignore +24 -0
  301. package/templates/node-ts/package.json +47 -0
  302. package/templates/node-ts/src/app.ts +36 -0
  303. package/templates/node-ts/src/config/cloudinary.ts +9 -0
  304. package/templates/node-ts/src/config/db.ts +15 -0
  305. package/templates/node-ts/src/config/dotenv.ts +2 -0
  306. package/templates/node-ts/src/config/email.ts +28 -0
  307. package/templates/node-ts/src/config/socket.ts +54 -0
  308. package/templates/node-ts/src/config/webPush.ts +9 -0
  309. package/templates/node-ts/src/controllers/auth.controller.ts +126 -0
  310. package/templates/node-ts/src/controllers/upload.controller.ts +22 -0
  311. package/templates/node-ts/src/index.ts +17 -0
  312. package/templates/node-ts/src/middleware/auth.middleware.ts +38 -0
  313. package/templates/node-ts/src/middleware/errorHandler.ts +16 -0
  314. package/templates/node-ts/src/middleware/multer.ts +20 -0
  315. package/templates/node-ts/src/middleware/rateLimiter.ts +53 -0
  316. package/templates/node-ts/src/models/otp.model.ts +21 -0
  317. package/templates/node-ts/src/models/pushSubscription.model.ts +32 -0
  318. package/templates/node-ts/src/models/user.model.ts +43 -0
  319. package/templates/node-ts/src/routes/auth.route.ts +22 -0
  320. package/templates/node-ts/src/routes/index.ts +10 -0
  321. package/templates/node-ts/src/routes/upload.route.ts +11 -0
  322. package/templates/node-ts/src/services/auth.service.ts +115 -0
  323. package/templates/node-ts/src/types/express.d.ts +10 -0
  324. package/templates/node-ts/src/utils/cloudinaryUpload.ts +44 -0
  325. package/templates/node-ts/src/utils/emailOtp.ts +30 -0
  326. package/templates/node-ts/src/utils/genOtpToken.ts +22 -0
  327. package/templates/node-ts/src/utils/generateVapidKeys.ts +12 -0
  328. package/templates/node-ts/src/utils/jwt.ts +27 -0
  329. package/templates/node-ts/src/utils/logger.ts +27 -0
  330. package/templates/node-ts/tsconfig.json +18 -0
  331. package/templates/react/.env.example +1 -0
  332. package/templates/react/_gitignore +24 -0
  333. package/templates/react/index.html +14 -0
  334. package/templates/react/package.json +39 -0
  335. package/templates/react/public/_redirects +1 -0
  336. package/templates/react/public/favicon.ico +0 -0
  337. package/templates/react/public/favicon.svg +1 -0
  338. package/templates/react/public/logo.png +0 -0
  339. package/templates/react/public/manifest.json +24 -0
  340. package/templates/react/public/sw.js +56 -0
  341. package/templates/react/src/App.jsx +68 -0
  342. package/templates/react/src/assets/animations/loading.json +1 -0
  343. package/templates/react/src/assets/data/navigation.js +29 -0
  344. package/templates/react/src/assets/images/logo.png +0 -0
  345. package/templates/react/src/components/common/Breadcrumbs.jsx +27 -0
  346. package/templates/react/src/components/common/Loading.jsx +19 -0
  347. package/templates/react/src/components/common/LottieIcon.jsx +36 -0
  348. package/templates/react/src/components/common/NotFound.jsx +78 -0
  349. package/templates/react/src/components/common/PwaInstallPrompt.jsx +72 -0
  350. package/templates/react/src/components/common/SEO.jsx +67 -0
  351. package/templates/react/src/components/common/Scroll.jsx +25 -0
  352. package/templates/react/src/components/common/Table.jsx +110 -0
  353. package/templates/react/src/components/common/ToggleSwitch.jsx +38 -0
  354. package/templates/react/src/components/common/Unauthorized.jsx +76 -0
  355. package/templates/react/src/components/layout/ProtectedRoute.jsx +17 -0
  356. package/templates/react/src/components/layout/PublicLayout.jsx +13 -0
  357. package/templates/react/src/components/layout/SidebarLayout.jsx +37 -0
  358. package/templates/react/src/components/modals/ConfirmModal.jsx +135 -0
  359. package/templates/react/src/components/modals/Modal.jsx +94 -0
  360. package/templates/react/src/components/skeletons/common/CardSkeleton.jsx +23 -0
  361. package/templates/react/src/components/skeletons/common/DashboardSkeleton.jsx +19 -0
  362. package/templates/react/src/components/skeletons/common/ListSkeleton.jsx +24 -0
  363. package/templates/react/src/components/skeletons/common/PageSkeleton.jsx +26 -0
  364. package/templates/react/src/components/skeletons/common/ProfileSkeleton.jsx +23 -0
  365. package/templates/react/src/components/skeletons/common/Skeleton.jsx +18 -0
  366. package/templates/react/src/components/skeletons/common/TableSkeleton.jsx +33 -0
  367. package/templates/react/src/components/ui/Header.jsx +230 -0
  368. package/templates/react/src/components/ui/SidebarHeader.jsx +27 -0
  369. package/templates/react/src/components/ui/sidebar.jsx +152 -0
  370. package/templates/react/src/config/api.js +22 -0
  371. package/templates/react/src/config/appConfig.js +44 -0
  372. package/templates/react/src/config/navigation.js +14 -0
  373. package/templates/react/src/hooks/useLenis.js +28 -0
  374. package/templates/react/src/hooks/usePwaInstall.js +45 -0
  375. package/templates/react/src/hooks/useWindowSize.js +25 -0
  376. package/templates/react/src/index.css +158 -0
  377. package/templates/react/src/main.jsx +24 -0
  378. package/templates/react/src/pages/Home.jsx +154 -0
  379. package/templates/react/src/pages/Login.jsx +196 -0
  380. package/templates/react/src/pages/Profile.jsx +9 -0
  381. package/templates/react/src/services/authService.js +16 -0
  382. package/templates/react/src/store/useAuthStore.js +98 -0
  383. package/templates/react/src/store/useUiStore.js +54 -0
  384. package/templates/react/src/utils/getInitials.js +10 -0
  385. package/templates/react/vite.config.js +8 -0
  386. package/templates/react-ts/_gitignore +24 -0
  387. package/templates/react-ts/index.html +14 -0
  388. package/templates/react-ts/package.json +45 -0
  389. package/templates/react-ts/public/_redirects +1 -0
  390. package/templates/react-ts/public/favicon.ico +0 -0
  391. package/templates/react-ts/public/favicon.svg +1 -0
  392. package/templates/react-ts/public/logo.png +0 -0
  393. package/templates/react-ts/public/manifest.json +24 -0
  394. package/templates/react-ts/public/sw.js +56 -0
  395. package/templates/react-ts/src/App.tsx +68 -0
  396. package/templates/react-ts/src/assets/animations/loading.json +1 -0
  397. package/templates/react-ts/src/assets/data/navigation.ts +29 -0
  398. package/templates/react-ts/src/assets/images/logo.png +0 -0
  399. package/templates/react-ts/src/components/common/Breadcrumbs.tsx +27 -0
  400. package/templates/react-ts/src/components/common/Loading.tsx +19 -0
  401. package/templates/react-ts/src/components/common/LottieIcon.tsx +36 -0
  402. package/templates/react-ts/src/components/common/NotFound.tsx +78 -0
  403. package/templates/react-ts/src/components/common/PwaInstallPrompt.tsx +72 -0
  404. package/templates/react-ts/src/components/common/SEO.tsx +67 -0
  405. package/templates/react-ts/src/components/common/Scroll.tsx +25 -0
  406. package/templates/react-ts/src/components/common/Table.tsx +118 -0
  407. package/templates/react-ts/src/components/common/ToggleSwitch.tsx +38 -0
  408. package/templates/react-ts/src/components/common/Unauthorized.tsx +76 -0
  409. package/templates/react-ts/src/components/layout/ProtectedRoute.tsx +23 -0
  410. package/templates/react-ts/src/components/layout/PublicLayout.tsx +13 -0
  411. package/templates/react-ts/src/components/layout/SidebarLayout.tsx +37 -0
  412. package/templates/react-ts/src/components/modals/ConfirmModal.tsx +135 -0
  413. package/templates/react-ts/src/components/modals/Modal.tsx +94 -0
  414. package/templates/react-ts/src/components/skeletons/common/CardSkeleton.tsx +23 -0
  415. package/templates/react-ts/src/components/skeletons/common/DashboardSkeleton.tsx +19 -0
  416. package/templates/react-ts/src/components/skeletons/common/ListSkeleton.tsx +24 -0
  417. package/templates/react-ts/src/components/skeletons/common/PageSkeleton.tsx +26 -0
  418. package/templates/react-ts/src/components/skeletons/common/ProfileSkeleton.tsx +23 -0
  419. package/templates/react-ts/src/components/skeletons/common/Skeleton.tsx +18 -0
  420. package/templates/react-ts/src/components/skeletons/common/TableSkeleton.tsx +33 -0
  421. package/templates/react-ts/src/components/ui/Header.tsx +230 -0
  422. package/templates/react-ts/src/components/ui/SidebarHeader.tsx +27 -0
  423. package/templates/react-ts/src/components/ui/sidebar.tsx +152 -0
  424. package/templates/react-ts/src/config/api.ts +22 -0
  425. package/templates/react-ts/src/config/appConfig.ts +44 -0
  426. package/templates/react-ts/src/config/navigation.ts +14 -0
  427. package/templates/react-ts/src/hooks/useLenis.ts +28 -0
  428. package/templates/react-ts/src/hooks/usePwaInstall.ts +45 -0
  429. package/templates/react-ts/src/hooks/useWindowSize.ts +25 -0
  430. package/templates/react-ts/src/index.css +158 -0
  431. package/templates/react-ts/src/main.tsx +24 -0
  432. package/templates/react-ts/src/pages/Home.tsx +154 -0
  433. package/templates/react-ts/src/pages/Login.tsx +196 -0
  434. package/templates/react-ts/src/pages/Profile.tsx +9 -0
  435. package/templates/react-ts/src/services/authService.ts +16 -0
  436. package/templates/react-ts/src/store/useAuthStore.ts +98 -0
  437. package/templates/react-ts/src/store/useUiStore.ts +54 -0
  438. package/templates/react-ts/src/utils/getInitials.ts +10 -0
  439. package/templates/react-ts/tsconfig.json +25 -0
  440. package/templates/react-ts/tsconfig.node.json +10 -0
  441. package/templates/react-ts/vite.config.ts +8 -0
@@ -0,0 +1,73 @@
1
+ # Node.js TypeScript Prisma Backend Boilerplate
2
+
3
+ A production-ready, strongly-typed Node.js & Express boilerplate project with best-practice architectures, modular routing, Prisma ORM, and TSX engine compilation.
4
+
5
+ ## Features
6
+
7
+ - ⚙️ **Modular Architecture:** Express application setup decoupled into `app.ts` (middleware + router wiring) and `index.ts` (server initialization & db connection).
8
+ - 🗄️ **Prisma ORM:** Built-in PostgreSQL datasource configuration and schema mapping for `User`, `Otp`, and `PushSubscription` models.
9
+ - 📝 **Colorized Logging:** Zero-dependency custom logger with timestamped success, warning, info, and error layouts.
10
+ - 🛡️ **Security Out-of-the-Box:** Pre-configured with Helmet headers, CORS policies, and global rate limiters (`apiLimiter`, `authLimiter`, `uploadLimiter`).
11
+ - 🔑 **Authentication & JWT:** Custom middlewares for route protection, sign-ups, and log-ins with HTTP-only cookie-based tokens.
12
+ - 📧 **SMTP Mailer & OTP:** Standard mailer transport using Gmail NodeMailer wrapper, integrated with an OTP generator and email template.
13
+ - 🖼️ **File Uploads:** Cloudinary integration utilizing Multer memory buffers for secure, single or multi-file uploads.
14
+ - 🔌 **Socket.io Setup:** Pre-installed Socket.io hooks mapping connected user sessions to active sockets.
15
+ - ✉️ **Web Push:** Push notifications integration powered by VAPID key generators and web-push subscriptions.
16
+ - 📦 **TSX Engine:** Fast TS runner with native ESM specifier resolution support.
17
+
18
+ ## Getting Started
19
+
20
+ ### 1. Configure Environment Variables
21
+
22
+ Create a `.env` file in the root directory (based on `.env.example`):
23
+
24
+ ```env
25
+ PORT=5002
26
+ JWT_SECRET=your_super_secret_jwt_key
27
+ DATABASE_URL=postgresql://user:password@localhost:5432/db_name
28
+
29
+ # Cloudinary
30
+ CLOUDINARY_CLOUD_NAME=your_cloud_name
31
+ CLOUDINARY_API_KEY=your_api_key
32
+ CLOUDINARY_API_SECRET=your_api_secret
33
+
34
+ # SMTP Settings
35
+ GMAIL_USER=your_email@gmail.com
36
+ GMAIL_PASSCODE=your_app_password
37
+
38
+ # Web Push
39
+ VAPID_SUBJECT=mailto:your_email@example.com
40
+ VAPID_PUBLIC_KEY=your_vapid_public_key
41
+ VAPID_PRIVATE_KEY=your_vapid_private_key
42
+ ```
43
+
44
+ ### 2. Install & Sync Schema
45
+
46
+ ```bash
47
+ # Install dependencies
48
+ npm install
49
+
50
+ # Push database schema changes locally
51
+ npm run db:push
52
+
53
+ # Generate Prisma Client types
54
+ npm run db:generate
55
+
56
+ # Start development server with reload (via tsx)
57
+ npm run dev
58
+
59
+ # Build the project to JS
60
+ npm run build
61
+ ```
62
+
63
+ ## API Endpoints
64
+
65
+ ### Auth Routes (`/api/auth`)
66
+ - `POST /signup` - Registers a new user session
67
+ - `POST /login` - Log in user and write token cookie
68
+ - `POST /logout` - Clear token session cookies
69
+ - `GET /me` - Returns logged-in user profile (requires auth)
70
+ - `PUT /me` - Edit profile info and upload avatars (requires auth)
71
+
72
+ ### Upload Routes (`/api/upload`)
73
+ - `POST /` - Securely uploads image/file to Cloudinary (requires auth)
@@ -0,0 +1,24 @@
1
+ # Logs
2
+ logs
3
+ *.log
4
+ npm-debug.log*
5
+ yarn-debug.log*
6
+ yarn-error.log*
7
+ pnpm-debug.log*
8
+ lerna-debug.log*
9
+
10
+ node_modules
11
+ dist
12
+ dist-ssr
13
+ *.local
14
+
15
+ # Editor directories and files
16
+ .vscode/*
17
+ !.vscode/extensions.json
18
+ .idea
19
+ .DS_Store
20
+ *.suo
21
+ *.ntvs*
22
+ *.njsproj
23
+ *.sln
24
+ *.sw?
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "node-prisma-ts-template",
3
+ "version": "1.0.0",
4
+ "main": "src/index.ts",
5
+ "type": "module",
6
+ "scripts": {
7
+ "start": "tsx src/index.ts",
8
+ "dev": "tsx watch src/index.ts",
9
+ "build": "tsc",
10
+ "db:push": "prisma db push",
11
+ "db:generate": "prisma generate",
12
+ "generate:vapid": "node ./src/utils/generateVapidKeys.js"
13
+ },
14
+ "dependencies": {
15
+ "@prisma/client": "^5.6.0",
16
+ "bcrypt": "^5.1.1",
17
+ "compression": "^1.7.4",
18
+ "cookie-parser": "^1.4.6",
19
+ "cors": "^2.8.5",
20
+ "dotenv": "^16.3.1",
21
+ "express": "^4.18.2",
22
+ "express-rate-limit": "^7.1.4",
23
+ "helmet": "^7.1.0",
24
+ "jsonwebtoken": "^9.0.2",
25
+ "morgan": "^1.10.0",
26
+ "multer": "^1.4.5-lts.1",
27
+ "cloudinary": "^2.0.0",
28
+ "nodemailer": "^6.9.7",
29
+ "socket.io": "^4.7.2",
30
+ "web-push": "^3.6.6"
31
+ },
32
+ "devDependencies": {
33
+ "@types/bcrypt": "^5.0.2",
34
+ "@types/compression": "^1.7.5",
35
+ "@types/cookie-parser": "^1.4.6",
36
+ "@types/cors": "^2.8.17",
37
+ "@types/express": "^4.17.21",
38
+ "@types/jsonwebtoken": "^9.0.5",
39
+ "@types/morgan": "^1.9.9",
40
+ "@types/multer": "^1.4.11",
41
+ "@types/nodemailer": "^6.4.14",
42
+ "@types/web-push": "^3.6.3",
43
+ "@types/node": "^20.9.0",
44
+ "prisma": "^5.6.0",
45
+ "tsx": "^4.23.1",
46
+ "typescript": "^5.2.2"
47
+ }
48
+ }
@@ -0,0 +1,41 @@
1
+ generator client {
2
+ provider = "prisma-client-js"
3
+ }
4
+
5
+ datasource db {
6
+ provider = "postgresql"
7
+ url = env("DATABASE_URL")
8
+ }
9
+
10
+ model User {
11
+ id String @id @default(uuid())
12
+ email String @unique
13
+ name String
14
+ phone String?
15
+ password String
16
+ role String @default("user")
17
+ avatarUrl String?
18
+ avatarPublicId String?
19
+ createdAt DateTime @default(now())
20
+ updatedAt DateTime @updatedAt
21
+ pushSubscriptions PushSubscription[]
22
+ }
23
+
24
+ model Otp {
25
+ id String @id @default(uuid())
26
+ email String @unique
27
+ otp String
28
+ createdAt DateTime @default(now())
29
+ }
30
+
31
+ model PushSubscription {
32
+ id String @id @default(uuid())
33
+ endpoint String @unique
34
+ p256dh String
35
+ auth String
36
+ role String @default("user")
37
+ userId String?
38
+ user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
39
+ createdAt DateTime @default(now())
40
+ updatedAt DateTime @updatedAt
41
+ }
@@ -0,0 +1,36 @@
1
+ import express, { Request, Response, NextFunction } from "express";
2
+ import helmet from "helmet";
3
+ import cors from "cors";
4
+ import compression from "compression";
5
+ import cookieParser from "cookie-parser";
6
+ import morgan from "morgan";
7
+ import apiRoutes from "./routes/index.js";
8
+ import { notFound, errorHandler } from "./middleware/errorHandler.js";
9
+ import { apiLimiter } from "./middleware/rateLimiter.js";
10
+
11
+ const app = express();
12
+
13
+ app.use(helmet());
14
+ app.use(
15
+ cors({
16
+ origin: process.env.CLIENT_URL || "http://localhost:5173",
17
+ credentials: true,
18
+ })
19
+ );
20
+ app.use(compression());
21
+ app.use(express.json());
22
+ app.use(express.urlencoded({ extended: true }));
23
+ app.use(cookieParser());
24
+ app.use(morgan("dev"));
25
+
26
+ app.use(apiLimiter);
27
+ app.use("/api", apiRoutes);
28
+
29
+ app.get("/api/health", (req: Request, res: Response) => {
30
+ res.status(200).json({ success: true, message: "API is running" });
31
+ });
32
+
33
+ app.use(notFound);
34
+ app.use(errorHandler);
35
+
36
+ export default app;
@@ -0,0 +1,9 @@
1
+ import { v2 as cloudinary } from "cloudinary";
2
+
3
+ cloudinary.config({
4
+ cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
5
+ api_key: process.env.CLOUDINARY_API_KEY,
6
+ api_secret: process.env.CLOUDINARY_API_SECRET,
7
+ });
8
+
9
+ export default cloudinary;
@@ -0,0 +1,16 @@
1
+ import { PrismaClient } from "@prisma/client";
2
+ import logger from "../utils/logger.js";
3
+
4
+ export const prisma = new PrismaClient();
5
+
6
+ const connectDB = async () => {
7
+ try {
8
+ await prisma.$connect();
9
+ logger.success("Prisma Database connected successfully");
10
+ } catch (error: any) {
11
+ logger.error(`Prisma Database connection failed: ${error.message}`, error);
12
+ process.exit(1);
13
+ }
14
+ };
15
+
16
+ export default connectDB;
@@ -0,0 +1,2 @@
1
+ import dotenv from "dotenv";
2
+ dotenv.config();
@@ -0,0 +1,28 @@
1
+ import nodemailer from "nodemailer";
2
+ import logger from "../utils/logger.js";
3
+
4
+ const sendEmail = async (to: string, subject: string, message: string) => {
5
+ try {
6
+ const transporter = nodemailer.createTransport({
7
+ service: "gmail",
8
+ auth: {
9
+ user: process.env.GMAIL_USER,
10
+ pass: process.env.GMAIL_PASSCODE,
11
+ },
12
+ });
13
+
14
+ const mailOptions = {
15
+ from: process.env.GMAIL_USER,
16
+ to,
17
+ subject,
18
+ html: message,
19
+ };
20
+
21
+ const res = await transporter.sendMail(mailOptions);
22
+ logger.success(`Email sent to ${to}: ${res.messageId}`);
23
+ } catch (error) {
24
+ logger.error("Failed to send email", error);
25
+ }
26
+ };
27
+
28
+ export default sendEmail;
@@ -0,0 +1,54 @@
1
+ import { Server } from "socket.io";
2
+ import logger from "../utils/logger.js";
3
+
4
+ let io: Server;
5
+
6
+ const userSocketMap: { [key: string]: Set<string> } = {};
7
+
8
+ const initializeSocket = (server: any) => {
9
+ io = new Server(server, {
10
+ cors: {
11
+ origin: ["http://localhost:5173"],
12
+ credentials: true,
13
+ },
14
+ });
15
+
16
+ io.on("connection", (socket) => {
17
+ const userId = socket.handshake.auth.userId as string | undefined;
18
+
19
+ if (!userId) {
20
+ logger.warn("No userId, disconnecting socket");
21
+ socket.disconnect();
22
+ return;
23
+ }
24
+
25
+ logger.info(`Socket connected: ${socket.id} (User: ${userId})`);
26
+
27
+ if (!userSocketMap[userId]) {
28
+ userSocketMap[userId] = new Set<string>();
29
+ }
30
+ userSocketMap[userId].add(socket.id);
31
+
32
+ socket.on("disconnect", (reason) => {
33
+ if (!userId) return;
34
+ userSocketMap[userId].delete(socket.id);
35
+ logger.info(`Socket disconnected: ${socket.id} (Reason: ${reason})`);
36
+ });
37
+ });
38
+
39
+ return io;
40
+ };
41
+
42
+ export const getIO = () => {
43
+ if (!io) {
44
+ throw new Error("Socket.IO has not been initialized yet");
45
+ }
46
+ return io;
47
+ };
48
+
49
+ const getReceiverSocketIds = (userId: string) =>
50
+ userSocketMap[userId] ? Array.from(userSocketMap[userId]) : [];
51
+
52
+ export { io, getReceiverSocketIds, userSocketMap };
53
+
54
+ export default initializeSocket;
@@ -0,0 +1,9 @@
1
+ import webpush from "web-push";
2
+
3
+ webpush.setVapidDetails(
4
+ process.env.VAPID_SUBJECT as string || "",
5
+ process.env.VAPID_PUBLIC_KEY as string || "",
6
+ process.env.VAPID_PRIVATE_KEY as string || ""
7
+ );
8
+
9
+ export default webpush;
@@ -0,0 +1,124 @@
1
+ import { Request, Response, NextFunction } from "express";
2
+ import { authService } from "../services/auth.service.js";
3
+ import { generateToken } from "../utils/jwt.js";
4
+ import genOtpToken from "../utils/genOtpToken.js";
5
+ import logger from "../utils/logger.js";
6
+
7
+ export const signup = async (req: Request, res: Response, next: NextFunction) => {
8
+ try {
9
+ const { name, email, phone, password } = req.body;
10
+ if (!email || !password || !name) {
11
+ return next({ status: 400, message: "All fields are required." });
12
+ }
13
+ const newUser = await authService.signup({ name, email, phone, password });
14
+ const token = await generateToken(newUser, res);
15
+ const safeUser: any = { ...newUser };
16
+ delete safeUser.password;
17
+ res.status(201).json({ message: "Registration Successful", data: safeUser, token });
18
+ } catch (error) {
19
+ logger.error("Error in signup controller", error);
20
+ next(error);
21
+ }
22
+ };
23
+
24
+ export const login = async (req: Request, res: Response, next: NextFunction) => {
25
+ try {
26
+ const { email, password } = req.body;
27
+ if (!email || !password) {
28
+ return next({ status: 400, message: "All fields are required." });
29
+ }
30
+ const user = await authService.login({ email, password });
31
+ const token = await generateToken(user, res);
32
+ const safeUser: any = { ...user };
33
+ delete safeUser.password;
34
+ res.status(200).json({ message: "Login successfully", data: safeUser, token });
35
+ } catch (error) {
36
+ logger.error("Error in login controller", error);
37
+ next(error);
38
+ }
39
+ };
40
+
41
+ export const logout = async (req: Request, res: Response, next: NextFunction) => {
42
+ try {
43
+ res.clearCookie("token", {
44
+ httpOnly: true,
45
+ secure: process.env.NODE_ENV === "production",
46
+ sameSite: "strict",
47
+ path: "/",
48
+ });
49
+ res.status(200).json({ message: "Logout Successfully" });
50
+ } catch (error) {
51
+ logger.error("Error in logout controller", error);
52
+ next(error);
53
+ }
54
+ };
55
+
56
+ export const getMe = async (req: Request, res: Response, next: NextFunction) => {
57
+ try {
58
+ res.status(200).json({ message: "User Authenticated", data: req.user });
59
+ } catch (error) {
60
+ logger.error("Error in getMe controller", error);
61
+ next(error);
62
+ }
63
+ };
64
+
65
+ export const genOtp = async (req: Request, res: Response, next: NextFunction) => {
66
+ try {
67
+ const { email } = req.body;
68
+ if (!email) {
69
+ return next({ status: 400, message: "Email is required." });
70
+ }
71
+ await authService.generateOtp(email);
72
+ res.status(200).json({ message: "Otp sent successfully" });
73
+ } catch (error) {
74
+ logger.error("Error in genOtp", error);
75
+ next(error);
76
+ }
77
+ };
78
+
79
+ export const verifyOtp = async (req: Request, res: Response, next: NextFunction) => {
80
+ try {
81
+ const { email, otp } = req.body;
82
+ if (!email || !otp) {
83
+ return next({ status: 400, message: "All fields are required." });
84
+ }
85
+ const user = await authService.verifyOtp({ email, otp });
86
+ await genOtpToken(user, res);
87
+ res.status(200).json({ message: "Otp verified successfully" });
88
+ } catch (error) {
89
+ logger.error("Error in verifyOtp", error);
90
+ next(error);
91
+ }
92
+ };
93
+
94
+ export const resetPassword = async (req: Request, res: Response, next: NextFunction) => {
95
+ try {
96
+ const { newPassword } = req.body;
97
+ const currentUser = req.user;
98
+ if (!newPassword) {
99
+ return next({ status: 400, message: "All fields are required." });
100
+ }
101
+ await authService.resetPassword(currentUser, newPassword);
102
+ res.status(200).json({ message: "Password updated successfully" });
103
+ } catch (error) {
104
+ logger.error("Error in resetPassword", error);
105
+ next(error);
106
+ }
107
+ };
108
+
109
+ export const updateMe = async (req: Request, res: Response, next: NextFunction) => {
110
+ try {
111
+ const { name, phone } = req.body;
112
+ const user = await authService.updateProfile(req.user.id, {
113
+ name,
114
+ phone,
115
+ file: req.file,
116
+ });
117
+ const safeUser: any = { ...user };
118
+ delete safeUser.password;
119
+ res.status(200).json({ success: true, data: safeUser });
120
+ } catch (error) {
121
+ logger.error("Error updating profile", error);
122
+ next(error);
123
+ }
124
+ };
@@ -0,0 +1,22 @@
1
+ import { Request, Response, NextFunction } from "express";
2
+ import { uploadSingleToCloudinary } from "../utils/cloudinaryUpload.js";
3
+ import logger from "../utils/logger.js";
4
+
5
+ export const uploadFile = async (req: Request, res: Response, next: NextFunction) => {
6
+ try {
7
+ if (!req.file) {
8
+ return res.status(400).json({ success: false, message: "No file uploaded" });
9
+ }
10
+ const result = await uploadSingleToCloudinary(req.file, {
11
+ folder: req.body.folder || "general_uploads",
12
+ });
13
+ res.status(200).json({
14
+ success: true,
15
+ message: "File uploaded successfully",
16
+ data: result,
17
+ });
18
+ } catch (error) {
19
+ logger.error("Upload controller error", error);
20
+ next(error);
21
+ }
22
+ };
@@ -0,0 +1,17 @@
1
+ import dotenv from "dotenv";
2
+ import http from "http";
3
+ import app from "./app.js";
4
+ import connectDB from "./config/db.js";
5
+ import logger from "./utils/logger.js";
6
+
7
+ dotenv.config();
8
+
9
+ const PORT = process.env.PORT || 5000;
10
+
11
+ connectDB();
12
+
13
+ const server = http.createServer(app);
14
+
15
+ server.listen(PORT, () => {
16
+ logger.success(`Server is running on port ${PORT}`);
17
+ });
@@ -0,0 +1,45 @@
1
+ import { Request, Response, NextFunction } from "express";
2
+ import { verifyToken } from "../utils/jwt.js";
3
+ import logger from "../utils/logger.js";
4
+ import { prisma } from "../config/db.js";
5
+
6
+ export const protect = async (req: Request, res: Response, next: NextFunction) => {
7
+ let token: string | undefined;
8
+
9
+ if (req.cookies?.token) {
10
+ token = req.cookies.token;
11
+ } else if (
12
+ req.headers.authorization &&
13
+ req.headers.authorization.startsWith("Bearer")
14
+ ) {
15
+ token = req.headers.authorization.split(" ")[1];
16
+ }
17
+
18
+ if (!token) {
19
+ return res.status(401).json({ message: "Not authorized, no token provided" });
20
+ }
21
+
22
+ try {
23
+ const decoded: any = verifyToken(token);
24
+ if (!decoded) {
25
+ return res.status(401).json({ message: "Not authorized, invalid token" });
26
+ }
27
+
28
+ const user = await prisma.user.findUnique({
29
+ where: { id: decoded.id },
30
+ });
31
+
32
+ if (!user) {
33
+ return res.status(401).json({ message: "Not authorized, user not found" });
34
+ }
35
+
36
+ const safeUser: any = { ...user };
37
+ delete safeUser.password;
38
+
39
+ req.user = safeUser;
40
+ return next();
41
+ } catch (error: any) {
42
+ logger.error("Auth middleware error", error);
43
+ return res.status(401).json({ message: "Not authorized, token verification failed" });
44
+ }
45
+ };
@@ -0,0 +1,16 @@
1
+ import { Request, Response, NextFunction } from "express";
2
+
3
+ export const notFound = (req: Request, res: Response, next: NextFunction) => {
4
+ const error = new Error(`Not Found - ${req.originalUrl}`);
5
+ res.status(404);
6
+ next(error);
7
+ };
8
+
9
+ export const errorHandler = (err: any, req: Request, res: Response, next: NextFunction) => {
10
+ const statusCode = err.status || err.statusCode || (res.statusCode === 200 ? 500 : res.statusCode);
11
+ res.status(statusCode).json({
12
+ success: false,
13
+ message: err.message || "An unexpected error occurred",
14
+ stack: process.env.NODE_ENV === "production" ? undefined : err.stack,
15
+ });
16
+ };
@@ -0,0 +1,20 @@
1
+ import multer, { FileFilterCallback } from "multer";
2
+ import { Request } from "express";
3
+
4
+ const storage = multer.memoryStorage();
5
+
6
+ const fileFilter = (req: Request, file: Express.Multer.File, cb: FileFilterCallback) => {
7
+ if (file.mimetype.startsWith("image/")) {
8
+ cb(null, true);
9
+ } else {
10
+ cb(new Error("Only image files are allowed!"));
11
+ }
12
+ };
13
+
14
+ export const upload = multer({
15
+ storage,
16
+ fileFilter,
17
+ limits: {
18
+ fileSize: 5 * 1024 * 1024, // 5MB limit
19
+ },
20
+ });
@@ -0,0 +1,53 @@
1
+ import rateLimit from "express-rate-limit";
2
+ import { Request, Response } from "express";
3
+
4
+ interface LimiterConfig {
5
+ windowMs: number;
6
+ max: number;
7
+ message: string;
8
+ skipSuccessfulRequests?: boolean;
9
+ }
10
+
11
+ const createLimiter = ({
12
+ windowMs,
13
+ max,
14
+ message,
15
+ skipSuccessfulRequests = false,
16
+ }: LimiterConfig) =>
17
+ rateLimit({
18
+ windowMs,
19
+ max,
20
+ standardHeaders: true,
21
+ legacyHeaders: false,
22
+ skipSuccessfulRequests,
23
+
24
+ keyGenerator: (req: any) => {
25
+ return req.user?.id || req.ip || req.headers["x-forwarded-for"] || req.socket.remoteAddress;
26
+ },
27
+
28
+ handler: (req: Request, res: Response) => {
29
+ res.status(429).json({
30
+ success: false,
31
+ message,
32
+ });
33
+ },
34
+ });
35
+
36
+ export const apiLimiter = createLimiter({
37
+ windowMs: 15 * 60 * 1000,
38
+ max: 100,
39
+ message: "Too many requests. Please try again later.",
40
+ });
41
+
42
+ export const authLimiter = createLimiter({
43
+ windowMs: 15 * 60 * 1000,
44
+ max: 10,
45
+ skipSuccessfulRequests: true,
46
+ message: "Too many login attempts. Please try again later.",
47
+ });
48
+
49
+ export const uploadLimiter = createLimiter({
50
+ windowMs: 60 * 60 * 1000,
51
+ max: 20,
52
+ message: "Upload limit reached. Please try again in an hour.",
53
+ });
@@ -0,0 +1,22 @@
1
+ import express from "express";
2
+ import {
3
+ signup,
4
+ login,
5
+ getMe,
6
+ logout,
7
+ updateMe,
8
+ } from "../controllers/auth.controller.js";
9
+ import { protect } from "../middleware/auth.middleware.js";
10
+ import { apiLimiter } from "../middleware/rateLimiter.js";
11
+
12
+ const router = express.Router();
13
+
14
+ router.use(apiLimiter);
15
+
16
+ router.post("/signup", signup);
17
+ router.post("/login", login);
18
+ router.post("/logout", logout);
19
+ router.get("/me", protect, getMe);
20
+ router.put("/me", protect, updateMe);
21
+
22
+ export default router;