@studious-lms/server 1.2.53 → 1.4.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 (479) hide show
  1. package/.coderabbit.yaml +9 -0
  2. package/.env.example +9 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +102 -8
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/config/env.d.ts +21 -0
  7. package/dist/lib/config/env.d.ts.map +1 -1
  8. package/dist/lib/config/env.js +8 -2
  9. package/dist/lib/config/env.js.map +1 -1
  10. package/dist/lib/fileUpload.d.ts.map +1 -1
  11. package/dist/lib/fileUpload.js +2 -2
  12. package/dist/lib/fileUpload.js.map +1 -1
  13. package/dist/lib/googleCloudStorage.d.ts +6 -0
  14. package/dist/lib/googleCloudStorage.d.ts.map +1 -1
  15. package/dist/lib/googleCloudStorage.js +19 -2
  16. package/dist/lib/googleCloudStorage.js.map +1 -1
  17. package/dist/lib/pusher.d.ts +4 -1
  18. package/dist/lib/pusher.d.ts.map +1 -1
  19. package/dist/lib/pusher.js +6 -3
  20. package/dist/lib/pusher.js.map +1 -1
  21. package/dist/lib/redis.d.ts +5 -0
  22. package/dist/lib/redis.d.ts.map +1 -0
  23. package/dist/lib/redis.js +53 -0
  24. package/dist/lib/redis.js.map +1 -0
  25. package/dist/lib/thumbnailGenerator.d.ts +0 -21
  26. package/dist/lib/thumbnailGenerator.d.ts.map +1 -1
  27. package/dist/lib/thumbnailGenerator.js +157 -160
  28. package/dist/lib/thumbnailGenerator.js.map +1 -1
  29. package/dist/middleware/auth.d.ts.map +1 -1
  30. package/dist/middleware/auth.js +33 -95
  31. package/dist/middleware/auth.js.map +1 -1
  32. package/dist/models/agenda.d.ts +97 -0
  33. package/dist/models/agenda.d.ts.map +1 -0
  34. package/dist/models/agenda.js +40 -0
  35. package/dist/models/agenda.js.map +1 -0
  36. package/dist/models/announcement.d.ts +223 -0
  37. package/dist/models/announcement.d.ts.map +1 -0
  38. package/dist/models/announcement.js +120 -0
  39. package/dist/models/announcement.js.map +1 -0
  40. package/dist/models/assignment.d.ts +1292 -0
  41. package/dist/models/assignment.d.ts.map +1 -0
  42. package/dist/models/assignment.js +309 -0
  43. package/dist/models/assignment.js.map +1 -0
  44. package/dist/models/attendance.d.ts +180 -0
  45. package/dist/models/attendance.d.ts.map +1 -0
  46. package/dist/models/attendance.js +188 -0
  47. package/dist/models/attendance.js.map +1 -0
  48. package/dist/models/auth.d.ts +153 -0
  49. package/dist/models/auth.d.ts.map +1 -0
  50. package/dist/models/auth.js +217 -0
  51. package/dist/models/auth.js.map +1 -0
  52. package/dist/models/class.d.ts +461 -0
  53. package/dist/models/class.d.ts.map +1 -0
  54. package/dist/models/class.js +645 -0
  55. package/dist/models/class.js.map +1 -0
  56. package/dist/models/comment.d.ts +171 -0
  57. package/dist/models/comment.d.ts.map +1 -0
  58. package/dist/models/comment.js +138 -0
  59. package/dist/models/comment.js.map +1 -0
  60. package/dist/models/conversation.d.ts +164 -0
  61. package/dist/models/conversation.d.ts.map +1 -0
  62. package/dist/models/conversation.js +175 -0
  63. package/dist/models/conversation.js.map +1 -0
  64. package/dist/models/event.d.ts +295 -0
  65. package/dist/models/event.d.ts.map +1 -0
  66. package/dist/models/event.js +145 -0
  67. package/dist/models/event.js.map +1 -0
  68. package/dist/models/file.d.ts +536 -0
  69. package/dist/models/file.d.ts.map +1 -0
  70. package/dist/models/file.js +126 -0
  71. package/dist/models/file.js.map +1 -0
  72. package/dist/models/folder.d.ts +295 -0
  73. package/dist/models/folder.d.ts.map +1 -0
  74. package/dist/models/folder.js +202 -0
  75. package/dist/models/folder.js.map +1 -0
  76. package/dist/models/labChat.d.ts +243 -0
  77. package/dist/models/labChat.d.ts.map +1 -0
  78. package/dist/models/labChat.js +204 -0
  79. package/dist/models/labChat.js.map +1 -0
  80. package/dist/models/marketing.d.ts +72 -0
  81. package/dist/models/marketing.d.ts.map +1 -0
  82. package/dist/models/marketing.js +26 -0
  83. package/dist/models/marketing.js.map +1 -0
  84. package/dist/models/message.d.ts +100 -0
  85. package/dist/models/message.d.ts.map +1 -0
  86. package/dist/models/message.js +131 -0
  87. package/dist/models/message.js.map +1 -0
  88. package/dist/models/newtonChat.d.ts +72 -0
  89. package/dist/models/newtonChat.d.ts.map +1 -0
  90. package/dist/models/newtonChat.js +61 -0
  91. package/dist/models/newtonChat.js.map +1 -0
  92. package/dist/models/notification.d.ts +65 -0
  93. package/dist/models/notification.d.ts.map +1 -0
  94. package/dist/models/notification.js +46 -0
  95. package/dist/models/notification.js.map +1 -0
  96. package/dist/models/section.d.ts +102 -0
  97. package/dist/models/section.d.ts.map +1 -0
  98. package/dist/models/section.js +83 -0
  99. package/dist/models/section.js.map +1 -0
  100. package/dist/models/user.d.ts +39 -0
  101. package/dist/models/user.d.ts.map +1 -0
  102. package/dist/models/user.js +38 -0
  103. package/dist/models/user.js.map +1 -0
  104. package/dist/models/worksheet.d.ts +460 -0
  105. package/dist/models/worksheet.d.ts.map +1 -0
  106. package/dist/models/worksheet.js +200 -0
  107. package/dist/models/worksheet.js.map +1 -0
  108. package/dist/pipelines/aiLabChat.d.ts +76 -0
  109. package/dist/pipelines/aiLabChat.d.ts.map +1 -0
  110. package/dist/pipelines/aiLabChat.js +599 -0
  111. package/dist/pipelines/aiLabChat.js.map +1 -0
  112. package/dist/pipelines/aiNewtonChat.d.ts +30 -0
  113. package/dist/pipelines/aiNewtonChat.d.ts.map +1 -0
  114. package/dist/pipelines/aiNewtonChat.js +289 -0
  115. package/dist/pipelines/aiNewtonChat.js.map +1 -0
  116. package/dist/pipelines/gradeWorksheet.d.ts +30 -0
  117. package/dist/pipelines/gradeWorksheet.d.ts.map +1 -0
  118. package/dist/pipelines/gradeWorksheet.js +252 -0
  119. package/dist/pipelines/gradeWorksheet.js.map +1 -0
  120. package/dist/routers/_app.d.ts +1523 -1315
  121. package/dist/routers/_app.d.ts.map +1 -1
  122. package/dist/routers/agenda.d.ts +22 -22
  123. package/dist/routers/agenda.d.ts.map +1 -1
  124. package/dist/routers/agenda.js +4 -65
  125. package/dist/routers/agenda.js.map +1 -1
  126. package/dist/routers/announcement.d.ts +16 -16
  127. package/dist/routers/announcement.d.ts.map +1 -1
  128. package/dist/routers/announcement.js +37 -446
  129. package/dist/routers/announcement.js.map +1 -1
  130. package/dist/routers/assignment.d.ts +300 -378
  131. package/dist/routers/assignment.d.ts.map +1 -1
  132. package/dist/routers/assignment.js +78 -1868
  133. package/dist/routers/assignment.js.map +1 -1
  134. package/dist/routers/attendance.d.ts +19 -9
  135. package/dist/routers/attendance.d.ts.map +1 -1
  136. package/dist/routers/attendance.js +7 -264
  137. package/dist/routers/attendance.js.map +1 -1
  138. package/dist/routers/auth.d.ts +2 -2
  139. package/dist/routers/auth.d.ts.map +1 -1
  140. package/dist/routers/auth.js +29 -354
  141. package/dist/routers/auth.js.map +1 -1
  142. package/dist/routers/class.d.ts +160 -68
  143. package/dist/routers/class.d.ts.map +1 -1
  144. package/dist/routers/class.js +82 -1052
  145. package/dist/routers/class.js.map +1 -1
  146. package/dist/routers/comment.d.ts +6 -42
  147. package/dist/routers/comment.d.ts.map +1 -1
  148. package/dist/routers/comment.js +24 -244
  149. package/dist/routers/comment.js.map +1 -1
  150. package/dist/routers/conversation.d.ts +45 -7
  151. package/dist/routers/conversation.d.ts.map +1 -1
  152. package/dist/routers/conversation.js +19 -327
  153. package/dist/routers/conversation.js.map +1 -1
  154. package/dist/routers/event.d.ts +36 -36
  155. package/dist/routers/event.d.ts.map +1 -1
  156. package/dist/routers/event.js +13 -433
  157. package/dist/routers/event.js.map +1 -1
  158. package/dist/routers/file.d.ts +2 -2
  159. package/dist/routers/file.d.ts.map +1 -1
  160. package/dist/routers/file.js +9 -323
  161. package/dist/routers/file.js.map +1 -1
  162. package/dist/routers/folder.d.ts +21 -14
  163. package/dist/routers/folder.d.ts.map +1 -1
  164. package/dist/routers/folder.js +34 -745
  165. package/dist/routers/folder.js.map +1 -1
  166. package/dist/routers/labChat.d.ts +21 -11
  167. package/dist/routers/labChat.d.ts.map +1 -1
  168. package/dist/routers/labChat.js +22 -570
  169. package/dist/routers/labChat.js.map +1 -1
  170. package/dist/routers/marketing.d.ts +1 -1
  171. package/dist/routers/marketing.d.ts.map +1 -1
  172. package/dist/routers/marketing.js +7 -56
  173. package/dist/routers/marketing.js.map +1 -1
  174. package/dist/routers/message.d.ts +13 -2
  175. package/dist/routers/message.d.ts.map +1 -1
  176. package/dist/routers/message.js +32 -520
  177. package/dist/routers/message.js.map +1 -1
  178. package/dist/routers/newtonChat.d.ts +1 -1
  179. package/dist/routers/newtonChat.d.ts.map +1 -1
  180. package/dist/routers/newtonChat.js +7 -246
  181. package/dist/routers/newtonChat.js.map +1 -1
  182. package/dist/routers/notifications.d.ts +4 -4
  183. package/dist/routers/notifications.d.ts.map +1 -1
  184. package/dist/routers/notifications.js +18 -83
  185. package/dist/routers/notifications.js.map +1 -1
  186. package/dist/routers/section.d.ts +4 -4
  187. package/dist/routers/section.d.ts.map +1 -1
  188. package/dist/routers/section.js +14 -286
  189. package/dist/routers/section.js.map +1 -1
  190. package/dist/routers/user.d.ts +1 -1
  191. package/dist/routers/user.d.ts.map +1 -1
  192. package/dist/routers/user.js +32 -207
  193. package/dist/routers/user.js.map +1 -1
  194. package/dist/routers/worksheet.d.ts +68 -55
  195. package/dist/routers/worksheet.d.ts.map +1 -1
  196. package/dist/routers/worksheet.js +79 -394
  197. package/dist/routers/worksheet.js.map +1 -1
  198. package/dist/seedDatabase.d.ts +1 -1
  199. package/dist/server/pipelines/gradeWorksheet.d.ts +6 -6
  200. package/dist/server/pipelines/gradeWorksheet.d.ts.map +1 -1
  201. package/dist/server/pipelines/gradeWorksheet.js +12 -5
  202. package/dist/server/pipelines/gradeWorksheet.js.map +1 -1
  203. package/dist/services/agenda.d.ts +100 -0
  204. package/dist/services/agenda.d.ts.map +1 -0
  205. package/dist/services/agenda.js +21 -0
  206. package/dist/services/agenda.js.map +1 -0
  207. package/dist/services/announcement.d.ts +135 -0
  208. package/dist/services/announcement.d.ts.map +1 -0
  209. package/dist/services/announcement.js +223 -0
  210. package/dist/services/announcement.js.map +1 -0
  211. package/dist/services/assignment.d.ts +1462 -0
  212. package/dist/services/assignment.d.ts.map +1 -0
  213. package/dist/services/assignment.js +898 -0
  214. package/dist/services/assignment.js.map +1 -0
  215. package/dist/services/attendance.d.ts +93 -0
  216. package/dist/services/attendance.d.ts.map +1 -0
  217. package/dist/services/attendance.js +61 -0
  218. package/dist/services/attendance.js.map +1 -0
  219. package/dist/services/auth.d.ts +68 -0
  220. package/dist/services/auth.d.ts.map +1 -0
  221. package/dist/services/auth.js +218 -0
  222. package/dist/services/auth.js.map +1 -0
  223. package/dist/services/class.d.ts +643 -0
  224. package/dist/services/class.d.ts.map +1 -0
  225. package/dist/services/class.js +486 -0
  226. package/dist/services/class.js.map +1 -0
  227. package/dist/services/comment.d.ts +100 -0
  228. package/dist/services/comment.d.ts.map +1 -0
  229. package/dist/services/comment.js +83 -0
  230. package/dist/services/comment.js.map +1 -0
  231. package/dist/services/conversation.d.ts +159 -0
  232. package/dist/services/conversation.d.ts.map +1 -0
  233. package/dist/services/conversation.js +138 -0
  234. package/dist/services/conversation.js.map +1 -0
  235. package/dist/services/event.d.ts +216 -0
  236. package/dist/services/event.d.ts.map +1 -0
  237. package/dist/services/event.js +168 -0
  238. package/dist/services/event.js.map +1 -0
  239. package/dist/services/file.d.ts +74 -0
  240. package/dist/services/file.d.ts.map +1 -0
  241. package/dist/services/file.js +133 -0
  242. package/dist/services/file.js.map +1 -0
  243. package/dist/services/folder.d.ts +239 -0
  244. package/dist/services/folder.d.ts.map +1 -0
  245. package/dist/services/folder.js +248 -0
  246. package/dist/services/folder.js.map +1 -0
  247. package/dist/services/labChat.d.ts +169 -0
  248. package/dist/services/labChat.d.ts.map +1 -0
  249. package/dist/services/labChat.js +381 -0
  250. package/dist/services/labChat.js.map +1 -0
  251. package/dist/services/marketing.d.ts +50 -0
  252. package/dist/services/marketing.d.ts.map +1 -0
  253. package/dist/services/marketing.js +32 -0
  254. package/dist/services/marketing.js.map +1 -0
  255. package/dist/services/message.d.ts +103 -0
  256. package/dist/services/message.d.ts.map +1 -0
  257. package/dist/services/message.js +422 -0
  258. package/dist/services/message.js.map +1 -0
  259. package/dist/services/newtonChat.d.ts +22 -0
  260. package/dist/services/newtonChat.d.ts.map +1 -0
  261. package/dist/services/newtonChat.js +174 -0
  262. package/dist/services/newtonChat.js.map +1 -0
  263. package/dist/services/notification.d.ts +65 -0
  264. package/dist/services/notification.d.ts.map +1 -0
  265. package/dist/services/notification.js +33 -0
  266. package/dist/services/notification.js.map +1 -0
  267. package/dist/services/section.d.ts +53 -0
  268. package/dist/services/section.d.ts.map +1 -0
  269. package/dist/services/section.js +199 -0
  270. package/dist/services/section.js.map +1 -0
  271. package/dist/services/user.d.ts +48 -0
  272. package/dist/services/user.d.ts.map +1 -0
  273. package/dist/services/user.js +141 -0
  274. package/dist/services/user.js.map +1 -0
  275. package/dist/services/worksheet.d.ts +239 -0
  276. package/dist/services/worksheet.d.ts.map +1 -0
  277. package/dist/services/worksheet.js +235 -0
  278. package/dist/services/worksheet.js.map +1 -0
  279. package/dist/utils/aiUser.d.ts +1 -3
  280. package/dist/utils/aiUser.d.ts.map +1 -1
  281. package/dist/utils/aiUser.js +6 -5
  282. package/dist/utils/aiUser.js.map +1 -1
  283. package/dist/utils/email.d.ts +3 -0
  284. package/dist/utils/email.d.ts.map +1 -1
  285. package/dist/utils/email.js +7 -4
  286. package/dist/utils/email.js.map +1 -1
  287. package/dist/utils/generateInviteCode.d.ts +1 -2
  288. package/dist/utils/generateInviteCode.d.ts.map +1 -1
  289. package/dist/utils/generateInviteCode.js +3 -4
  290. package/dist/utils/generateInviteCode.js.map +1 -1
  291. package/dist/utils/inference.d.ts +3 -0
  292. package/dist/utils/inference.d.ts.map +1 -1
  293. package/dist/utils/inference.js +7 -4
  294. package/dist/utils/inference.js.map +1 -1
  295. package/dist/utils/logger.d.ts +3 -0
  296. package/dist/utils/logger.d.ts.map +1 -1
  297. package/dist/utils/logger.js +5 -2
  298. package/dist/utils/logger.js.map +1 -1
  299. package/dist/utils/prismaErrorHandler.d.ts.map +1 -1
  300. package/dist/utils/prismaErrorHandler.js +5 -2
  301. package/dist/utils/prismaErrorHandler.js.map +1 -1
  302. package/dist/utils/prismaWrapper.d.ts +1 -0
  303. package/dist/utils/prismaWrapper.d.ts.map +1 -1
  304. package/dist/utils/prismaWrapper.js +6 -2
  305. package/dist/utils/prismaWrapper.js.map +1 -1
  306. package/docker-compose.yml +5 -0
  307. package/package.json +4 -3
  308. package/prisma/schema.prisma +1 -1
  309. package/src/index.ts +119 -12
  310. package/src/lib/config/env.ts +6 -0
  311. package/src/lib/fileUpload.ts +0 -1
  312. package/src/lib/googleCloudStorage.ts +17 -0
  313. package/src/lib/pusher.ts +5 -1
  314. package/src/lib/redis.ts +56 -0
  315. package/src/lib/thumbnailGenerator.ts +170 -168
  316. package/src/middleware/auth.ts +80 -137
  317. package/src/models/agenda.ts +46 -0
  318. package/src/models/announcement.ts +134 -0
  319. package/src/models/assignment.ts +322 -0
  320. package/src/models/attendance.ts +208 -0
  321. package/src/models/auth.ts +247 -0
  322. package/src/models/class.ts +703 -0
  323. package/src/models/comment.ts +152 -0
  324. package/src/models/conversation.ts +200 -0
  325. package/src/models/event.ts +177 -0
  326. package/src/models/file.ts +129 -0
  327. package/src/models/folder.ts +225 -0
  328. package/src/models/labChat.ts +213 -0
  329. package/src/models/marketing.ts +45 -0
  330. package/src/models/message.ts +153 -0
  331. package/src/models/newtonChat.ts +70 -0
  332. package/src/models/notification.ts +54 -0
  333. package/src/models/section.ts +98 -0
  334. package/src/models/user.ts +47 -0
  335. package/src/models/worksheet.ts +294 -0
  336. package/src/pipelines/aiLabChat.ts +684 -0
  337. package/src/{server/pipelines → pipelines}/aiNewtonChat.ts +9 -5
  338. package/src/{server/pipelines → pipelines}/gradeWorksheet.ts +25 -14
  339. package/src/routers/agenda.ts +3 -66
  340. package/src/routers/announcement.ts +54 -495
  341. package/src/routers/assignment.ts +126 -2018
  342. package/src/routers/attendance.ts +15 -276
  343. package/src/routers/auth.ts +79 -442
  344. package/src/routers/class.ts +263 -1187
  345. package/src/routers/comment.ts +61 -288
  346. package/src/routers/conversation.ts +51 -360
  347. package/src/routers/event.ts +50 -481
  348. package/src/routers/file.ts +45 -368
  349. package/src/routers/folder.ts +107 -836
  350. package/src/routers/labChat.ts +35 -604
  351. package/src/routers/marketing.ts +35 -77
  352. package/src/routers/message.ts +54 -567
  353. package/src/routers/newtonChat.ts +17 -278
  354. package/src/routers/notifications.ts +32 -82
  355. package/src/routers/section.ts +46 -330
  356. package/src/routers/user.ts +49 -227
  357. package/src/routers/worksheet.ts +215 -503
  358. package/src/services/agenda.ts +21 -0
  359. package/src/services/announcement.ts +290 -0
  360. package/src/services/assignment.ts +1198 -0
  361. package/src/services/attendance.ts +85 -0
  362. package/src/services/auth.ts +277 -0
  363. package/src/services/class.ts +629 -0
  364. package/src/services/comment.ts +106 -0
  365. package/src/services/conversation.ts +213 -0
  366. package/src/services/event.ts +231 -0
  367. package/src/services/file.ts +167 -0
  368. package/src/services/folder.ts +316 -0
  369. package/src/services/labChat.ts +458 -0
  370. package/src/services/marketing.ts +57 -0
  371. package/src/services/message.ts +554 -0
  372. package/src/services/newtonChat.ts +222 -0
  373. package/src/services/notification.ts +50 -0
  374. package/src/services/section.ts +283 -0
  375. package/src/services/user.ts +172 -0
  376. package/src/services/worksheet.ts +358 -0
  377. package/src/utils/aiUser.ts +4 -3
  378. package/src/utils/email.ts +5 -3
  379. package/src/utils/generateInviteCode.ts +1 -3
  380. package/src/utils/inference.ts +5 -2
  381. package/src/utils/logger.ts +3 -1
  382. package/src/utils/prismaErrorHandler.ts +3 -0
  383. package/src/utils/prismaWrapper.ts +4 -0
  384. package/tests/globalSetup.ts +62 -0
  385. package/tests/helpers.ts +22 -0
  386. package/tests/middleware/security.test.ts +42 -0
  387. package/tests/routers/agenda.test.ts +138 -0
  388. package/tests/routers/announcement.test.ts +490 -0
  389. package/tests/routers/assignment.test.ts +837 -0
  390. package/tests/{attendance.test.ts → routers/attendance.test.ts} +6 -14
  391. package/tests/routers/auth.test.ts +171 -0
  392. package/tests/{class.test.ts → routers/class.test.ts} +131 -85
  393. package/tests/routers/comment.test.ts +126 -0
  394. package/tests/routers/conversation.test.ts +145 -0
  395. package/tests/{event.test.ts → routers/event.test.ts} +93 -32
  396. package/tests/routers/folder.test.ts +178 -0
  397. package/tests/routers/labChat.test.ts +115 -0
  398. package/tests/routers/marketing.test.ts +59 -0
  399. package/tests/routers/message.test.ts +123 -0
  400. package/tests/routers/notification.test.ts +69 -0
  401. package/tests/{section.test.ts → routers/section.test.ts} +5 -13
  402. package/tests/server/rateLimit.test.ts +73 -0
  403. package/tests/setup.ts +18 -92
  404. package/tests/user.test.ts +9 -31
  405. package/tests/utils/aiUser.test.ts +22 -0
  406. package/tests/utils/generateInviteCode.test.ts +24 -0
  407. package/tests/utils/logger.test.ts +74 -0
  408. package/tests/utils/prismaErrorHandler.test.ts +101 -0
  409. package/tests/utils/prismaWrapper.test.ts +82 -0
  410. package/tests/worksheet.test.ts +181 -0
  411. package/vitest.config.ts +6 -3
  412. package/vitest.unit.config.ts +21 -0
  413. package/TODO.md +0 -2
  414. package/coverage/base.css +0 -224
  415. package/coverage/block-navigation.js +0 -87
  416. package/coverage/clover.xml +0 -12110
  417. package/coverage/coverage-final.json +0 -44
  418. package/coverage/favicon.png +0 -0
  419. package/coverage/index.html +0 -221
  420. package/coverage/prettify.css +0 -1
  421. package/coverage/prettify.js +0 -2
  422. package/coverage/server/index.html +0 -116
  423. package/coverage/server/src/exportType.ts.html +0 -109
  424. package/coverage/server/src/index.html +0 -161
  425. package/coverage/server/src/index.ts.html +0 -1702
  426. package/coverage/server/src/instrument.ts.html +0 -130
  427. package/coverage/server/src/lib/config/env.ts.html +0 -448
  428. package/coverage/server/src/lib/config/index.html +0 -116
  429. package/coverage/server/src/lib/fileUpload.ts.html +0 -1138
  430. package/coverage/server/src/lib/googleCloudStorage.ts.html +0 -334
  431. package/coverage/server/src/lib/index.html +0 -206
  432. package/coverage/server/src/lib/jsonConversion.ts.html +0 -2323
  433. package/coverage/server/src/lib/jsonStyles.ts.html +0 -193
  434. package/coverage/server/src/lib/notificationHandler.ts.html +0 -193
  435. package/coverage/server/src/lib/pusher.ts.html +0 -121
  436. package/coverage/server/src/lib/thumbnailGenerator.ts.html +0 -592
  437. package/coverage/server/src/middleware/auth.ts.html +0 -646
  438. package/coverage/server/src/middleware/index.html +0 -146
  439. package/coverage/server/src/middleware/logging.ts.html +0 -244
  440. package/coverage/server/src/middleware/security.ts.html +0 -271
  441. package/coverage/server/src/routers/_app.ts.html +0 -232
  442. package/coverage/server/src/routers/agenda.ts.html +0 -319
  443. package/coverage/server/src/routers/announcement.ts.html +0 -3481
  444. package/coverage/server/src/routers/assignment.ts.html +0 -7633
  445. package/coverage/server/src/routers/attendance.ts.html +0 -1030
  446. package/coverage/server/src/routers/auth.ts.html +0 -1081
  447. package/coverage/server/src/routers/class.ts.html +0 -3535
  448. package/coverage/server/src/routers/comment.ts.html +0 -991
  449. package/coverage/server/src/routers/conversation.ts.html +0 -982
  450. package/coverage/server/src/routers/event.ts.html +0 -1609
  451. package/coverage/server/src/routers/file.ts.html +0 -1144
  452. package/coverage/server/src/routers/folder.ts.html +0 -2797
  453. package/coverage/server/src/routers/index.html +0 -386
  454. package/coverage/server/src/routers/labChat.ts.html +0 -3073
  455. package/coverage/server/src/routers/marketing.ts.html +0 -340
  456. package/coverage/server/src/routers/message.ts.html +0 -1912
  457. package/coverage/server/src/routers/notifications.ts.html +0 -364
  458. package/coverage/server/src/routers/section.ts.html +0 -1120
  459. package/coverage/server/src/routers/user.ts.html +0 -862
  460. package/coverage/server/src/routers/worksheet.ts.html +0 -1729
  461. package/coverage/server/src/trpc.ts.html +0 -397
  462. package/coverage/server/src/types/index.html +0 -116
  463. package/coverage/server/src/types/trpc.ts.html +0 -127
  464. package/coverage/server/src/utils/aiUser.ts.html +0 -280
  465. package/coverage/server/src/utils/email.ts.html +0 -121
  466. package/coverage/server/src/utils/generateInviteCode.ts.html +0 -106
  467. package/coverage/server/src/utils/index.html +0 -206
  468. package/coverage/server/src/utils/inference.ts.html +0 -709
  469. package/coverage/server/src/utils/logger.ts.html +0 -664
  470. package/coverage/server/src/utils/prismaErrorHandler.ts.html +0 -907
  471. package/coverage/server/src/utils/prismaWrapper.ts.html +0 -355
  472. package/coverage/server/vitest.config.ts.html +0 -196
  473. package/coverage/sort-arrow-sprite.png +0 -0
  474. package/coverage/sorter.js +0 -210
  475. package/src/lib/notificationHandler.ts +0 -36
  476. package/src/server/pipelines/aiLabChat.ts +0 -507
  477. package/tests/announcement.test.ts +0 -164
  478. package/tests/assignment.test.ts +0 -296
  479. package/tests/auth.test.ts +0 -48
@@ -0,0 +1,9 @@
1
+ # Raise the file limit
2
+ reviews:
3
+ review_status: true
4
+ path_filters:
5
+ # Exclude paths you don't want reviewed
6
+ - "!**/node_modules/**"
7
+ - "!**/dist/**"
8
+ - "!**/*.lock"
9
+ - "!**/package-lock.json"
package/.env.example CHANGED
@@ -28,12 +28,20 @@ YOUR_PRIVATE_KEY
28
28
  GOOGLE_CLOUD_BUCKET_NAME="your-bucket-name"
29
29
 
30
30
  # Pusher Configuration
31
- # Required for real-time notifications
31
+ # Required for real-time notifications (chat, worksheet grading)
32
32
  PUSHER_APP_ID="your-app-id"
33
33
  PUSHER_KEY="your-key"
34
34
  PUSHER_SECRET="your-secret"
35
35
  PUSHER_CLUSTER="your-cluster"
36
36
 
37
+ # Frontend must set these to match (for real-time chat to work):
38
+ # NEXT_PUBLIC_PUSHER_KEY=<same as PUSHER_KEY>
39
+ # NEXT_PUBLIC_PUSHER_CLUSTER=<same as PUSHER_CLUSTER>
40
+ # NEXT_PUBLIC_API_URL=<backend URL, e.g. http://localhost:3001>
41
+
42
+ # Redis (optional - for caching, rate limiting, etc.)
43
+ REDIS_URL="redis://localhost:6379"
44
+
37
45
  # AI/Inference Configuration
38
46
  # Required for AI features (lab chat, etc.)
39
47
  INFERENCE_API_KEY="your-api-key"
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"/","sources":["index.ts"],"names":[],"mappings":"AAsBA,OAAO,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"/","sources":["index.ts"],"names":[],"mappings":"AAwBA,OAAO,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a128ff07-a361-51b4-b86d-b00ea86ed03a")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="e28b4205-9ed2-5148-b94c-3326b3073261")}catch(e){}}();
3
3
  import express from 'express';
4
4
  import { createServer } from 'http';
5
5
  import { Server } from 'socket.io';
@@ -11,6 +11,8 @@ import { logger } from './utils/logger.js';
11
11
  import { setupSocketHandlers } from './socket/handlers.js';
12
12
  import { bucket } from './lib/googleCloudStorage.js';
13
13
  import { prisma } from './lib/prisma.js';
14
+ import { pusher } from './lib/pusher.js';
15
+ import { connectRedis, disconnectRedis } from './lib/redis.js';
14
16
  import { authLimiter, generalLimiter, helmetConfig, uploadLimiter } from './middleware/security.js';
15
17
  import * as Sentry from "@sentry/node";
16
18
  import { env } from './lib/config/env.js';
@@ -20,6 +22,8 @@ import "./instrument.js";
20
22
  const app = express();
21
23
  app.use(helmetConfig);
22
24
  app.use(compression());
25
+ app.use(express.json());
26
+ app.use(express.urlencoded({ extended: true }));
23
27
  app.use((req, res, next) => {
24
28
  const requestId = uuidv4();
25
29
  res.setHeader('X-Request-ID', requestId);
@@ -29,6 +33,8 @@ const allowedOrigins = env.NODE_ENV === 'production'
29
33
  ? [
30
34
  'https://www.studious.sh',
31
35
  'https://studious.sh',
36
+ 'https://dev.studious.sh',
37
+ 'https://www.dev.studious.sh',
32
38
  env.NEXT_PUBLIC_APP_URL,
33
39
  'http://localhost:3000',
34
40
  ].filter(Boolean)
@@ -113,6 +119,92 @@ app.get('/health', async (req, res) => {
113
119
  });
114
120
  }
115
121
  });
122
+ // Pusher channel auth (for private-* and presence-* channels)
123
+ // Token from: x-user header, or cookie (same-origin requests send cookies automatically)
124
+ app.post('/api/pusher/auth', async (req, res) => {
125
+ try {
126
+ let token = req.headers['x-user'];
127
+ if (!token && req.headers.cookie) {
128
+ const cookieName = env.PUSHER_AUTH_COOKIE_NAME || 'token';
129
+ const match = req.headers.cookie.match(new RegExp(`${cookieName}=([^;]+)`));
130
+ token = match?.[1]?.trim();
131
+ }
132
+ const { socket_id, channel_name } = req.body;
133
+ if (!socket_id || !channel_name) {
134
+ return res.status(400).json({ error: 'socket_id and channel_name required' });
135
+ }
136
+ if (!token) {
137
+ return res.status(401).json({ error: 'Authentication required' });
138
+ }
139
+ const user = await prisma.user.findFirst({
140
+ where: { sessions: { some: { id: token } } },
141
+ select: { id: true, username: true },
142
+ });
143
+ if (!user) {
144
+ return res.status(401).json({ error: 'Invalid or expired session' });
145
+ }
146
+ // Verify channel access for private-conversation-* channels
147
+ if (channel_name.startsWith('private-conversation-')) {
148
+ const conversationId = channel_name.replace('private-conversation-', '');
149
+ const member = await prisma.conversationMember.findFirst({
150
+ where: { conversationId, userId: user.id },
151
+ });
152
+ if (!member) {
153
+ return res.status(403).json({ error: 'Not a member of this conversation' });
154
+ }
155
+ }
156
+ if (channel_name.startsWith('private-worksheet-')) {
157
+ const worksheetId = channel_name.replace('private-worksheet-', '');
158
+ const worksheet = await prisma.studentWorksheetResponse.findFirst({
159
+ where: { id: worksheetId, OR: [
160
+ { studentId: user.id },
161
+ { submission: { assignment: { class: { teachers: { some: { id: user.id } } } } } },
162
+ ] },
163
+ });
164
+ if (!worksheet) {
165
+ return res.status(403).json({ error: 'No access to this worksheet' });
166
+ }
167
+ }
168
+ if (channel_name.startsWith('private-teacher-')) {
169
+ const classId = channel_name.replace('private-teacher-', '');
170
+ const isTeacher = await prisma.class.findFirst({
171
+ where: { id: classId, teachers: { some: { id: user.id } } },
172
+ });
173
+ if (!isTeacher) {
174
+ return res.status(403).json({ error: 'Not a teacher of this class' });
175
+ }
176
+ }
177
+ // Verify channel access for private-class-* channels
178
+ // if (channel_name.startsWith('private-class-')) {
179
+ // const classId = channel_name.replace('private-class-', '');
180
+ // const isMember = await prisma.class.findFirst({
181
+ // where: {
182
+ // id: classId,
183
+ // OR: [
184
+ // { students: { some: { id: user.id } } },
185
+ // { teachers: { some: { id: user.id } } },
186
+ // ],
187
+ // },
188
+ // });
189
+ // if (!isMember) {
190
+ // return res.status(403).json({ error: 'Not a member of this class' });
191
+ // }
192
+ // }
193
+ if (channel_name.startsWith('presence-')) {
194
+ const authResponse = pusher.authorizeChannel(socket_id, channel_name, {
195
+ user_id: user.id,
196
+ user_info: { username: user.username },
197
+ });
198
+ return res.json(authResponse);
199
+ }
200
+ const authResponse = pusher.authorizeChannel(socket_id, channel_name);
201
+ return res.json(authResponse);
202
+ }
203
+ catch (error) {
204
+ logger.error('Pusher auth error', { error });
205
+ return res.status(500).json({ error: 'Authentication failed' });
206
+ }
207
+ });
116
208
  // Setup Socket.IO
117
209
  const io = new Server(httpServer, {
118
210
  cors: {
@@ -404,10 +496,12 @@ Sentry.setupExpressErrorHandler(app);
404
496
  // res.end(res.sentry + "\n");
405
497
  // });
406
498
  const PORT = env.PORT || 3001;
407
- httpServer.listen(PORT, () => {
408
- logger.info(`Server running on port ${PORT}`, {
409
- port: PORT,
410
- services: ['tRPC', 'Socket.IO']
499
+ connectRedis().then(() => {
500
+ httpServer.listen(PORT, () => {
501
+ logger.info(`Server running on port ${PORT}`, {
502
+ port: PORT,
503
+ services: ['tRPC', 'Socket.IO', env.REDIS_URL ? 'Redis' : null].filter(Boolean),
504
+ });
411
505
  });
412
506
  });
413
507
  // log all env variables
@@ -433,13 +527,13 @@ const gracefulShutdown = (signal) => {
433
527
  logger.info('HTTP server closed');
434
528
  io.close(() => {
435
529
  logger.info('Socket.IO server closed');
436
- prisma.$disconnect().then(() => {
530
+ disconnectRedis().then(() => prisma.$disconnect().then(() => {
437
531
  logger.info('Database connections closed');
438
532
  process.exit(0);
439
533
  }).catch((err) => {
440
534
  logger.error('Error disconnecting from database', { error: err });
441
535
  process.exit(1);
442
- });
536
+ }));
443
537
  });
444
538
  });
445
539
  // Force shutdown after 10 seconds
@@ -451,4 +545,4 @@ const gracefulShutdown = (signal) => {
451
545
  process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
452
546
  process.on('SIGINT', () => gracefulShutdown('SIGINT'));
453
547
  //# sourceMappingURL=index.js.map
454
- //# debugId=a128ff07-a361-51b4-b86d-b00ea86ed03a
548
+ //# debugId=e28b4205-9ed2-5148-b94c-3326b3073261
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["index.ts"],"sourceRoot":"/","sourcesContent":["import express from 'express';\nimport type { Request, Response } from 'express';\nimport { createServer } from 'http';\nimport { Server } from 'socket.io';\nimport cors from 'cors';\nimport dotenv from 'dotenv';\nimport { createExpressMiddleware } from '@trpc/server/adapters/express';\nimport { appRouter } from './routers/_app.js';\nimport { createTRPCContext, createCallerFactory } from './trpc.js';\nimport { logger } from './utils/logger.js';\nimport { setupSocketHandlers } from './socket/handlers.js';\nimport { bucket } from './lib/googleCloudStorage.js';\nimport { prisma } from './lib/prisma.js';\n\nimport { authLimiter, generalLimiter, helmetConfig, uploadLimiter } from './middleware/security.js';\n\nimport * as Sentry from \"@sentry/node\";\nimport { env } from './lib/config/env.js';\nimport compression from 'compression';\nimport { v4 as uuidv4 } from 'uuid';\n\n\nimport \"./instrument.js\";\nimport { openAIClient } from './utils/inference.js';\n\nconst app = express();\n\napp.use(helmetConfig);\napp.use(compression());\n\napp.use((req, res, next) => {\n const requestId = uuidv4();\n res.setHeader('X-Request-ID', requestId);\n next();\n});\n\nconst allowedOrigins = env.NODE_ENV === 'production'\n? [\n 'https://www.studious.sh',\n 'https://studious.sh',\n env.NEXT_PUBLIC_APP_URL,\n 'http://localhost:3000',\n\n ].filter(Boolean)\n: [\n 'http://localhost:3000',\n 'http://localhost:3001',\n 'http://127.0.0.1:3000',\n 'http://127.0.0.1:3001',\n\n env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'\n ];\n\n// CORS middleware\napp.use(cors({\n origin: allowedOrigins,\n credentials: true,\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],\n allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With', 'x-user'],\n preflightContinue: false, // Important: stop further handling of OPTIONS\n optionsSuccessStatus: 204, // Recommended for modern browsers\n\n}));\n\napp.use(generalLimiter);\n\n// CORS debugging middleware\napp.use((req, res, next) => {\n if (req.method === 'OPTIONS' || req.path.includes('trpc')) {\n logger.info('CORS Request', {\n method: req.method,\n path: req.path,\n origin: req.headers.origin,\n userAgent: req.headers['user-agent']\n });\n }\n next();\n});\n\n// Response time logging middleware\napp.use((req, res, next) => {\n const start = Date.now();\n res.on('finish', () => {\n const duration = Date.now() - start;\n logger.info('Request completed', {\n method: req.method,\n path: req.path,\n statusCode: res.statusCode,\n duration: `${duration}ms`\n });\n });\n next();\n});\n\n// app.use(\"/panel\", async (_, res) => {\n// if (env.NODE_ENV !== \"development\") {\n// return res.status(404).send(\"Not Found\");\n// }\n\n// // Dynamically import renderTrpcPanel only in development\n// const { renderTrpcPanel } = await import(\"trpc-ui\");\n\n// return res.send(\n// renderTrpcPanel(appRouter, {\n// url: \"/trpc\", // Base url of your trpc server\n// meta: {\n// title: \"Studious Backend\",\n// description:\n// \"This is the backend for the Studious application.\",\n// },\n// })\n// );\n// });\n\n\n// Create HTTP server\nconst httpServer = createServer(app);\n\napp.get('/health', async (req, res) => {\n\n try {\n // Check database connectivity\n await prisma.$queryRaw`SELECT 1`;\n \n res.status(200).json({ \n status: 'OK',\n timestamp: new Date().toISOString(),\n uptime: process.uptime(),\n database: 'connected'\n });\n } catch (error) {\n res.status(503).json({ \n status: 'ERROR',\n database: 'disconnected',\n error: error instanceof Error ? error.message : 'Unknown error'\n });\n }\n});\n\n// Setup Socket.IO\nconst io = new Server(httpServer, {\n cors: {\n origin: [\n 'http://localhost:3000', // Frontend development server\n 'http://localhost:3001', // Server port\n 'http://127.0.0.1:3000', // Alternative localhost\n 'http://127.0.0.1:3001', // Alternative localhost\n 'https://www.studious.sh', // Production frontend\n 'https://studious.sh', // Production frontend (without www)\n env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'\n ],\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],\n credentials: true,\n allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With', 'Access-Control-Allow-Origin', 'x-user']\n },\n transports: ['websocket', 'polling'],\n pingTimeout: 60000,\n pingInterval: 25000,\n connectTimeout: 45000,\n path: '/socket.io/',\n allowEIO3: true\n});\n\n// Add server-level logging\nio.engine.on('connection_error', (err: Error) => {\n logger.error('Socket connection error', { error: err.message });\n});\n\n// Setup socket handlers\nsetupSocketHandlers(io);\n\n// File serving endpoint for secure file access\napp.get('/api/files/:fileId', async (req, res) => {\n try {\n const fileId = decodeURIComponent(req.params.fileId);\n // console.log('File request:', { fileId, originalPath: req.params.fileId });\n \n // Get user from request headers\n const userHeader = req.headers['x-user'];\n if (!userHeader) {\n return res.status(401).json({ error: 'Authentication required' });\n }\n\n const token = typeof userHeader === 'string' ? userHeader : userHeader[0];\n\n // Find user by session token\n const user = await prisma.user.findFirst({\n where: {\n sessions: {\n some: {\n id: token\n }\n }\n },\n select: {\n id: true,\n username: true,\n }\n });\n\n if (!user) {\n return res.status(401).json({ error: 'Invalid or expired session' });\n }\n\n // Find file in database by path\n const fileRecord = await prisma.file.findFirst({\n where: { id: fileId },\n include: {\n user: true,\n assignment: {\n include: {\n class: {\n include: {\n students: true,\n teachers: true\n }\n }\n }\n },\n submission: {\n include: {\n student: true,\n assignment: {\n include: {\n class: {\n include: {\n teachers: true\n }\n }\n }\n }\n }\n },\n annotations: {\n include: {\n student: true,\n assignment: {\n include: {\n class: {\n include: {\n teachers: true\n }\n }\n }\n }\n }\n },\n folder: {\n include: {\n class: {\n include: {\n students: true,\n teachers: true\n }\n }\n }\n },\n classDraft: {\n include: {\n students: true,\n teachers: true\n }\n }\n }\n });\n\n if (!fileRecord) {\n return res.status(404).json({ error: 'File not found in database' });\n }\n\n // Check if user has permission to access this file\n let hasPermission = false;\n\n // Check if user created the file\n if (fileRecord.userId === user.id) {\n hasPermission = true;\n }\n\n // Check if file is related to a class where user is a member\n if (!hasPermission) {\n // Check assignment files\n if (fileRecord.assignment?.class) {\n const classData = fileRecord.assignment.class;\n const isStudent = classData.students.some(student => student.id === user.id);\n const isTeacher = classData.teachers.some(teacher => teacher.id === user.id);\n if (isStudent || isTeacher) {\n hasPermission = true;\n }\n }\n\n if (!hasPermission && fileRecord.annotations) {\n const annotation = fileRecord.annotations;\n if (annotation.studentId === user.id) {\n hasPermission = true;\n } else if (annotation.assignment?.class?.teachers.some(teacher => teacher.id === user.id)) {\n hasPermission = true;\n }\n }\n\n // Check submission files (student can access their own submissions, teachers can access all submissions in their class)\n if (!hasPermission && fileRecord.submission) {\n const submission = fileRecord.submission;\n if (submission.studentId === user.id) {\n hasPermission = true; // Student accessing their own submission\n } else if (submission.assignment?.class?.teachers.some(teacher => teacher.id === user.id)) {\n hasPermission = true; // Teacher accessing submission in their class\n }\n }\n\n // Check folder files\n if (!hasPermission && fileRecord.folder?.class) {\n const classData = fileRecord.folder.class;\n const isStudent = classData.students.some(student => student.id === user.id);\n const isTeacher = classData.teachers.some(teacher => teacher.id === user.id);\n if (isStudent || isTeacher) {\n hasPermission = true;\n }\n }\n\n // Check class draft files\n if (!hasPermission && fileRecord.classDraft) {\n const classData = fileRecord.classDraft;\n const isStudent = classData.students.some(student => student.id === user.id);\n const isTeacher = classData.teachers.some(teacher => teacher.id === user.id);\n if (isStudent || isTeacher) {\n hasPermission = true;\n }\n }\n }\n\n if (!hasPermission) {\n return res.status(403).json({ error: 'Access denied - insufficient permissions' });\n }\n \n const filePath = fileRecord.path;\n \n // Get file from Google Cloud Storage\n const file = bucket.file(filePath);\n const [exists] = await file.exists();\n \n if (!exists) {\n return res.status(404).json({ error: 'File not found in storage', filePath });\n }\n \n // Get file metadata\n const [metadata] = await file.getMetadata();\n \n // Set appropriate headers\n res.set({\n 'Content-Type': metadata.contentType || 'application/octet-stream',\n 'Content-Length': metadata.size,\n 'Cache-Control': 'public, max-age=31536000', // 1 year cache\n 'ETag': metadata.etag,\n });\n \n // Stream file to response\n const stream = file.createReadStream();\n stream.pipe(res);\n \n stream.on('error', (error) => {\n logger.error('Error streaming file:', {error});\n if (!res.headersSent) {\n res.status(500).json({ error: 'Error streaming file' });\n }\n });\n \n } catch (error) {\n logger.error('Error serving file:', {error});\n res.status(500).json({ error: 'Internal server error' });\n }\n});\n\napp.use('/trpc/auth.login', authLimiter);\napp.use('/trpc/auth.register', authLimiter);\n\n// File upload endpoint for secure file uploads (supports both POST and PUT)\napp.post('/api/upload/:filePath', uploadLimiter, async (req, res) => {\n handleFileUpload(req, res);\n});\n\napp.put('/api/upload/:filePath', uploadLimiter, async (req, res) => {\n handleFileUpload(req, res);\n});\n\nfunction handleFileUpload(req: any, res: any) {\n try {\n const filePath = decodeURIComponent(req.params.filePath);\n \n // Set CORS headers for upload endpoint\n const origin = req.headers.origin;\n const allowedOrigins = [\n 'http://localhost:3000',\n 'http://localhost:3001', \n 'http://127.0.0.1:3000',\n 'http://127.0.0.1:3001',\n 'https://www.studious.sh', // Production frontend\n 'https://studious.sh', // Production frontend (without www)\n env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'\n ];\n \n if (origin && allowedOrigins.includes(origin)) {\n res.header('Access-Control-Allow-Origin', origin);\n } else {\n res.header('Access-Control-Allow-Origin', 'http://localhost:3000');\n }\n \n res.header('Access-Control-Allow-Credentials', 'true');\n \n // Get content type from headers\n const contentType = req.headers['content-type'] || 'application/octet-stream';\n \n // Create a new file in the bucket\n const file = bucket.file(filePath);\n \n // Create a write stream to Google Cloud Storage\n const writeStream = file.createWriteStream({\n metadata: {\n contentType,\n },\n });\n \n // Handle stream events\n writeStream.on('error', (error) => {\n logger.error('Error uploading file:', {error});\n if (!res.headersSent) {\n res.status(500).json({ error: 'Error uploading file' });\n }\n });\n \n writeStream.on('finish', () => {\n res.status(200).json({ \n success: true, \n filePath,\n message: 'File uploaded successfully' \n });\n });\n \n // Pipe the request body to the write stream\n req.pipe(writeStream);\n \n } catch (error) {\n logger.error('Error handling file upload:', {error});\n res.status(500).json({ error: 'Internal server error' });\n }\n}\n\n// Create caller\nconst createCaller = createCallerFactory(appRouter);\n\n// Setup tRPC middleware\napp.use(\n '/trpc',\n createExpressMiddleware({\n router: appRouter,\n createContext: async ({ req, res }: { req: Request; res: Response }) => {\n return createTRPCContext({ req, res });\n },\n })\n);\n\n// IMPORTANT: Sentry error handler must be added AFTER all other middleware and routes\n// but BEFORE any other error handlers\nSentry.setupExpressErrorHandler(app);\n\n// app.use(function onError(err, req, res, next) {\n// // The error id is attached to `res.sentry` to be returned\n// // and optionally displayed to the user for support.\n// res.statusCode = 500;\n// res.end(res.sentry + \"\\n\");\n// });\n\n\nconst PORT = env.PORT || 3001;\n\nhttpServer.listen(PORT, () => {\n logger.info(`Server running on port ${PORT}`, { \n port: PORT,\n services: ['tRPC', 'Socket.IO']\n });\n}); \n\n// log all env variables\nlogger.info('Configurations', {\n NODE_ENV: env.NODE_ENV,\n PORT: env.PORT,\n NEXT_PUBLIC_APP_URL: env.NEXT_PUBLIC_APP_URL,\n LOG_MODE: env.LOG_MODE,\n});\n\n// Log CORS configuration\nlogger.info('CORS Configuration', {\n allowedOrigins: [\n 'http://localhost:3000',\n 'http://localhost:3001', \n 'http://127.0.0.1:3000',\n 'http://127.0.0.1:3001',\n env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'\n ]\n});\n\nconst gracefulShutdown = (signal: string) => {\n logger.info(`Received ${signal}, shutting down gracefully`);\n \n httpServer.close(() => {\n logger.info('HTTP server closed');\n \n io.close(() => {\n logger.info('Socket.IO server closed');\n \n prisma.$disconnect().then(() => {\n logger.info('Database connections closed');\n process.exit(0);\n }).catch((err) => {\n logger.error('Error disconnecting from database', { error: err });\n process.exit(1);\n });\n });\n });\n \n // Force shutdown after 10 seconds\n setTimeout(() => {\n logger.error('Forced shutdown after timeout');\n process.exit(1);\n }, 10000);\n};\n\nprocess.on('SIGTERM', () => gracefulShutdown('SIGTERM'));\nprocess.on('SIGINT', () => gracefulShutdown('SIGINT'));"],"names":[],"mappings":"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","debug_id":"a128ff07-a361-51b4-b86d-b00ea86ed03a"}
1
+ {"version":3,"file":"index.js","sources":["index.ts"],"sourceRoot":"/","sourcesContent":["import express from 'express';\nimport type { Request, Response } from 'express';\nimport { createServer } from 'http';\nimport { Server } from 'socket.io';\nimport cors from 'cors';\nimport dotenv from 'dotenv';\nimport { createExpressMiddleware } from '@trpc/server/adapters/express';\nimport { appRouter } from './routers/_app.js';\nimport { createTRPCContext, createCallerFactory } from './trpc.js';\nimport { logger } from './utils/logger.js';\nimport { setupSocketHandlers } from './socket/handlers.js';\nimport { bucket } from './lib/googleCloudStorage.js';\nimport { prisma } from './lib/prisma.js';\nimport { pusher } from './lib/pusher.js';\nimport { connectRedis, disconnectRedis } from './lib/redis.js';\n\nimport { authLimiter, generalLimiter, helmetConfig, uploadLimiter } from './middleware/security.js';\n\nimport * as Sentry from \"@sentry/node\";\nimport { env } from './lib/config/env.js';\nimport compression from 'compression';\nimport { v4 as uuidv4 } from 'uuid';\n\n\nimport \"./instrument.js\";\nimport { openAIClient } from './utils/inference.js';\n\nconst app = express();\n\napp.use(helmetConfig);\napp.use(compression());\napp.use(express.json());\napp.use(express.urlencoded({ extended: true }));\n\napp.use((req, res, next) => {\n const requestId = uuidv4();\n res.setHeader('X-Request-ID', requestId);\n next();\n});\n\nconst allowedOrigins = env.NODE_ENV === 'production'\n? [\n 'https://www.studious.sh',\n 'https://studious.sh',\n 'https://dev.studious.sh',\n 'https://www.dev.studious.sh',\n env.NEXT_PUBLIC_APP_URL,\n 'http://localhost:3000',\n\n ].filter(Boolean)\n: [\n 'http://localhost:3000',\n 'http://localhost:3001',\n 'http://127.0.0.1:3000',\n 'http://127.0.0.1:3001',\n\n env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'\n ];\n\n// CORS middleware\napp.use(cors({\n origin: allowedOrigins,\n credentials: true,\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],\n allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With', 'x-user'],\n preflightContinue: false, // Important: stop further handling of OPTIONS\n optionsSuccessStatus: 204, // Recommended for modern browsers\n\n}));\n\napp.use(generalLimiter);\n\n// CORS debugging middleware\napp.use((req, res, next) => {\n if (req.method === 'OPTIONS' || req.path.includes('trpc')) {\n logger.info('CORS Request', {\n method: req.method,\n path: req.path,\n origin: req.headers.origin,\n userAgent: req.headers['user-agent']\n });\n }\n next();\n});\n\n// Response time logging middleware\napp.use((req, res, next) => {\n const start = Date.now();\n res.on('finish', () => {\n const duration = Date.now() - start;\n logger.info('Request completed', {\n method: req.method,\n path: req.path,\n statusCode: res.statusCode,\n duration: `${duration}ms`\n });\n });\n next();\n});\n\n// app.use(\"/panel\", async (_, res) => {\n// if (env.NODE_ENV !== \"development\") {\n// return res.status(404).send(\"Not Found\");\n// }\n\n// // Dynamically import renderTrpcPanel only in development\n// const { renderTrpcPanel } = await import(\"trpc-ui\");\n\n// return res.send(\n// renderTrpcPanel(appRouter, {\n// url: \"/trpc\", // Base url of your trpc server\n// meta: {\n// title: \"Studious Backend\",\n// description:\n// \"This is the backend for the Studious application.\",\n// },\n// })\n// );\n// });\n\n\n// Create HTTP server\nconst httpServer = createServer(app);\n\napp.get('/health', async (req, res) => {\n\n try {\n // Check database connectivity\n await prisma.$queryRaw`SELECT 1`;\n \n res.status(200).json({ \n status: 'OK',\n timestamp: new Date().toISOString(),\n uptime: process.uptime(),\n database: 'connected'\n });\n } catch (error) {\n res.status(503).json({ \n status: 'ERROR',\n database: 'disconnected',\n error: error instanceof Error ? error.message : 'Unknown error'\n });\n }\n});\n\n// Pusher channel auth (for private-* and presence-* channels)\n// Token from: x-user header, or cookie (same-origin requests send cookies automatically)\napp.post('/api/pusher/auth', async (req, res) => {\n try {\n let token = req.headers['x-user'] as string | undefined;\n if (!token && req.headers.cookie) {\n const cookieName = env.PUSHER_AUTH_COOKIE_NAME || 'token';\n const match = req.headers.cookie.match(new RegExp(`${cookieName}=([^;]+)`));\n token = match?.[1]?.trim();\n }\n const { socket_id, channel_name } = req.body as { socket_id?: string; channel_name?: string };\n\n if (!socket_id || !channel_name) {\n return res.status(400).json({ error: 'socket_id and channel_name required' });\n }\n\n if (!token) {\n return res.status(401).json({ error: 'Authentication required' });\n }\n\n const user = await prisma.user.findFirst({\n where: { sessions: { some: { id: token } } },\n select: { id: true, username: true },\n });\n\n if (!user) {\n return res.status(401).json({ error: 'Invalid or expired session' });\n }\n\n // Verify channel access for private-conversation-* channels\n if (channel_name.startsWith('private-conversation-')) {\n const conversationId = channel_name.replace('private-conversation-', '');\n const member = await prisma.conversationMember.findFirst({\n where: { conversationId, userId: user.id },\n });\n \n if (!member) {\n return res.status(403).json({ error: 'Not a member of this conversation' });\n }\n }\n\n if (channel_name.startsWith('private-worksheet-')) {\n const worksheetId = channel_name.replace('private-worksheet-', '');\n const worksheet = await prisma.studentWorksheetResponse.findFirst({\n where: { id: worksheetId, OR: [\n { studentId: user.id },\n { submission: { assignment: { class: { teachers: { some: { id: user.id } } } } } },\n ] },\n });\n if (!worksheet) {\n return res.status(403).json({ error: 'No access to this worksheet' });\n }\n }\n\n if (channel_name.startsWith('private-teacher-')) {\n const classId = channel_name.replace('private-teacher-', '');\n const isTeacher = await prisma.class.findFirst({\n where: { id: classId, teachers: { some: { id: user.id } } },\n });\n if (!isTeacher) {\n return res.status(403).json({ error: 'Not a teacher of this class' });\n }\n }\n\n // Verify channel access for private-class-* channels\n // if (channel_name.startsWith('private-class-')) {\n // const classId = channel_name.replace('private-class-', '');\n // const isMember = await prisma.class.findFirst({\n // where: {\n // id: classId,\n // OR: [\n // { students: { some: { id: user.id } } },\n // { teachers: { some: { id: user.id } } },\n // ],\n // },\n // });\n // if (!isMember) {\n // return res.status(403).json({ error: 'Not a member of this class' });\n // }\n // }\n\n if (channel_name.startsWith('presence-')) {\n const authResponse = pusher.authorizeChannel(socket_id, channel_name, {\n user_id: user.id,\n user_info: { username: user.username },\n });\n return res.json(authResponse);\n }\n\n const authResponse = pusher.authorizeChannel(socket_id, channel_name);\n return res.json(authResponse);\n } catch (error) {\n logger.error('Pusher auth error', { error });\n return res.status(500).json({ error: 'Authentication failed' });\n }\n});\n\n// Setup Socket.IO\nconst io = new Server(httpServer, {\n cors: {\n origin: [\n 'http://localhost:3000', // Frontend development server\n 'http://localhost:3001', // Server port\n 'http://127.0.0.1:3000', // Alternative localhost\n 'http://127.0.0.1:3001', // Alternative localhost\n 'https://www.studious.sh', // Production frontend\n 'https://studious.sh', // Production frontend (without www)\n env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'\n ],\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],\n credentials: true,\n allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With', 'Access-Control-Allow-Origin', 'x-user']\n },\n transports: ['websocket', 'polling'],\n pingTimeout: 60000,\n pingInterval: 25000,\n connectTimeout: 45000,\n path: '/socket.io/',\n allowEIO3: true\n});\n\n// Add server-level logging\nio.engine.on('connection_error', (err: Error) => {\n logger.error('Socket connection error', { error: err.message });\n});\n\n// Setup socket handlers\nsetupSocketHandlers(io);\n\n// File serving endpoint for secure file access\napp.get('/api/files/:fileId', async (req, res) => {\n try {\n const fileId = decodeURIComponent(req.params.fileId);\n // console.log('File request:', { fileId, originalPath: req.params.fileId });\n \n // Get user from request headers\n const userHeader = req.headers['x-user'];\n if (!userHeader) {\n return res.status(401).json({ error: 'Authentication required' });\n }\n\n const token = typeof userHeader === 'string' ? userHeader : userHeader[0];\n\n // Find user by session token\n const user = await prisma.user.findFirst({\n where: {\n sessions: {\n some: {\n id: token\n }\n }\n },\n select: {\n id: true,\n username: true,\n }\n });\n\n if (!user) {\n return res.status(401).json({ error: 'Invalid or expired session' });\n }\n\n // Find file in database by path\n const fileRecord = await prisma.file.findFirst({\n where: { id: fileId },\n include: {\n user: true,\n assignment: {\n include: {\n class: {\n include: {\n students: true,\n teachers: true\n }\n }\n }\n },\n submission: {\n include: {\n student: true,\n assignment: {\n include: {\n class: {\n include: {\n teachers: true\n }\n }\n }\n }\n }\n },\n annotations: {\n include: {\n student: true,\n assignment: {\n include: {\n class: {\n include: {\n teachers: true\n }\n }\n }\n }\n }\n },\n folder: {\n include: {\n class: {\n include: {\n students: true,\n teachers: true\n }\n }\n }\n },\n classDraft: {\n include: {\n students: true,\n teachers: true\n }\n }\n }\n });\n\n if (!fileRecord) {\n return res.status(404).json({ error: 'File not found in database' });\n }\n\n // Check if user has permission to access this file\n let hasPermission = false;\n\n // Check if user created the file\n if (fileRecord.userId === user.id) {\n hasPermission = true;\n }\n\n // Check if file is related to a class where user is a member\n if (!hasPermission) {\n // Check assignment files\n if (fileRecord.assignment?.class) {\n const classData = fileRecord.assignment.class;\n const isStudent = classData.students.some(student => student.id === user.id);\n const isTeacher = classData.teachers.some(teacher => teacher.id === user.id);\n if (isStudent || isTeacher) {\n hasPermission = true;\n }\n }\n\n if (!hasPermission && fileRecord.annotations) {\n const annotation = fileRecord.annotations;\n if (annotation.studentId === user.id) {\n hasPermission = true;\n } else if (annotation.assignment?.class?.teachers.some(teacher => teacher.id === user.id)) {\n hasPermission = true;\n }\n }\n\n // Check submission files (student can access their own submissions, teachers can access all submissions in their class)\n if (!hasPermission && fileRecord.submission) {\n const submission = fileRecord.submission;\n if (submission.studentId === user.id) {\n hasPermission = true; // Student accessing their own submission\n } else if (submission.assignment?.class?.teachers.some(teacher => teacher.id === user.id)) {\n hasPermission = true; // Teacher accessing submission in their class\n }\n }\n\n // Check folder files\n if (!hasPermission && fileRecord.folder?.class) {\n const classData = fileRecord.folder.class;\n const isStudent = classData.students.some(student => student.id === user.id);\n const isTeacher = classData.teachers.some(teacher => teacher.id === user.id);\n if (isStudent || isTeacher) {\n hasPermission = true;\n }\n }\n\n // Check class draft files\n if (!hasPermission && fileRecord.classDraft) {\n const classData = fileRecord.classDraft;\n const isStudent = classData.students.some(student => student.id === user.id);\n const isTeacher = classData.teachers.some(teacher => teacher.id === user.id);\n if (isStudent || isTeacher) {\n hasPermission = true;\n }\n }\n }\n\n if (!hasPermission) {\n return res.status(403).json({ error: 'Access denied - insufficient permissions' });\n }\n \n const filePath = fileRecord.path;\n \n // Get file from Google Cloud Storage\n const file = bucket.file(filePath);\n const [exists] = await file.exists();\n \n if (!exists) {\n return res.status(404).json({ error: 'File not found in storage', filePath });\n }\n \n // Get file metadata\n const [metadata] = await file.getMetadata();\n \n // Set appropriate headers\n res.set({\n 'Content-Type': metadata.contentType || 'application/octet-stream',\n 'Content-Length': metadata.size,\n 'Cache-Control': 'public, max-age=31536000', // 1 year cache\n 'ETag': metadata.etag,\n });\n \n // Stream file to response\n const stream = file.createReadStream();\n stream.pipe(res);\n \n stream.on('error', (error) => {\n logger.error('Error streaming file:', {error});\n if (!res.headersSent) {\n res.status(500).json({ error: 'Error streaming file' });\n }\n });\n \n } catch (error) {\n logger.error('Error serving file:', {error});\n res.status(500).json({ error: 'Internal server error' });\n }\n});\n\napp.use('/trpc/auth.login', authLimiter);\napp.use('/trpc/auth.register', authLimiter);\n\n// File upload endpoint for secure file uploads (supports both POST and PUT)\napp.post('/api/upload/:filePath', uploadLimiter, async (req, res) => {\n handleFileUpload(req, res);\n});\n\napp.put('/api/upload/:filePath', uploadLimiter, async (req, res) => {\n handleFileUpload(req, res);\n});\n\nfunction handleFileUpload(req: any, res: any) {\n try {\n const filePath = decodeURIComponent(req.params.filePath);\n \n // Set CORS headers for upload endpoint\n const origin = req.headers.origin;\n const allowedOrigins = [\n 'http://localhost:3000',\n 'http://localhost:3001', \n 'http://127.0.0.1:3000',\n 'http://127.0.0.1:3001',\n 'https://www.studious.sh', // Production frontend\n 'https://studious.sh', // Production frontend (without www)\n env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'\n ];\n \n if (origin && allowedOrigins.includes(origin)) {\n res.header('Access-Control-Allow-Origin', origin);\n } else {\n res.header('Access-Control-Allow-Origin', 'http://localhost:3000');\n }\n \n res.header('Access-Control-Allow-Credentials', 'true');\n \n // Get content type from headers\n const contentType = req.headers['content-type'] || 'application/octet-stream';\n \n // Create a new file in the bucket\n const file = bucket.file(filePath);\n \n // Create a write stream to Google Cloud Storage\n const writeStream = file.createWriteStream({\n metadata: {\n contentType,\n },\n });\n \n // Handle stream events\n writeStream.on('error', (error) => {\n logger.error('Error uploading file:', {error});\n if (!res.headersSent) {\n res.status(500).json({ error: 'Error uploading file' });\n }\n });\n \n writeStream.on('finish', () => {\n res.status(200).json({ \n success: true, \n filePath,\n message: 'File uploaded successfully' \n });\n });\n \n // Pipe the request body to the write stream\n req.pipe(writeStream);\n \n } catch (error) {\n logger.error('Error handling file upload:', {error});\n res.status(500).json({ error: 'Internal server error' });\n }\n}\n\n// Create caller\nconst createCaller = createCallerFactory(appRouter);\n\n// Setup tRPC middleware\napp.use(\n '/trpc',\n createExpressMiddleware({\n router: appRouter,\n createContext: async ({ req, res }: { req: Request; res: Response }) => {\n return createTRPCContext({ req, res });\n },\n })\n);\n\n// IMPORTANT: Sentry error handler must be added AFTER all other middleware and routes\n// but BEFORE any other error handlers\nSentry.setupExpressErrorHandler(app);\n\n// app.use(function onError(err, req, res, next) {\n// // The error id is attached to `res.sentry` to be returned\n// // and optionally displayed to the user for support.\n// res.statusCode = 500;\n// res.end(res.sentry + \"\\n\");\n// });\n\n\nconst PORT = env.PORT || 3001;\n\nconnectRedis().then(() => {\n httpServer.listen(PORT, () => {\n logger.info(`Server running on port ${PORT}`, {\n port: PORT,\n services: ['tRPC', 'Socket.IO', env.REDIS_URL ? 'Redis' : null].filter(Boolean),\n });\n });\n}); \n\n// log all env variables\nlogger.info('Configurations', {\n NODE_ENV: env.NODE_ENV,\n PORT: env.PORT,\n NEXT_PUBLIC_APP_URL: env.NEXT_PUBLIC_APP_URL,\n LOG_MODE: env.LOG_MODE,\n});\n\n// Log CORS configuration\nlogger.info('CORS Configuration', {\n allowedOrigins: [\n 'http://localhost:3000',\n 'http://localhost:3001', \n 'http://127.0.0.1:3000',\n 'http://127.0.0.1:3001',\n env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'\n ]\n});\n\nconst gracefulShutdown = (signal: string) => {\n logger.info(`Received ${signal}, shutting down gracefully`);\n \n httpServer.close(() => {\n logger.info('HTTP server closed');\n \n io.close(() => {\n logger.info('Socket.IO server closed');\n\n disconnectRedis().then(() =>\n prisma.$disconnect().then(() => {\n logger.info('Database connections closed');\n process.exit(0);\n }).catch((err) => {\n logger.error('Error disconnecting from database', { error: err });\n process.exit(1);\n })\n );\n });\n });\n \n // Force shutdown after 10 seconds\n setTimeout(() => {\n logger.error('Forced shutdown after timeout');\n process.exit(1);\n }, 10000);\n};\n\nprocess.on('SIGTERM', () => gracefulShutdown('SIGTERM'));\nprocess.on('SIGINT', () => gracefulShutdown('SIGINT'));"],"names":[],"mappings":"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","debug_id":"e28b4205-9ed2-5148-b94c-3326b3073261"}
@@ -8,6 +8,7 @@ declare const envSchema: z.ZodObject<{
8
8
  BACKEND_URL: z.ZodDefault<z.ZodString>;
9
9
  SENTRY_DSN: z.ZodOptional<z.ZodString>;
10
10
  EMAIL_HOST: z.ZodString;
11
+ EMAIL_PORT: z.ZodDefault<z.ZodEffects<z.ZodString, number, string>>;
11
12
  EMAIL_USER: z.ZodString;
12
13
  EMAIL_PASS: z.ZodString;
13
14
  EMAIL_DRY_RUN: z.ZodDefault<z.ZodOptional<z.ZodString>>;
@@ -19,6 +20,8 @@ declare const envSchema: z.ZodObject<{
19
20
  PUSHER_KEY: z.ZodString;
20
21
  PUSHER_SECRET: z.ZodString;
21
22
  PUSHER_CLUSTER: z.ZodString;
23
+ PUSHER_AUTH_COOKIE_NAME: z.ZodOptional<z.ZodString>;
24
+ REDIS_URL: z.ZodOptional<z.ZodString>;
22
25
  INFERENCE_API_KEY: z.ZodOptional<z.ZodString>;
23
26
  INFERENCE_API_BASE_URL: z.ZodOptional<z.ZodString>;
24
27
  OPENAI_API_KEY: z.ZodOptional<z.ZodString>;
@@ -31,6 +34,7 @@ declare const envSchema: z.ZodObject<{
31
34
  NEXT_PUBLIC_APP_URL: string;
32
35
  BACKEND_URL: string;
33
36
  EMAIL_HOST: string;
37
+ EMAIL_PORT: number;
34
38
  EMAIL_USER: string;
35
39
  EMAIL_PASS: string;
36
40
  EMAIL_DRY_RUN: string;
@@ -43,6 +47,8 @@ declare const envSchema: z.ZodObject<{
43
47
  PUSHER_SECRET: string;
44
48
  PUSHER_CLUSTER: string;
45
49
  SENTRY_DSN?: string | undefined;
50
+ PUSHER_AUTH_COOKIE_NAME?: string | undefined;
51
+ REDIS_URL?: string | undefined;
46
52
  INFERENCE_API_KEY?: string | undefined;
47
53
  INFERENCE_API_BASE_URL?: string | undefined;
48
54
  OPENAI_API_KEY?: string | undefined;
@@ -65,7 +71,10 @@ declare const envSchema: z.ZodObject<{
65
71
  NEXT_PUBLIC_APP_URL?: string | undefined;
66
72
  BACKEND_URL?: string | undefined;
67
73
  SENTRY_DSN?: string | undefined;
74
+ EMAIL_PORT?: string | undefined;
68
75
  EMAIL_DRY_RUN?: string | undefined;
76
+ PUSHER_AUTH_COOKIE_NAME?: string | undefined;
77
+ REDIS_URL?: string | undefined;
69
78
  INFERENCE_API_KEY?: string | undefined;
70
79
  INFERENCE_API_BASE_URL?: string | undefined;
71
80
  OPENAI_API_KEY?: string | undefined;
@@ -78,6 +87,7 @@ declare const envSchema: z.ZodObject<{
78
87
  BACKEND_URL: z.ZodDefault<z.ZodOptional<z.ZodString>>;
79
88
  SENTRY_DSN: z.ZodOptional<z.ZodString>;
80
89
  EMAIL_HOST: z.ZodDefault<z.ZodOptional<z.ZodString>>;
90
+ EMAIL_PORT: z.ZodDefault<z.ZodEffects<z.ZodString, number, string>>;
81
91
  EMAIL_USER: z.ZodDefault<z.ZodOptional<z.ZodString>>;
82
92
  EMAIL_PASS: z.ZodDefault<z.ZodOptional<z.ZodString>>;
83
93
  EMAIL_DRY_RUN: z.ZodDefault<z.ZodOptional<z.ZodString>>;
@@ -89,6 +99,8 @@ declare const envSchema: z.ZodObject<{
89
99
  PUSHER_KEY: z.ZodDefault<z.ZodOptional<z.ZodString>>;
90
100
  PUSHER_SECRET: z.ZodDefault<z.ZodOptional<z.ZodString>>;
91
101
  PUSHER_CLUSTER: z.ZodDefault<z.ZodOptional<z.ZodString>>;
102
+ PUSHER_AUTH_COOKIE_NAME: z.ZodOptional<z.ZodString>;
103
+ REDIS_URL: z.ZodOptional<z.ZodString>;
92
104
  INFERENCE_API_KEY: z.ZodOptional<z.ZodString>;
93
105
  OPENAI_API_KEY: z.ZodOptional<z.ZodString>;
94
106
  INFERENCE_API_BASE_URL: z.ZodOptional<z.ZodString>;
@@ -101,6 +113,7 @@ declare const envSchema: z.ZodObject<{
101
113
  NEXT_PUBLIC_APP_URL: string;
102
114
  BACKEND_URL: string;
103
115
  EMAIL_HOST: string;
116
+ EMAIL_PORT: number;
104
117
  EMAIL_USER: string;
105
118
  EMAIL_PASS: string;
106
119
  EMAIL_DRY_RUN: string;
@@ -113,6 +126,8 @@ declare const envSchema: z.ZodObject<{
113
126
  PUSHER_SECRET: string;
114
127
  PUSHER_CLUSTER: string;
115
128
  SENTRY_DSN?: string | undefined;
129
+ PUSHER_AUTH_COOKIE_NAME?: string | undefined;
130
+ REDIS_URL?: string | undefined;
116
131
  INFERENCE_API_KEY?: string | undefined;
117
132
  INFERENCE_API_BASE_URL?: string | undefined;
118
133
  OPENAI_API_KEY?: string | undefined;
@@ -125,6 +140,7 @@ declare const envSchema: z.ZodObject<{
125
140
  BACKEND_URL?: string | undefined;
126
141
  SENTRY_DSN?: string | undefined;
127
142
  EMAIL_HOST?: string | undefined;
143
+ EMAIL_PORT?: string | undefined;
128
144
  EMAIL_USER?: string | undefined;
129
145
  EMAIL_PASS?: string | undefined;
130
146
  EMAIL_DRY_RUN?: string | undefined;
@@ -136,6 +152,8 @@ declare const envSchema: z.ZodObject<{
136
152
  PUSHER_KEY?: string | undefined;
137
153
  PUSHER_SECRET?: string | undefined;
138
154
  PUSHER_CLUSTER?: string | undefined;
155
+ PUSHER_AUTH_COOKIE_NAME?: string | undefined;
156
+ REDIS_URL?: string | undefined;
139
157
  INFERENCE_API_KEY?: string | undefined;
140
158
  INFERENCE_API_BASE_URL?: string | undefined;
141
159
  OPENAI_API_KEY?: string | undefined;
@@ -148,6 +166,7 @@ export declare const env: {
148
166
  NEXT_PUBLIC_APP_URL: string;
149
167
  BACKEND_URL: string;
150
168
  EMAIL_HOST: string;
169
+ EMAIL_PORT: number;
151
170
  EMAIL_USER: string;
152
171
  EMAIL_PASS: string;
153
172
  EMAIL_DRY_RUN: string;
@@ -160,6 +179,8 @@ export declare const env: {
160
179
  PUSHER_SECRET: string;
161
180
  PUSHER_CLUSTER: string;
162
181
  SENTRY_DSN?: string | undefined;
182
+ PUSHER_AUTH_COOKIE_NAME?: string | undefined;
183
+ REDIS_URL?: string | undefined;
163
184
  INFERENCE_API_KEY?: string | undefined;
164
185
  INFERENCE_API_BASE_URL?: string | undefined;
165
186
  OPENAI_API_KEY?: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"env.d.ts","sourceRoot":"/","sources":["lib/config/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA+ExB,QAAA,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAmC,CAAC;AA2CnD,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;CAAgB,CAAC;AAGjC,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC"}
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"/","sources":["lib/config/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAqFxB,QAAA,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAmC,CAAC;AA2CnD,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;CAAgB,CAAC;AAGjC,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC"}
@@ -1,5 +1,5 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="07e685fd-2066-519c-9412-be25dae9cd72")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="6fe796c8-7781-5540-892a-a320464bfbae")}catch(e){}}();
3
3
  import { z } from 'zod';
4
4
  import dotenv from 'dotenv';
5
5
  import { resolve } from 'path';
@@ -32,6 +32,7 @@ const fullSchema = baseSchema.extend({
32
32
  BACKEND_URL: z.string().url().default('http://localhost:3001'),
33
33
  SENTRY_DSN: z.string().url().optional(),
34
34
  EMAIL_HOST: z.string().min(1, 'EMAIL_HOST is required'),
35
+ EMAIL_PORT: z.string().transform(Number).default('587'),
35
36
  EMAIL_USER: z.string().email('EMAIL_USER must be a valid email'),
36
37
  EMAIL_PASS: z.string().min(1, 'EMAIL_PASS is required'),
37
38
  EMAIL_DRY_RUN: z.string().optional().default('false'),
@@ -43,6 +44,8 @@ const fullSchema = baseSchema.extend({
43
44
  PUSHER_KEY: z.string().min(1, 'PUSHER_KEY is required'),
44
45
  PUSHER_SECRET: z.string().min(1, 'PUSHER_SECRET is required'),
45
46
  PUSHER_CLUSTER: z.string().min(1, 'PUSHER_CLUSTER is required'),
47
+ PUSHER_AUTH_COOKIE_NAME: z.string().optional(), // Cookie name for session token (default: 'token')
48
+ REDIS_URL: z.string().url().optional(), // Redis connection URL (e.g. redis://localhost:6379)
46
49
  INFERENCE_API_KEY: z.string().optional(),
47
50
  INFERENCE_API_BASE_URL: z.string().url().optional(),
48
51
  OPENAI_API_KEY: z.string().optional(),
@@ -54,6 +57,7 @@ const testSchema = baseSchema.extend({
54
57
  BACKEND_URL: z.string().url().optional().default('http://localhost:3001'),
55
58
  SENTRY_DSN: z.string().url().optional(),
56
59
  EMAIL_HOST: z.string().optional().default('smtp.test.com'),
60
+ EMAIL_PORT: z.string().transform(Number).default('587'),
57
61
  EMAIL_USER: z.string().email().optional().default('test@test.com'),
58
62
  EMAIL_PASS: z.string().optional().default('test'),
59
63
  EMAIL_DRY_RUN: z.string().optional().default('false'),
@@ -65,6 +69,8 @@ const testSchema = baseSchema.extend({
65
69
  PUSHER_KEY: z.string().optional().default('test-key'),
66
70
  PUSHER_SECRET: z.string().optional().default('test-secret'),
67
71
  PUSHER_CLUSTER: z.string().optional().default('us2'),
72
+ PUSHER_AUTH_COOKIE_NAME: z.string().optional(),
73
+ REDIS_URL: z.string().url().optional(),
68
74
  INFERENCE_API_KEY: z.string().optional(),
69
75
  OPENAI_API_KEY: z.string().optional(),
70
76
  INFERENCE_API_BASE_URL: z.string().url().optional(),
@@ -112,4 +118,4 @@ function validateEnv() {
112
118
  // Export validated environment variables
113
119
  export const env = validateEnv();
114
120
  //# sourceMappingURL=env.js.map
115
- //# debugId=07e685fd-2066-519c-9412-be25dae9cd72
121
+ //# debugId=6fe796c8-7781-5540-892a-a320464bfbae
@@ -1 +1 @@
1
- {"version":3,"file":"env.js","sources":["lib/config/env.ts"],"sourceRoot":"/","sourcesContent":["import { z } from 'zod';\nimport dotenv from 'dotenv';\nimport { resolve } from 'path';\nimport { logger } from '../../utils/logger.js';\n\n// Determine which env file to load based on NODE_ENV\nconst nodeEnv = process.env.NODE_ENV || 'development';\nconst envFileMap: Record<string, string> = {\n test: '.env.test',\n development: '.env.development',\n production: '.env.production',\n};\n\n// Load the appropriate env file\nconst envFile = envFileMap[nodeEnv] || '.env';\nconst envPath = resolve(process.cwd(), envFile);\n\n// Load environment variables from the correct file\n// First load .env (base), then override with environment-specific file\ndotenv.config(); // Load .env first (base config)\ndotenv.config({ path: envPath, override: true }); // Override with env-specific\n\nconst isTest = nodeEnv === 'test';\nconst isProduction = nodeEnv === 'production';\n\n// Base schema with required vars for all environments\nconst baseSchema = z.object({\n NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),\n PORT: z.string().transform(Number).default('3001'),\n DATABASE_URL: z.string().url('DATABASE_URL must be a valid URL'),\n});\n\n// Production/development schema with all required vars\nconst fullSchema = baseSchema.extend({\n NEXT_PUBLIC_APP_URL: z.string().url().default('http://localhost:3000'),\n BACKEND_URL: z.string().url().default('http://localhost:3001'),\n SENTRY_DSN: z.string().url().optional(),\n EMAIL_HOST: z.string().min(1, 'EMAIL_HOST is required'),\n EMAIL_USER: z.string().email('EMAIL_USER must be a valid email'),\n EMAIL_PASS: z.string().min(1, 'EMAIL_PASS is required'),\n EMAIL_DRY_RUN: z.string().optional().default('false'),\n GOOGLE_CLOUD_PROJECT_ID: z.string().min(1, 'GOOGLE_CLOUD_PROJECT_ID is required'),\n GOOGLE_CLOUD_CLIENT_EMAIL: z.string().email('GOOGLE_CLOUD_CLIENT_EMAIL must be a valid email'),\n GOOGLE_CLOUD_PRIVATE_KEY: z.string().min(1, 'GOOGLE_CLOUD_PRIVATE_KEY is required'),\n GOOGLE_CLOUD_BUCKET_NAME: z.string().min(1, 'GOOGLE_CLOUD_BUCKET_NAME is required'),\n PUSHER_APP_ID: z.string().min(1, 'PUSHER_APP_ID is required'),\n PUSHER_KEY: z.string().min(1, 'PUSHER_KEY is required'),\n PUSHER_SECRET: z.string().min(1, 'PUSHER_SECRET is required'),\n PUSHER_CLUSTER: z.string().min(1, 'PUSHER_CLUSTER is required'),\n INFERENCE_API_KEY: z.string().optional(),\n INFERENCE_API_BASE_URL: z.string().url().optional(),\n OPENAI_API_KEY: z.string().optional(),\n LOG_MODE: z.enum(['normal', 'verbose', 'quiet']).default('normal'),\n});\n\n// Test schema - only require what's needed for tests\nconst testSchema = baseSchema.extend({\n NEXT_PUBLIC_APP_URL: z.string().url().optional().default('http://localhost:3000'),\n BACKEND_URL: z.string().url().optional().default('http://localhost:3001'),\n SENTRY_DSN: z.string().url().optional(),\n EMAIL_HOST: z.string().optional().default('smtp.test.com'),\n EMAIL_USER: z.string().email().optional().default('test@test.com'),\n EMAIL_PASS: z.string().optional().default('test'),\n EMAIL_DRY_RUN: z.string().optional().default('false'),\n GOOGLE_CLOUD_PROJECT_ID: z.string().optional().default('test-project'),\n GOOGLE_CLOUD_CLIENT_EMAIL: z.string().email().optional().default('test@test.iam.gserviceaccount.com'),\n GOOGLE_CLOUD_PRIVATE_KEY: z.string().optional().default('test-key'),\n GOOGLE_CLOUD_BUCKET_NAME: z.string().optional().default('test-bucket'),\n PUSHER_APP_ID: z.string().optional().default('test-app-id'),\n PUSHER_KEY: z.string().optional().default('test-key'),\n PUSHER_SECRET: z.string().optional().default('test-secret'),\n PUSHER_CLUSTER: z.string().optional().default('us2'),\n INFERENCE_API_KEY: z.string().optional(),\n OPENAI_API_KEY: z.string().optional(),\n INFERENCE_API_BASE_URL: z.string().url().optional(),\n LOG_MODE: z.enum(['normal', 'verbose', 'quiet']).default('quiet'),\n});\n\n// Use test schema in test mode, full schema otherwise\nconst envSchema = isTest ? testSchema : fullSchema;\n\n// Validate environment variables\nfunction validateEnv() {\n try {\n const parsed = envSchema.parse(process.env);\n \n // Only exit on validation failure in production\n if (isProduction && !parsed.DATABASE_URL) {\n logger.error('DATABASE_URL is required in production');\n process.exit(1);\n }\n \n return parsed;\n } catch (error) {\n if (error instanceof z.ZodError) {\n const missingVars = error.errors.map(err => ({\n path: err.path.join('.'),\n message: err.message,\n }));\n \n logger.error('Environment variable validation failed', {\n envFile,\n missingVars,\n });\n \n // Only exit in production - in test/dev, log warning but continue\n if (isProduction) {\n logger.error(`Please check your ${envFile} file and ensure all required variables are set.`);\n process.exit(1);\n } else {\n logger.warn('Continuing with defaults - some features may not work correctly', {\n envFile,\n });\n // Return parsed with defaults for non-production\n return envSchema.parse({ ...process.env });\n }\n }\n throw error;\n }\n}\n\n// Export validated environment variables\nexport const env = validateEnv();\n\n// Type-safe environment access\nexport type Env = z.infer<typeof envSchema>;"],"names":[],"mappings":"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","debug_id":"07e685fd-2066-519c-9412-be25dae9cd72"}
1
+ {"version":3,"file":"env.js","sources":["lib/config/env.ts"],"sourceRoot":"/","sourcesContent":["import { z } from 'zod';\nimport dotenv from 'dotenv';\nimport { resolve } from 'path';\nimport { logger } from '../../utils/logger.js';\n\n// Determine which env file to load based on NODE_ENV\nconst nodeEnv = process.env.NODE_ENV || 'development';\nconst envFileMap: Record<string, string> = {\n test: '.env.test',\n development: '.env.development',\n production: '.env.production',\n};\n\n// Load the appropriate env file\nconst envFile = envFileMap[nodeEnv] || '.env';\nconst envPath = resolve(process.cwd(), envFile);\n\n// Load environment variables from the correct file\n// First load .env (base), then override with environment-specific file\ndotenv.config(); // Load .env first (base config)\ndotenv.config({ path: envPath, override: true }); // Override with env-specific\n\nconst isTest = nodeEnv === 'test';\nconst isProduction = nodeEnv === 'production';\n\n// Base schema with required vars for all environments\nconst baseSchema = z.object({\n NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),\n PORT: z.string().transform(Number).default('3001'),\n DATABASE_URL: z.string().url('DATABASE_URL must be a valid URL'),\n});\n\n// Production/development schema with all required vars\nconst fullSchema = baseSchema.extend({\n NEXT_PUBLIC_APP_URL: z.string().url().default('http://localhost:3000'),\n BACKEND_URL: z.string().url().default('http://localhost:3001'),\n SENTRY_DSN: z.string().url().optional(),\n EMAIL_HOST: z.string().min(1, 'EMAIL_HOST is required'),\n EMAIL_PORT: z.string().transform(Number).default('587'),\n EMAIL_USER: z.string().email('EMAIL_USER must be a valid email'),\n EMAIL_PASS: z.string().min(1, 'EMAIL_PASS is required'),\n EMAIL_DRY_RUN: z.string().optional().default('false'),\n GOOGLE_CLOUD_PROJECT_ID: z.string().min(1, 'GOOGLE_CLOUD_PROJECT_ID is required'),\n GOOGLE_CLOUD_CLIENT_EMAIL: z.string().email('GOOGLE_CLOUD_CLIENT_EMAIL must be a valid email'),\n GOOGLE_CLOUD_PRIVATE_KEY: z.string().min(1, 'GOOGLE_CLOUD_PRIVATE_KEY is required'),\n GOOGLE_CLOUD_BUCKET_NAME: z.string().min(1, 'GOOGLE_CLOUD_BUCKET_NAME is required'),\n PUSHER_APP_ID: z.string().min(1, 'PUSHER_APP_ID is required'),\n PUSHER_KEY: z.string().min(1, 'PUSHER_KEY is required'),\n PUSHER_SECRET: z.string().min(1, 'PUSHER_SECRET is required'),\n PUSHER_CLUSTER: z.string().min(1, 'PUSHER_CLUSTER is required'),\n PUSHER_AUTH_COOKIE_NAME: z.string().optional(), // Cookie name for session token (default: 'token')\n REDIS_URL: z.string().url().optional(), // Redis connection URL (e.g. redis://localhost:6379)\n INFERENCE_API_KEY: z.string().optional(),\n INFERENCE_API_BASE_URL: z.string().url().optional(),\n OPENAI_API_KEY: z.string().optional(),\n LOG_MODE: z.enum(['normal', 'verbose', 'quiet']).default('normal'),\n});\n\n// Test schema - only require what's needed for tests\nconst testSchema = baseSchema.extend({\n NEXT_PUBLIC_APP_URL: z.string().url().optional().default('http://localhost:3000'),\n BACKEND_URL: z.string().url().optional().default('http://localhost:3001'),\n SENTRY_DSN: z.string().url().optional(),\n EMAIL_HOST: z.string().optional().default('smtp.test.com'),\n EMAIL_PORT: z.string().transform(Number).default('587'),\n EMAIL_USER: z.string().email().optional().default('test@test.com'),\n EMAIL_PASS: z.string().optional().default('test'),\n EMAIL_DRY_RUN: z.string().optional().default('false'),\n GOOGLE_CLOUD_PROJECT_ID: z.string().optional().default('test-project'),\n GOOGLE_CLOUD_CLIENT_EMAIL: z.string().email().optional().default('test@test.iam.gserviceaccount.com'),\n GOOGLE_CLOUD_PRIVATE_KEY: z.string().optional().default('test-key'),\n GOOGLE_CLOUD_BUCKET_NAME: z.string().optional().default('test-bucket'),\n PUSHER_APP_ID: z.string().optional().default('test-app-id'),\n PUSHER_KEY: z.string().optional().default('test-key'),\n PUSHER_SECRET: z.string().optional().default('test-secret'),\n PUSHER_CLUSTER: z.string().optional().default('us2'),\n PUSHER_AUTH_COOKIE_NAME: z.string().optional(),\n REDIS_URL: z.string().url().optional(),\n INFERENCE_API_KEY: z.string().optional(),\n OPENAI_API_KEY: z.string().optional(),\n INFERENCE_API_BASE_URL: z.string().url().optional(),\n LOG_MODE: z.enum(['normal', 'verbose', 'quiet']).default('quiet'),\n});\n\n// Use test schema in test mode, full schema otherwise\nconst envSchema = isTest ? testSchema : fullSchema;\n\n// Validate environment variables\nfunction validateEnv() {\n try {\n const parsed = envSchema.parse(process.env);\n \n // Only exit on validation failure in production\n if (isProduction && !parsed.DATABASE_URL) {\n logger.error('DATABASE_URL is required in production');\n process.exit(1);\n }\n \n return parsed;\n } catch (error) {\n if (error instanceof z.ZodError) {\n const missingVars = error.errors.map(err => ({\n path: err.path.join('.'),\n message: err.message,\n }));\n \n logger.error('Environment variable validation failed', {\n envFile,\n missingVars,\n });\n \n // Only exit in production - in test/dev, log warning but continue\n if (isProduction) {\n logger.error(`Please check your ${envFile} file and ensure all required variables are set.`);\n process.exit(1);\n } else {\n logger.warn('Continuing with defaults - some features may not work correctly', {\n envFile,\n });\n // Return parsed with defaults for non-production\n return envSchema.parse({ ...process.env });\n }\n }\n throw error;\n }\n}\n\n// Export validated environment variables\nexport const env = validateEnv();\n\n// Type-safe environment access\nexport type Env = z.infer<typeof envSchema>;"],"names":[],"mappings":"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","debug_id":"6fe796c8-7781-5540-892a-a320464bfbae"}
@@ -1 +1 @@
1
- {"version":3,"file":"fileUpload.d.ts","sourceRoot":"/","sources":["lib/fileUpload.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAEd;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAEd;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,IAAI,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;CACzB;AAKD;;GAEG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,YAAY,CAAC,CAKvB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,QAAQ,EAAE,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC,CAKzB;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUlE;AAED;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,MAAM,EACrB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,gBAAgB,CAAC,CA8F3B;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,OAAO,EACtB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CA+Df;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAED;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,cAAc,EAAE,EACvB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,MAAM,EACrB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAiB7B"}
1
+ {"version":3,"file":"fileUpload.d.ts","sourceRoot":"/","sources":["lib/fileUpload.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAEd;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAEd;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,IAAI,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;CACzB;AAKD;;GAEG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,YAAY,CAAC,CAKvB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,QAAQ,EAAE,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC,CAKzB;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUlE;AAED;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,MAAM,EACrB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,gBAAgB,CAAC,CA8F3B;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,OAAO,EACtB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CA+Df;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAED;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,cAAc,EAAE,EACvB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,MAAM,EACrB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAiB7B"}
@@ -1,5 +1,5 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="04fce6f6-76e4-53e2-b139-39e7fa1d2987")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="4ff4c0f2-8784-50fe-a248-6adcac3fa659")}catch(e){}}();
3
3
  import { TRPCError } from "@trpc/server";
4
4
  import { v4 as uuidv4 } from "uuid";
5
5
  import { getSignedUrl, objectExists } from "./googleCloudStorage.js";
@@ -270,4 +270,4 @@ export async function createDirectUploadFiles(files, userId, directory, assignme
270
270
  }
271
271
  }
272
272
  //# sourceMappingURL=fileUpload.js.map
273
- //# debugId=04fce6f6-76e4-53e2-b139-39e7fa1d2987
273
+ //# debugId=4ff4c0f2-8784-50fe-a248-6adcac3fa659