@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,54 @@
1
+ import { create } from "zustand";
2
+
3
+ export const useUiStore = create((set, get) => ({
4
+ open: false,
5
+ collapsed: false,
6
+ isMobileMenuOpened: false,
7
+ headerTitle: "Dashboard",
8
+ headerActions: null,
9
+ setHeaderTitle: (title) => set({ headerTitle: title }),
10
+ setHeaderActions: (actions) => set({ headerActions: actions }),
11
+ toggleCollapsed: () => set((state) => ({ collapsed: !state.collapsed })),
12
+
13
+ setMobileMenuOpened: (open) => {
14
+ set({ isMobileMenuOpened: open });
15
+ },
16
+ toggleMobileMenuOpened: () => {
17
+ set((state) => ({ isMobileMenuOpened: !state.isMobileMenuOpened }));
18
+ },
19
+
20
+ theme: localStorage.getItem("theme") || "light",
21
+
22
+ setTheme: (theme) => {
23
+ document.documentElement.setAttribute("data-theme", theme);
24
+
25
+ localStorage.setItem("theme", theme);
26
+
27
+ set({ theme });
28
+ },
29
+
30
+ toggleTheme: () => {
31
+ const nextTheme = get().theme === "light" ? "dark" : "light";
32
+
33
+ document.documentElement.setAttribute("data-theme", nextTheme);
34
+
35
+ localStorage.setItem("theme", nextTheme);
36
+
37
+ set({ theme: nextTheme });
38
+ },
39
+
40
+ toggleSidebar: () =>
41
+ set((state) => ({
42
+ open: !state.open,
43
+ })),
44
+
45
+ openSidebar: () =>
46
+ set({
47
+ open: true,
48
+ }),
49
+
50
+ close: () =>
51
+ set({
52
+ open: false,
53
+ }),
54
+ }));
@@ -0,0 +1,10 @@
1
+ export const getInitials = (name = "") => {
2
+ if (!name.trim()) return "";
3
+
4
+ return name
5
+ .trim()
6
+ .split(/\s+/)
7
+ .slice(0, 2)
8
+ .map((word) => word[0].toUpperCase())
9
+ .join("");
10
+ };
@@ -0,0 +1,25 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
+ "module": "ESNext",
7
+ "skipLibCheck": true,
8
+
9
+ /* Bundler mode */
10
+ "moduleResolution": "bundler",
11
+ "allowImportingTsExtensions": true,
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "noEmit": true,
15
+ "jsx": "react-jsx",
16
+
17
+ /* Linting */
18
+ "strict": true,
19
+ "noUnusedLocals": true,
20
+ "noUnusedParameters": true,
21
+ "noFallthroughCasesInSwitch": true
22
+ },
23
+ "include": ["src"],
24
+ "references": [{ "path": "./tsconfig.node.json" }]
25
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "compilerOptions": {
3
+ "composite": true,
4
+ "skipLibCheck": true,
5
+ "module": "ESNext",
6
+ "moduleResolution": "bundler",
7
+ "allowSyntheticDefaultImports": true
8
+ },
9
+ "include": ["vite.config.ts"]
10
+ }
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from 'vite'
2
+ import react from '@vitejs/plugin-react'
3
+ import tailwindcss from '@tailwindcss/vite'
4
+
5
+ // https://vitejs.dev/config/
6
+ export default defineConfig({
7
+ plugins: [react(), tailwindcss()],
8
+ })
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "mern-ts-template",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "postinstall": "npm run install:all",
7
+ "install:all": "npm run install:client && npm run install:server",
8
+ "install:client": "cd client && npm install",
9
+ "install:server": "cd server && npm install",
10
+ "dev": "concurrently \"npm run dev:client\" \"npm run dev:server\"",
11
+ "dev:client": "cd client && npm run dev",
12
+ "dev:server": "cd server && npm run dev",
13
+ "build": "cd client && npm run build",
14
+ "generate:vapid": "node ./server/src/utils/generateVapidKeys.js"
15
+ },
16
+ "devDependencies": {
17
+ "concurrently": "^8.2.2"
18
+ }
19
+ }
@@ -0,0 +1,62 @@
1
+ # ==========================
2
+ # Application
3
+ # ==========================
4
+ NODE_ENV=development
5
+ PORT=5001
6
+
7
+ APP_NAME=My App
8
+ APP_URL=http://localhost:5173
9
+ APP_EMAIL=noreply@example.com
10
+ APP_PRIMARY_COLOR=#2563eb
11
+
12
+ # ==========================
13
+ # Database
14
+ # ==========================
15
+ MONGO_URI=
16
+
17
+ # ==========================
18
+ # JWT
19
+ # ==========================
20
+ JWT_SECRET=
21
+ JWT_EXPIRES_IN=7d
22
+
23
+ # ==========================
24
+ # Cloudinary
25
+ # ==========================
26
+ CLOUDINARY_CLOUD_NAME=
27
+ CLOUDINARY_API_KEY=
28
+ CLOUDINARY_API_SECRET=
29
+
30
+ # ==========================
31
+ # Email (SMTP)
32
+ # ==========================
33
+ SMTP_HOST=smtp.gmail.com
34
+ SMTP_PORT=587
35
+ SMTP_SECURE=false
36
+ SMTP_USER=
37
+ SMTP_PASS=
38
+ SMTP_FROM="My App <noreply@example.com>"
39
+
40
+ # ==========================
41
+ # CORS
42
+ # ==========================
43
+ CLIENT_URL=http://localhost:5173
44
+
45
+ # ==========================
46
+ # Cookie
47
+ # ==========================
48
+ COOKIE_NAME=token
49
+ COOKIE_EXPIRES_IN=7d
50
+
51
+ # ==========================
52
+ # Rate Limiting
53
+ # ==========================
54
+ RATE_LIMIT_WINDOW=15
55
+ RATE_LIMIT_MAX=100
56
+
57
+ # ==========================
58
+ # Rate Limiting
59
+ # ==========================
60
+ VAPID_PRIVATE_KEY=
61
+ VAPID_PUBLIC_KEY=
62
+ VAPID_SUBJECT=mailto:noreply@example.com
@@ -0,0 +1,69 @@
1
+ # Node.js TypeScript Backend Boilerplate
2
+
3
+ A production-ready, strongly-typed Node.js & Express boilerplate project with best-practice architectures, modular routing, and TypeScript 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
+ - 📝 **Colorized Logging:** Zero-dependency custom logger with timestamped success, warning, info, and error layouts.
9
+ - 🛡️ **Security Out-of-the-Box:** Pre-configured with Helmet headers, CORS policies, and global rate limiters (`apiLimiter`, `authLimiter`, `uploadLimiter`).
10
+ - 🔑 **Authentication & JWT:** Custom middlewares for route protection, sign-ups, and log-ins with HTTP-only cookie-based tokens.
11
+ - 📧 **SMTP Mailer & OTP:** Standard mailer transport using Gmail NodeMailer wrapper, integrated with an OTP generator and email template.
12
+ - 🖼️ **File Uploads:** Cloudinary integration utilizing Multer memory buffers for secure, single or multi-file uploads.
13
+ - 🔌 **Socket.io Setup:** Pre-installed Socket.io hooks mapping connected user sessions to active sockets.
14
+ - ✉️ **Web Push:** Push notifications integration powered by VAPID key generators and web-push subscriptions.
15
+ - 📦 **TSX Engine:** Fast runtime TS loader supporting ESM resolutions natively with instant reloads.
16
+
17
+ ## Getting Started
18
+
19
+ ### 1. Configure Environment Variables
20
+
21
+ Create a `.env` file in the root directory (based on `.env.example`):
22
+
23
+ ```env
24
+ PORT=5002
25
+ JWT_SECRET=your_super_secret_jwt_key
26
+ MONGO_URI=your_mongodb_connection_uri
27
+
28
+ # Cloudinary
29
+ CLOUDINARY_CLOUD_NAME=your_cloud_name
30
+ CLOUDINARY_API_KEY=your_api_key
31
+ CLOUDINARY_API_SECRET=your_api_secret
32
+
33
+ # SMTP Settings
34
+ GMAIL_USER=your_email@gmail.com
35
+ GMAIL_PASSCODE=your_app_password
36
+
37
+ # Web Push
38
+ VAPID_SUBJECT=mailto:your_email@example.com
39
+ VAPID_PUBLIC_KEY=your_vapid_public_key
40
+ VAPID_PRIVATE_KEY=your_vapid_private_key
41
+ ```
42
+
43
+ ### 2. Install & Start Development
44
+
45
+ ```bash
46
+ # Install dependencies
47
+ npm install
48
+
49
+ # Start development server with reload (via tsx)
50
+ npm run dev
51
+
52
+ # Build the project to JS
53
+ npm run build
54
+
55
+ # Start production compiled server
56
+ npm start
57
+ ```
58
+
59
+ ## API Endpoints
60
+
61
+ ### Auth Routes (`/api/auth`)
62
+ - `POST /signup` - Registers a new user session
63
+ - `POST /login` - Log in user and write token cookie
64
+ - `POST /logout` - Clear token session cookies
65
+ - `GET /me` - Returns logged-in user profile (requires auth)
66
+ - `PUT /me` - Edit profile info and upload avatars (requires auth)
67
+
68
+ ### Upload Routes (`/api/upload`)
69
+ - `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,47 @@
1
+ {
2
+ "name": "/Users/karan/workspace/Projects/boilerplate/test-app-node-ts",
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
+ "generate:vapid": "node ./src/utils/generateVapidKeys.js"
11
+ },
12
+ "dependencies": {
13
+ "bcrypt": "^5.1.1",
14
+ "cloudinary": "^2.0.0",
15
+ "compression": "^1.7.4",
16
+ "cookie-parser": "^1.4.6",
17
+ "cors": "^2.8.5",
18
+ "dotenv": "^16.3.1",
19
+ "express": "^4.18.2",
20
+ "express-rate-limit": "^7.1.4",
21
+ "helmet": "^7.1.0",
22
+ "jsonwebtoken": "^9.0.2",
23
+ "mongoose": "^8.0.0",
24
+ "morgan": "^1.10.0",
25
+ "multer": "^1.4.5-lts.1",
26
+ "nodemailer": "^6.9.7",
27
+ "socket.io": "^4.7.2",
28
+ "web-push": "^3.6.6"
29
+ },
30
+ "devDependencies": {
31
+ "@types/bcrypt": "^5.0.2",
32
+ "@types/compression": "^1.7.5",
33
+ "@types/cookie-parser": "^1.4.6",
34
+ "@types/cors": "^2.8.17",
35
+ "@types/express": "^4.17.21",
36
+ "@types/jsonwebtoken": "^9.0.5",
37
+ "@types/morgan": "^1.9.9",
38
+ "@types/multer": "^1.4.11",
39
+ "@types/node": "^20.9.0",
40
+ "@types/nodemailer": "^6.4.14",
41
+ "@types/web-push": "^3.6.3",
42
+ "nodemon": "^3.0.1",
43
+ "ts-node": "^10.9.1",
44
+ "tsx": "^4.23.1",
45
+ "typescript": "^5.2.2"
46
+ }
47
+ }
@@ -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,15 @@
1
+ import mongoose from "mongoose";
2
+ import logger from "../utils/logger.js";
3
+
4
+ const connectDB = async () => {
5
+ try {
6
+ const MONGO_URI = process.env.MONGO_URI || "mongodb://localhost:27017/test";
7
+ const conn = await mongoose.connect(MONGO_URI);
8
+ logger.success(`MongoDB connected: ${conn.connection.host}`);
9
+ } catch (error: any) {
10
+ logger.error(`MongoDB connection error: ${error.message}`, error);
11
+ process.exit(1);
12
+ }
13
+ };
14
+
15
+ 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,126 @@
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.toObject();
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.toObject();
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
+ const safeUser: any = req.user.toObject();
59
+ delete safeUser.password;
60
+ res.status(200).json({ message: "User Authenticated", data: safeUser });
61
+ } catch (error) {
62
+ logger.error("Error in getMe controller", error);
63
+ next(error);
64
+ }
65
+ };
66
+
67
+ export const genOtp = async (req: Request, res: Response, next: NextFunction) => {
68
+ try {
69
+ const { email } = req.body;
70
+ if (!email) {
71
+ return next({ status: 400, message: "Email is required." });
72
+ }
73
+ await authService.generateOtp(email);
74
+ res.status(200).json({ message: "Otp sent successfully" });
75
+ } catch (error) {
76
+ logger.error("Error in genOtp", error);
77
+ next(error);
78
+ }
79
+ };
80
+
81
+ export const verifyOtp = async (req: Request, res: Response, next: NextFunction) => {
82
+ try {
83
+ const { email, otp } = req.body;
84
+ if (!email || !otp) {
85
+ return next({ status: 400, message: "All fields are required." });
86
+ }
87
+ const user = await authService.verifyOtp({ email, otp });
88
+ await genOtpToken(user, res);
89
+ res.status(200).json({ message: "Otp verified successfully" });
90
+ } catch (error) {
91
+ logger.error("Error in verifyOtp", error);
92
+ next(error);
93
+ }
94
+ };
95
+
96
+ export const resetPassword = async (req: Request, res: Response, next: NextFunction) => {
97
+ try {
98
+ const { newPassword } = req.body;
99
+ const currentUser = req.user;
100
+ if (!newPassword) {
101
+ return next({ status: 400, message: "All fields are required." });
102
+ }
103
+ await authService.resetPassword(currentUser, newPassword);
104
+ res.status(200).json({ message: "Password updated successfully" });
105
+ } catch (error) {
106
+ logger.error("Error in resetPassword", error);
107
+ next(error);
108
+ }
109
+ };
110
+
111
+ export const updateMe = async (req: Request, res: Response, next: NextFunction) => {
112
+ try {
113
+ const { name, phone } = req.body;
114
+ const user = await authService.updateProfile(req.user._id, {
115
+ name,
116
+ phone,
117
+ file: req.file,
118
+ });
119
+ const safeUser: any = user.toObject();
120
+ delete safeUser.password;
121
+ res.status(200).json({ success: true, data: safeUser });
122
+ } catch (error) {
123
+ logger.error("Error updating profile", error);
124
+ next(error);
125
+ }
126
+ };
@@ -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
+ });