@hed-hog/core 0.0.399 → 0.0.400

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 (668) hide show
  1. package/dist/ai/ai-agent.sort.d.ts +6 -0
  2. package/dist/ai/ai-agent.sort.d.ts.map +1 -0
  3. package/dist/ai/ai-agent.sort.js +21 -0
  4. package/dist/ai/ai-agent.sort.js.map +1 -0
  5. package/dist/ai/ai.controller.d.ts +4 -4
  6. package/dist/ai/ai.service.d.ts +35 -4
  7. package/dist/ai/ai.service.d.ts.map +1 -1
  8. package/dist/ai/ai.service.js +51 -137
  9. package/dist/ai/ai.service.js.map +1 -1
  10. package/dist/ai-instruction/ai-instruction.service.d.ts.map +1 -1
  11. package/dist/ai-instruction/ai-instruction.service.js +26 -23
  12. package/dist/ai-instruction/ai-instruction.service.js.map +1 -1
  13. package/dist/ai-instruction/ai-instruction.sort.d.ts +16 -0
  14. package/dist/ai-instruction/ai-instruction.sort.d.ts.map +1 -0
  15. package/dist/ai-instruction/ai-instruction.sort.js +32 -0
  16. package/dist/ai-instruction/ai-instruction.sort.js.map +1 -0
  17. package/dist/auth/auth.controller.d.ts +24 -8
  18. package/dist/auth/auth.controller.d.ts.map +1 -1
  19. package/dist/auth/auth.module.d.ts.map +1 -1
  20. package/dist/auth/auth.module.js +8 -1
  21. package/dist/auth/auth.module.js.map +1 -1
  22. package/dist/auth/auth.service.d.ts +72 -25
  23. package/dist/auth/auth.service.d.ts.map +1 -1
  24. package/dist/auth/auth.service.js +41 -4
  25. package/dist/auth/auth.service.js.map +1 -1
  26. package/dist/auth/guards/auth.guard.d.ts +3 -1
  27. package/dist/auth/guards/auth.guard.d.ts.map +1 -1
  28. package/dist/auth/guards/auth.guard.js +12 -3
  29. package/dist/auth/guards/auth.guard.js.map +1 -1
  30. package/dist/authorize/authorize.controller.d.ts +29 -5
  31. package/dist/authorize/authorize.controller.d.ts.map +1 -1
  32. package/dist/authorize/authorize.controller.js +120 -13
  33. package/dist/authorize/authorize.controller.js.map +1 -1
  34. package/dist/authorize/authorize.errors.d.ts +34 -0
  35. package/dist/authorize/authorize.errors.d.ts.map +1 -0
  36. package/dist/authorize/authorize.errors.js +37 -0
  37. package/dist/authorize/authorize.errors.js.map +1 -0
  38. package/dist/authorize/authorize.module.d.ts.map +1 -1
  39. package/dist/authorize/authorize.module.js +6 -1
  40. package/dist/authorize/authorize.module.js.map +1 -1
  41. package/dist/authorize/authorize.service.d.ts +77 -3
  42. package/dist/authorize/authorize.service.d.ts.map +1 -1
  43. package/dist/authorize/authorize.service.js +212 -21
  44. package/dist/authorize/authorize.service.js.map +1 -1
  45. package/dist/authorize/dto/authorize-info.dto.d.ts +10 -1
  46. package/dist/authorize/dto/authorize-info.dto.d.ts.map +1 -1
  47. package/dist/authorize/dto/authorize-info.dto.js +16 -1
  48. package/dist/authorize/dto/authorize-info.dto.js.map +1 -1
  49. package/dist/authorize/dto/consent.dto.d.ts +10 -1
  50. package/dist/authorize/dto/consent.dto.d.ts.map +1 -1
  51. package/dist/authorize/dto/consent.dto.js +16 -1
  52. package/dist/authorize/dto/consent.dto.js.map +1 -1
  53. package/dist/authorize/dto/token.dto.d.ts +12 -0
  54. package/dist/authorize/dto/token.dto.d.ts.map +1 -1
  55. package/dist/authorize/dto/token.dto.js +21 -1
  56. package/dist/authorize/dto/token.dto.js.map +1 -1
  57. package/dist/authorize/oauth-exception.filter.d.ts +17 -0
  58. package/dist/authorize/oauth-exception.filter.d.ts.map +1 -0
  59. package/dist/authorize/oauth-exception.filter.js +54 -0
  60. package/dist/authorize/oauth-exception.filter.js.map +1 -0
  61. package/dist/authorize/oauth-metadata.service.d.ts +39 -0
  62. package/dist/authorize/oauth-metadata.service.d.ts.map +1 -0
  63. package/dist/authorize/oauth-metadata.service.js +81 -0
  64. package/dist/authorize/oauth-metadata.service.js.map +1 -0
  65. package/dist/authorize/well-known.controller.d.ts +67 -0
  66. package/dist/authorize/well-known.controller.d.ts.map +1 -0
  67. package/dist/authorize/well-known.controller.js +126 -0
  68. package/dist/authorize/well-known.controller.js.map +1 -0
  69. package/dist/captcha/captcha.service.d.ts +32 -2
  70. package/dist/captcha/captcha.service.d.ts.map +1 -1
  71. package/dist/captcha/captcha.service.js +85 -12
  72. package/dist/captcha/captcha.service.js.map +1 -1
  73. package/dist/challenge/challenge.service.d.ts +2 -2
  74. package/dist/core.module.d.ts.map +1 -1
  75. package/dist/core.module.js +6 -0
  76. package/dist/core.module.js.map +1 -1
  77. package/dist/dashboard/dashboard/dashboard.controller.d.ts +9 -9
  78. package/dist/dashboard/dashboard/dashboard.service.d.ts +9 -9
  79. package/dist/dashboard/dashboard-component/dashboard-component.controller.d.ts +3 -3
  80. package/dist/dashboard/dashboard-component/dashboard-component.service.d.ts +3 -3
  81. package/dist/dashboard/dashboard-component-role/dashboard-component-role.controller.d.ts +3 -3
  82. package/dist/dashboard/dashboard-component-role/dashboard-component-role.service.d.ts +3 -3
  83. package/dist/dashboard/dashboard-component-role/dashboard-component-role.service.d.ts.map +1 -1
  84. package/dist/dashboard/dashboard-component-role/dashboard-component-role.service.js +2 -4
  85. package/dist/dashboard/dashboard-component-role/dashboard-component-role.service.js.map +1 -1
  86. package/dist/dashboard/dashboard-component-role/dashboard-component-role.sort.d.ts +8 -0
  87. package/dist/dashboard/dashboard-component-role/dashboard-component-role.sort.d.ts.map +1 -0
  88. package/dist/dashboard/dashboard-component-role/dashboard-component-role.sort.js +18 -0
  89. package/dist/dashboard/dashboard-component-role/dashboard-component-role.sort.js.map +1 -0
  90. package/dist/dashboard/dashboard-item/dashboard-item.service.d.ts.map +1 -1
  91. package/dist/dashboard/dashboard-item/dashboard-item.service.js +2 -4
  92. package/dist/dashboard/dashboard-item/dashboard-item.service.js.map +1 -1
  93. package/dist/dashboard/dashboard-item/dashboard-item.sort.d.ts +9 -0
  94. package/dist/dashboard/dashboard-item/dashboard-item.sort.d.ts.map +1 -0
  95. package/dist/dashboard/dashboard-item/dashboard-item.sort.js +19 -0
  96. package/dist/dashboard/dashboard-item/dashboard-item.sort.js.map +1 -0
  97. package/dist/dashboard/dashboard-role/dashboard-role.controller.d.ts +3 -3
  98. package/dist/dashboard/dashboard-role/dashboard-role.service.d.ts +3 -3
  99. package/dist/dashboard/dashboard-role/dashboard-role.service.d.ts.map +1 -1
  100. package/dist/dashboard/dashboard-role/dashboard-role.service.js +2 -4
  101. package/dist/dashboard/dashboard-role/dashboard-role.service.js.map +1 -1
  102. package/dist/dashboard/dashboard-role/dashboard-role.sort.d.ts +8 -0
  103. package/dist/dashboard/dashboard-role/dashboard-role.sort.d.ts.map +1 -0
  104. package/dist/dashboard/dashboard-role/dashboard-role.sort.js +16 -0
  105. package/dist/dashboard/dashboard-role/dashboard-role.sort.js.map +1 -0
  106. package/dist/file/file-upload-ticket.service.d.ts +160 -0
  107. package/dist/file/file-upload-ticket.service.d.ts.map +1 -0
  108. package/dist/file/file-upload-ticket.service.js +382 -0
  109. package/dist/file/file-upload-ticket.service.js.map +1 -0
  110. package/dist/file/file.controller.d.ts +24 -1
  111. package/dist/file/file.controller.d.ts.map +1 -1
  112. package/dist/file/file.controller.js +63 -2
  113. package/dist/file/file.controller.js.map +1 -1
  114. package/dist/file/file.module.d.ts.map +1 -1
  115. package/dist/file/file.module.js +14 -2
  116. package/dist/file/file.module.js.map +1 -1
  117. package/dist/file/file.service.d.ts +182 -6
  118. package/dist/file/file.service.d.ts.map +1 -1
  119. package/dist/file/file.service.js +386 -54
  120. package/dist/file/file.service.js.map +1 -1
  121. package/dist/file/filename-encoding.util.d.ts +24 -0
  122. package/dist/file/filename-encoding.util.d.ts.map +1 -0
  123. package/dist/file/filename-encoding.util.js +63 -0
  124. package/dist/file/filename-encoding.util.js.map +1 -0
  125. package/dist/file/image-optimization.service.d.ts +27 -0
  126. package/dist/file/image-optimization.service.d.ts.map +1 -1
  127. package/dist/file/image-optimization.service.js +63 -14
  128. package/dist/file/image-optimization.service.js.map +1 -1
  129. package/dist/file/mcp-file-source.schema.d.ts +33 -0
  130. package/dist/file/mcp-file-source.schema.d.ts.map +1 -0
  131. package/dist/file/mcp-file-source.schema.js +75 -0
  132. package/dist/file/mcp-file-source.schema.js.map +1 -0
  133. package/dist/file/mcp-file-source.service.d.ts +124 -0
  134. package/dist/file/mcp-file-source.service.d.ts.map +1 -0
  135. package/dist/file/mcp-file-source.service.js +262 -0
  136. package/dist/file/mcp-file-source.service.js.map +1 -0
  137. package/dist/file/mimetype-sniff.util.d.ts +62 -0
  138. package/dist/file/mimetype-sniff.util.d.ts.map +1 -0
  139. package/dist/file/mimetype-sniff.util.js +226 -0
  140. package/dist/file/mimetype-sniff.util.js.map +1 -0
  141. package/dist/file/remote-fetch.util.d.ts +35 -0
  142. package/dist/file/remote-fetch.util.d.ts.map +1 -0
  143. package/dist/file/remote-fetch.util.js +236 -0
  144. package/dist/file/remote-fetch.util.js.map +1 -0
  145. package/dist/impersonation/dto/start-impersonation.dto.d.ts +4 -1
  146. package/dist/impersonation/dto/start-impersonation.dto.d.ts.map +1 -1
  147. package/dist/impersonation/dto/start-impersonation.dto.js +1 -1
  148. package/dist/impersonation/dto/start-impersonation.dto.js.map +1 -1
  149. package/dist/impersonation/impersonation.service.d.ts +8 -3
  150. package/dist/impersonation/impersonation.service.d.ts.map +1 -1
  151. package/dist/impersonation/impersonation.service.js +14 -4
  152. package/dist/impersonation/impersonation.service.js.map +1 -1
  153. package/dist/incident/incident.controller.d.ts +2 -1
  154. package/dist/incident/incident.controller.d.ts.map +1 -1
  155. package/dist/incident/incident.controller.js +10 -6
  156. package/dist/incident/incident.controller.js.map +1 -1
  157. package/dist/incident/incident.service.d.ts +2 -0
  158. package/dist/incident/incident.service.d.ts.map +1 -1
  159. package/dist/incident/incident.service.js +4 -0
  160. package/dist/incident/incident.service.js.map +1 -1
  161. package/dist/index.d.ts +17 -0
  162. package/dist/index.d.ts.map +1 -1
  163. package/dist/index.js +17 -0
  164. package/dist/index.js.map +1 -1
  165. package/dist/integration-profile/integration-profile.secrets.d.ts.map +1 -1
  166. package/dist/integration-profile/integration-profile.secrets.js +7 -0
  167. package/dist/integration-profile/integration-profile.secrets.js.map +1 -1
  168. package/dist/integration-profile/integration-profile.service.d.ts +0 -13
  169. package/dist/integration-profile/integration-profile.service.d.ts.map +1 -1
  170. package/dist/integration-profile/integration-profile.service.js +5 -40
  171. package/dist/integration-profile/integration-profile.service.js.map +1 -1
  172. package/dist/integration-profile/integration-profile.utils.js +5 -5
  173. package/dist/integration-profile/integration-profile.utils.js.map +1 -1
  174. package/dist/integration-profile/testers/index.d.ts.map +1 -1
  175. package/dist/integration-profile/testers/index.js +2 -0
  176. package/dist/integration-profile/testers/index.js.map +1 -1
  177. package/dist/integration-profile/testers/shipping.testers.d.ts +3 -0
  178. package/dist/integration-profile/testers/shipping.testers.d.ts.map +1 -0
  179. package/dist/integration-profile/testers/shipping.testers.js +71 -0
  180. package/dist/integration-profile/testers/shipping.testers.js.map +1 -0
  181. package/dist/locale/locale.controller.d.ts +1 -1
  182. package/dist/locale/locale.service.d.ts +1 -1
  183. package/dist/mail/dto/send.dto.d.ts +6 -1
  184. package/dist/mail/dto/send.dto.d.ts.map +1 -1
  185. package/dist/mail/dto/send.dto.js.map +1 -1
  186. package/dist/mail/mail.service.d.ts +9 -0
  187. package/dist/mail/mail.service.d.ts.map +1 -1
  188. package/dist/mail/mail.service.js +34 -14
  189. package/dist/mail/mail.service.js.map +1 -1
  190. package/dist/mail-sent/mail-sent.controller.d.ts +1 -1
  191. package/dist/mail-sent/mail-sent.service.d.ts +1 -1
  192. package/dist/mail-sent/mail-sent.service.d.ts.map +1 -1
  193. package/dist/mail-sent/mail-sent.service.js +2 -1
  194. package/dist/mail-sent/mail-sent.service.js.map +1 -1
  195. package/dist/mail-sent/mail-sent.sort.d.ts +9 -0
  196. package/dist/mail-sent/mail-sent.sort.d.ts.map +1 -0
  197. package/dist/mail-sent/mail-sent.sort.js +19 -0
  198. package/dist/mail-sent/mail-sent.sort.js.map +1 -0
  199. package/dist/mcp/filters/mcp-challenge.filter.d.ts +20 -0
  200. package/dist/mcp/filters/mcp-challenge.filter.d.ts.map +1 -0
  201. package/dist/mcp/filters/mcp-challenge.filter.js +69 -0
  202. package/dist/mcp/filters/mcp-challenge.filter.js.map +1 -0
  203. package/dist/mcp/guards/mcp-auth.guard.d.ts +4 -1
  204. package/dist/mcp/guards/mcp-auth.guard.d.ts.map +1 -1
  205. package/dist/mcp/guards/mcp-auth.guard.js +19 -5
  206. package/dist/mcp/guards/mcp-auth.guard.js.map +1 -1
  207. package/dist/mcp/guards/mcp-permission.guard.d.ts +25 -3
  208. package/dist/mcp/guards/mcp-permission.guard.d.ts.map +1 -1
  209. package/dist/mcp/guards/mcp-permission.guard.js +46 -26
  210. package/dist/mcp/guards/mcp-permission.guard.js.map +1 -1
  211. package/dist/mcp/mcp-audit.service.d.ts +17 -0
  212. package/dist/mcp/mcp-audit.service.d.ts.map +1 -1
  213. package/dist/mcp/mcp-audit.service.js +32 -3
  214. package/dist/mcp/mcp-audit.service.js.map +1 -1
  215. package/dist/mcp/mcp-permission.service.d.ts +64 -0
  216. package/dist/mcp/mcp-permission.service.d.ts.map +1 -0
  217. package/dist/mcp/mcp-permission.service.js +178 -0
  218. package/dist/mcp/mcp-permission.service.js.map +1 -0
  219. package/dist/mcp/mcp-server.service.d.ts +3 -1
  220. package/dist/mcp/mcp-server.service.d.ts.map +1 -1
  221. package/dist/mcp/mcp-server.service.js +36 -15
  222. package/dist/mcp/mcp-server.service.js.map +1 -1
  223. package/dist/mcp/mcp.controller.d.ts.map +1 -1
  224. package/dist/mcp/mcp.controller.js +10 -2
  225. package/dist/mcp/mcp.controller.js.map +1 -1
  226. package/dist/mcp/mcp.module.d.ts.map +1 -1
  227. package/dist/mcp/mcp.module.js +5 -1
  228. package/dist/mcp/mcp.module.js.map +1 -1
  229. package/dist/mcp/tools/core-ai.mcp-tools.js +2 -9
  230. package/dist/mcp/tools/core-ai.mcp-tools.js.map +1 -1
  231. package/dist/mcp/tools/core-dashboard-items.mcp-tools.js +1 -1
  232. package/dist/mcp/tools/core-dashboard-items.mcp-tools.js.map +1 -1
  233. package/dist/mcp/tools/core-dashboard.mcp-tools.js +2 -9
  234. package/dist/mcp/tools/core-dashboard.mcp-tools.js.map +1 -1
  235. package/dist/mcp/tools/core-event-webhooks.mcp-tools.d.ts.map +1 -1
  236. package/dist/mcp/tools/core-event-webhooks.mcp-tools.js +2 -10
  237. package/dist/mcp/tools/core-event-webhooks.mcp-tools.js.map +1 -1
  238. package/dist/mcp/tools/core-files.mcp-tools.d.ts +17 -5
  239. package/dist/mcp/tools/core-files.mcp-tools.d.ts.map +1 -1
  240. package/dist/mcp/tools/core-files.mcp-tools.js +186 -24
  241. package/dist/mcp/tools/core-files.mcp-tools.js.map +1 -1
  242. package/dist/mcp/tools/core-integration-events.mcp-tools.js +2 -9
  243. package/dist/mcp/tools/core-integration-events.mcp-tools.js.map +1 -1
  244. package/dist/mcp/tools/core-mail-sent.mcp-tools.js +2 -14
  245. package/dist/mcp/tools/core-mail-sent.mcp-tools.js.map +1 -1
  246. package/dist/mcp/tools/core-mail.mcp-tools.js +2 -9
  247. package/dist/mcp/tools/core-mail.mcp-tools.js.map +1 -1
  248. package/dist/mcp/tools/core-menus.mcp-tools.d.ts.map +1 -1
  249. package/dist/mcp/tools/core-menus.mcp-tools.js +2 -10
  250. package/dist/mcp/tools/core-menus.mcp-tools.js.map +1 -1
  251. package/dist/mcp/tools/core-notifications.mcp-tools.d.ts.map +1 -1
  252. package/dist/mcp/tools/core-notifications.mcp-tools.js +0 -1
  253. package/dist/mcp/tools/core-notifications.mcp-tools.js.map +1 -1
  254. package/dist/mcp/tools/core-roles.mcp-tools.d.ts.map +1 -1
  255. package/dist/mcp/tools/core-roles.mcp-tools.js +2 -13
  256. package/dist/mcp/tools/core-roles.mcp-tools.js.map +1 -1
  257. package/dist/mcp/tools/core-routes.mcp-tools.d.ts.map +1 -1
  258. package/dist/mcp/tools/core-routes.mcp-tools.js +2 -11
  259. package/dist/mcp/tools/core-routes.mcp-tools.js.map +1 -1
  260. package/dist/mcp/tools/core-screens.mcp-tools.d.ts.map +1 -1
  261. package/dist/mcp/tools/core-screens.mcp-tools.js +2 -11
  262. package/dist/mcp/tools/core-screens.mcp-tools.js.map +1 -1
  263. package/dist/mcp/tools/core-sessions.mcp-tools.d.ts.map +1 -1
  264. package/dist/mcp/tools/core-sessions.mcp-tools.js +0 -2
  265. package/dist/mcp/tools/core-sessions.mcp-tools.js.map +1 -1
  266. package/dist/mcp/tools/core-settings.mcp-tools.d.ts.map +1 -1
  267. package/dist/mcp/tools/core-settings.mcp-tools.js +2 -10
  268. package/dist/mcp/tools/core-settings.mcp-tools.js.map +1 -1
  269. package/dist/mcp/tools/core-users.mcp-tools.js +2 -9
  270. package/dist/mcp/tools/core-users.mcp-tools.js.map +1 -1
  271. package/dist/mcp/tools/core-webhooks.mcp-tools.d.ts.map +1 -1
  272. package/dist/mcp/tools/core-webhooks.mcp-tools.js +2 -10
  273. package/dist/mcp/tools/core-webhooks.mcp-tools.js.map +1 -1
  274. package/dist/mcp/types/mcp-context.type.d.ts +9 -0
  275. package/dist/mcp/types/mcp-context.type.d.ts.map +1 -1
  276. package/dist/mcp-chat/mcp-chat.service.d.ts.map +1 -1
  277. package/dist/mcp-chat/mcp-chat.service.js +8 -0
  278. package/dist/mcp-chat/mcp-chat.service.js.map +1 -1
  279. package/dist/meeting/meeting-provider.registry.d.ts +115 -0
  280. package/dist/meeting/meeting-provider.registry.d.ts.map +1 -1
  281. package/dist/meeting/meeting-provider.registry.js.map +1 -1
  282. package/dist/meeting/meeting.constants.d.ts +70 -0
  283. package/dist/meeting/meeting.constants.d.ts.map +1 -1
  284. package/dist/meeting/meeting.constants.js +9 -1
  285. package/dist/meeting/meeting.constants.js.map +1 -1
  286. package/dist/menu/menu.service.d.ts.map +1 -1
  287. package/dist/menu/menu.service.js +29 -9
  288. package/dist/menu/menu.service.js.map +1 -1
  289. package/dist/message-template/dto/update-message-template.dto.d.ts +18 -0
  290. package/dist/message-template/dto/update-message-template.dto.d.ts.map +1 -0
  291. package/dist/message-template/dto/update-message-template.dto.js +38 -0
  292. package/dist/message-template/dto/update-message-template.dto.js.map +1 -0
  293. package/dist/message-template/message-template-admin.service.d.ts +70 -0
  294. package/dist/message-template/message-template-admin.service.d.ts.map +1 -0
  295. package/dist/message-template/message-template-admin.service.js +226 -0
  296. package/dist/message-template/message-template-admin.service.js.map +1 -0
  297. package/dist/message-template/message-template.controller.d.ts +29 -0
  298. package/dist/message-template/message-template.controller.d.ts.map +1 -0
  299. package/dist/message-template/message-template.controller.js +101 -0
  300. package/dist/message-template/message-template.controller.js.map +1 -0
  301. package/dist/message-template/message-template.module.d.ts +10 -0
  302. package/dist/message-template/message-template.module.d.ts.map +1 -0
  303. package/dist/message-template/message-template.module.js +33 -0
  304. package/dist/message-template/message-template.module.js.map +1 -0
  305. package/dist/message-template/message-template.registry.d.ts +55 -0
  306. package/dist/message-template/message-template.registry.d.ts.map +1 -0
  307. package/dist/message-template/message-template.registry.js +64 -0
  308. package/dist/message-template/message-template.registry.js.map +1 -0
  309. package/dist/message-template/message-template.service.d.ts +59 -0
  310. package/dist/message-template/message-template.service.d.ts.map +1 -0
  311. package/dist/message-template/message-template.service.js +166 -0
  312. package/dist/message-template/message-template.service.js.map +1 -0
  313. package/dist/notification/notification.constants.d.ts +11 -0
  314. package/dist/notification/notification.constants.d.ts.map +1 -0
  315. package/dist/notification/notification.constants.js +14 -0
  316. package/dist/notification/notification.constants.js.map +1 -0
  317. package/dist/notification/notification.controller.d.ts +20 -20
  318. package/dist/notification/notification.module.d.ts.map +1 -1
  319. package/dist/notification/notification.module.js +3 -0
  320. package/dist/notification/notification.module.js.map +1 -1
  321. package/dist/notification/notification.service.d.ts +33 -21
  322. package/dist/notification/notification.service.d.ts.map +1 -1
  323. package/dist/notification/notification.service.js +36 -2
  324. package/dist/notification/notification.service.js.map +1 -1
  325. package/dist/oauth/oauth.controller.d.ts +4 -6
  326. package/dist/oauth/oauth.controller.d.ts.map +1 -1
  327. package/dist/oauth/oauth.controller.js +0 -1
  328. package/dist/oauth/oauth.controller.js.map +1 -1
  329. package/dist/oauth/oauth.errors.d.ts +15 -1
  330. package/dist/oauth/oauth.errors.d.ts.map +1 -1
  331. package/dist/oauth/oauth.errors.js +9 -1
  332. package/dist/oauth/oauth.errors.js.map +1 -1
  333. package/dist/oauth/oauth.module.d.ts.map +1 -1
  334. package/dist/oauth/oauth.module.js +6 -1
  335. package/dist/oauth/oauth.module.js.map +1 -1
  336. package/dist/oauth/oauth.service.d.ts +25 -5
  337. package/dist/oauth/oauth.service.d.ts.map +1 -1
  338. package/dist/oauth/oauth.service.js +63 -27
  339. package/dist/oauth/oauth.service.js.map +1 -1
  340. package/dist/oauth/providers/abstract.provider.d.ts +10 -0
  341. package/dist/oauth/providers/abstract.provider.d.ts.map +1 -1
  342. package/dist/oauth/providers/abstract.provider.js +39 -12
  343. package/dist/oauth/providers/abstract.provider.js.map +1 -1
  344. package/dist/oauth/providers/github.provider.d.ts +1 -1
  345. package/dist/oauth/providers/github.provider.d.ts.map +1 -1
  346. package/dist/oauth/providers/github.provider.js +48 -22
  347. package/dist/oauth/providers/github.provider.js.map +1 -1
  348. package/dist/oauth/providers/microsoft-entra-id.provider.d.ts.map +1 -1
  349. package/dist/oauth/providers/microsoft-entra-id.provider.js +6 -0
  350. package/dist/oauth/providers/microsoft-entra-id.provider.js.map +1 -1
  351. package/dist/observability/monitored-cron.d.ts +29 -12
  352. package/dist/observability/monitored-cron.d.ts.map +1 -1
  353. package/dist/observability/monitored-cron.js +131 -46
  354. package/dist/observability/monitored-cron.js.map +1 -1
  355. package/dist/pairing/pairing.service.d.ts +6 -2
  356. package/dist/pairing/pairing.service.d.ts.map +1 -1
  357. package/dist/profile/dto/change-password.dto.d.ts.map +1 -1
  358. package/dist/profile/dto/change-password.dto.js +4 -6
  359. package/dist/profile/dto/change-password.dto.js.map +1 -1
  360. package/dist/profile/profile.controller.d.ts +1 -1
  361. package/dist/profile/profile.service.d.ts +1 -1
  362. package/dist/profile/profile.service.d.ts.map +1 -1
  363. package/dist/profile/profile.service.js +9 -3
  364. package/dist/profile/profile.service.js.map +1 -1
  365. package/dist/realtime/realtime-tick.coalescer.d.ts +34 -0
  366. package/dist/realtime/realtime-tick.coalescer.d.ts.map +1 -0
  367. package/dist/realtime/realtime-tick.coalescer.js +60 -0
  368. package/dist/realtime/realtime-tick.coalescer.js.map +1 -0
  369. package/dist/realtime/realtime.service.d.ts +2 -0
  370. package/dist/realtime/realtime.service.d.ts.map +1 -1
  371. package/dist/realtime/realtime.service.js +22 -2
  372. package/dist/realtime/realtime.service.js.map +1 -1
  373. package/dist/redis/redis-kv.service.d.ts +90 -0
  374. package/dist/redis/redis-kv.service.d.ts.map +1 -0
  375. package/dist/redis/redis-kv.service.js +247 -0
  376. package/dist/redis/redis-kv.service.js.map +1 -0
  377. package/dist/redis/redis-master.d.ts +29 -0
  378. package/dist/redis/redis-master.d.ts.map +1 -0
  379. package/dist/redis/redis-master.js +81 -0
  380. package/dist/redis/redis-master.js.map +1 -0
  381. package/dist/redis/redis-pubsub.d.ts +12 -0
  382. package/dist/redis/redis-pubsub.d.ts.map +1 -1
  383. package/dist/redis/redis-pubsub.js +25 -2
  384. package/dist/redis/redis-pubsub.js.map +1 -1
  385. package/dist/redis/redis.module.d.ts +11 -0
  386. package/dist/redis/redis.module.d.ts.map +1 -0
  387. package/dist/redis/redis.module.js +30 -0
  388. package/dist/redis/redis.module.js.map +1 -0
  389. package/dist/session/session.controller.d.ts +6 -2
  390. package/dist/session/session.controller.d.ts.map +1 -1
  391. package/dist/session/session.service.d.ts +118 -15
  392. package/dist/session/session.service.d.ts.map +1 -1
  393. package/dist/session/session.service.js +251 -77
  394. package/dist/session/session.service.js.map +1 -1
  395. package/dist/setting/setting.controller.d.ts +5 -0
  396. package/dist/setting/setting.controller.d.ts.map +1 -1
  397. package/dist/setting/setting.service.d.ts +7 -0
  398. package/dist/setting/setting.service.d.ts.map +1 -1
  399. package/dist/setting/setting.service.js +38 -3
  400. package/dist/setting/setting.service.js.map +1 -1
  401. package/dist/task/task.service.d.ts +17 -0
  402. package/dist/task/task.service.d.ts.map +1 -1
  403. package/dist/task/task.service.js +48 -13
  404. package/dist/task/task.service.js.map +1 -1
  405. package/dist/token/token.service.d.ts +19 -1
  406. package/dist/token/token.service.d.ts.map +1 -1
  407. package/dist/token/token.service.js +39 -2
  408. package/dist/token/token.service.js.map +1 -1
  409. package/dist/user/user-credential.util.d.ts +10 -0
  410. package/dist/user/user-credential.util.d.ts.map +1 -1
  411. package/dist/user/user-credential.util.js +14 -1
  412. package/dist/user/user-credential.util.js.map +1 -1
  413. package/dist/user/user.service.d.ts +12 -4
  414. package/dist/user/user.service.d.ts.map +1 -1
  415. package/dist/user/user.service.js +2 -11
  416. package/dist/user/user.service.js.map +1 -1
  417. package/dist/user/user.sort.d.ts +16 -0
  418. package/dist/user/user.sort.d.ts.map +1 -0
  419. package/dist/user/user.sort.js +25 -0
  420. package/dist/user/user.sort.js.map +1 -0
  421. package/dist/utils/abbreviate-name.d.ts +13 -0
  422. package/dist/utils/abbreviate-name.d.ts.map +1 -0
  423. package/dist/utils/abbreviate-name.js +42 -0
  424. package/dist/utils/abbreviate-name.js.map +1 -0
  425. package/dist/utils/date-range-query.dto.d.ts +11 -0
  426. package/dist/utils/date-range-query.dto.d.ts.map +1 -0
  427. package/dist/utils/date-range-query.dto.js +63 -0
  428. package/dist/utils/date-range-query.dto.js.map +1 -0
  429. package/dist/utils/date-range.d.ts +96 -0
  430. package/dist/utils/date-range.d.ts.map +1 -0
  431. package/dist/utils/date-range.js +172 -0
  432. package/dist/utils/date-range.js.map +1 -0
  433. package/dist/webhook-integration/webhook-utils.d.ts.map +1 -1
  434. package/dist/webhook-integration/webhook-utils.js +24 -0
  435. package/dist/webhook-integration/webhook-utils.js.map +1 -1
  436. package/dist/whatsapp-sender/whatsapp-recipients.d.ts +49 -0
  437. package/dist/whatsapp-sender/whatsapp-recipients.d.ts.map +1 -0
  438. package/dist/whatsapp-sender/whatsapp-recipients.js +66 -0
  439. package/dist/whatsapp-sender/whatsapp-recipients.js.map +1 -0
  440. package/dist/whatsapp-sender/whatsapp-sender.service.d.ts +25 -0
  441. package/dist/whatsapp-sender/whatsapp-sender.service.d.ts.map +1 -1
  442. package/dist/whatsapp-sender/whatsapp-sender.service.js +46 -5
  443. package/dist/whatsapp-sender/whatsapp-sender.service.js.map +1 -1
  444. package/hedhog/data/integration_provider.yaml +9 -0
  445. package/hedhog/data/integration_type.yaml +6 -0
  446. package/hedhog/data/locale.yaml +0 -1
  447. package/hedhog/data/mail.yaml +2 -2
  448. package/hedhog/data/mail_layout.yaml +6 -3
  449. package/hedhog/data/menu.yaml +25 -5
  450. package/hedhog/data/route.yaml +140 -0
  451. package/hedhog/data/setting_group.yaml +137 -3
  452. package/hedhog/frontend/app/access-log/page.tsx.ejs +47 -53
  453. package/hedhog/frontend/app/account/components/active-sessions.tsx.ejs +33 -8
  454. package/hedhog/frontend/app/account/components/mcp-tokens.tsx.ejs +54 -13
  455. package/hedhog/frontend/app/account/components/mfa-method-card.tsx.ejs +7 -1
  456. package/hedhog/frontend/app/account/components/recovery-codes-dialog.tsx.ejs +1 -0
  457. package/hedhog/frontend/app/account/components/tokens.tsx.ejs +47 -17
  458. package/hedhog/frontend/app/ai_agent/page.tsx.ejs +46 -5
  459. package/hedhog/frontend/app/ai_instruction/_components/ai-instruction-form.tsx.ejs +101 -30
  460. package/hedhog/frontend/app/ai_instruction/_components/ai-instruction-versions.tsx.ejs +24 -8
  461. package/hedhog/frontend/app/ai_instruction/page.tsx.ejs +80 -15
  462. package/hedhog/frontend/app/configurations/[slug]/components/image-optimization-action.tsx.ejs +166 -0
  463. package/hedhog/frontend/app/configurations/[slug]/components/setting-field.test.tsx.ejs +145 -45
  464. package/hedhog/frontend/app/configurations/[slug]/components/setting-field.tsx.ejs +99 -219
  465. package/hedhog/frontend/app/configurations/[slug]/page.tsx.ejs +19 -1
  466. package/hedhog/frontend/app/configurations/layout.tsx.ejs +19 -5
  467. package/hedhog/frontend/app/dashboard/[slug]/widget-renderer.tsx.ejs +2 -8
  468. package/hedhog/frontend/app/dashboard/components/dynamic-widget.tsx.ejs +3 -0
  469. package/hedhog/frontend/app/dashboard/components/widget-wrapper.tsx.ejs +4 -0
  470. package/hedhog/frontend/app/dashboard/dashboard-home-tabs.tsx.ejs +43 -44
  471. package/hedhog/frontend/app/dashboard/management/tabs/component-roles-tab.tsx.ejs +41 -3
  472. package/hedhog/frontend/app/dashboard/management/tabs/components-tab.tsx.ejs +42 -2
  473. package/hedhog/frontend/app/dashboard/management/tabs/dashboard-roles-tab.tsx.ejs +41 -3
  474. package/hedhog/frontend/app/dashboard/management/tabs/dashboards-tab.tsx.ejs +39 -4
  475. package/hedhog/frontend/app/dashboard/management/tabs/items-tab.tsx.ejs +42 -3
  476. package/hedhog/frontend/app/incidents/page.tsx.ejs +60 -31
  477. package/hedhog/frontend/app/integration/profiles/page.tsx.ejs +45 -5
  478. package/hedhog/frontend/app/integrations-webhooks/page.tsx.ejs +92 -15
  479. package/hedhog/frontend/app/mail/log/page.tsx.ejs +109 -61
  480. package/hedhog/frontend/app/mail/template/page.tsx.ejs +125 -23
  481. package/hedhog/frontend/app/mcp_chat/chat-components.tsx.ejs +13 -15
  482. package/hedhog/frontend/app/mcp_chat/page.tsx.ejs +116 -110
  483. package/hedhog/frontend/app/message-templates/_components/message-template-sheet.tsx.ejs +245 -0
  484. package/hedhog/frontend/app/message-templates/_lib/types.ts.ejs +24 -0
  485. package/hedhog/frontend/app/message-templates/page.tsx.ejs +182 -0
  486. package/hedhog/frontend/app/pages/_components/page-wizard-sheet.tsx.ejs +1 -0
  487. package/hedhog/frontend/app/pages/page.tsx.ejs +94 -9
  488. package/hedhog/frontend/app/roles/menus.tsx.ejs +4 -4
  489. package/hedhog/frontend/app/roles/routes.tsx.ejs +4 -4
  490. package/hedhog/frontend/app/roles/users.tsx.ejs +4 -4
  491. package/hedhog/frontend/app/setting-list/page.tsx.ejs +71 -9
  492. package/hedhog/frontend/app/users/page.tsx.ejs +77 -67
  493. package/hedhog/frontend/messages/en.json +183 -36
  494. package/hedhog/frontend/messages/pt.json +183 -36
  495. package/hedhog/table/cron_lock.yaml +17 -0
  496. package/hedhog/table/file.yaml +13 -1
  497. package/hedhog/table/file_upload_chunk.yaml +23 -0
  498. package/hedhog/table/file_upload_ticket.yaml +67 -0
  499. package/hedhog/table/mcp_tool_call_log.yaml +30 -22
  500. package/hedhog/table/message_template.yaml +33 -0
  501. package/hedhog/table/setting.yaml +8 -0
  502. package/hedhog/table/user_session.yaml +36 -1
  503. package/package.json +7 -5
  504. package/src/ai/ai-agent.sort.ts +21 -0
  505. package/src/ai/ai.service.spec.ts +173 -1
  506. package/src/ai/ai.service.ts +64 -193
  507. package/src/ai-instruction/ai-instruction.service.ts +32 -28
  508. package/src/ai-instruction/ai-instruction.sort.ts +32 -0
  509. package/src/auth/auth.module.ts +8 -1
  510. package/src/auth/auth.service.spec.ts +108 -1
  511. package/src/auth/auth.service.ts +59 -5
  512. package/src/auth/guards/auth.guard.ts +9 -1
  513. package/src/authorize/authorize.controller.ts +126 -11
  514. package/src/authorize/authorize.errors.ts +55 -0
  515. package/src/authorize/authorize.module.ts +6 -1
  516. package/src/authorize/authorize.service.spec.ts +379 -7
  517. package/src/authorize/authorize.service.ts +309 -23
  518. package/src/authorize/dto/authorize-info.dto.ts +21 -3
  519. package/src/authorize/dto/consent.dto.ts +21 -3
  520. package/src/authorize/dto/token.dto.ts +24 -2
  521. package/src/authorize/oauth-exception.filter.ts +58 -0
  522. package/src/authorize/oauth-metadata.service.ts +67 -0
  523. package/src/authorize/well-known.controller.spec.ts +84 -0
  524. package/src/authorize/well-known.controller.ts +96 -0
  525. package/src/captcha/captcha.service.spec.ts +211 -4
  526. package/src/captcha/captcha.service.ts +127 -10
  527. package/src/core.module.ts +6 -0
  528. package/src/dashboard/dashboard-component-role/dashboard-component-role.service.ts +2 -3
  529. package/src/dashboard/dashboard-component-role/dashboard-component-role.sort.ts +18 -0
  530. package/src/dashboard/dashboard-item/dashboard-item.service.ts +2 -3
  531. package/src/dashboard/dashboard-item/dashboard-item.sort.ts +19 -0
  532. package/src/dashboard/dashboard-role/dashboard-role.service.ts +2 -3
  533. package/src/dashboard/dashboard-role/dashboard-role.sort.ts +16 -0
  534. package/src/file/file-upload-ticket.service.spec.ts +422 -0
  535. package/src/file/file-upload-ticket.service.ts +513 -0
  536. package/src/file/file.controller.ts +65 -0
  537. package/src/file/file.module.ts +14 -2
  538. package/src/file/file.service.spec.ts +94 -0
  539. package/src/file/file.service.ts +433 -53
  540. package/src/file/filename-encoding.util.spec.ts +54 -0
  541. package/src/file/filename-encoding.util.ts +67 -0
  542. package/src/file/image-optimization.service.spec.ts +156 -19
  543. package/src/file/image-optimization.service.ts +106 -21
  544. package/src/file/mcp-file-source.schema.ts +83 -0
  545. package/src/file/mcp-file-source.service.spec.ts +473 -0
  546. package/src/file/mcp-file-source.service.ts +445 -0
  547. package/src/file/mimetype-sniff.util.spec.ts +126 -0
  548. package/src/file/mimetype-sniff.util.ts +265 -0
  549. package/src/file/remote-fetch.util.spec.ts +117 -0
  550. package/src/file/remote-fetch.util.ts +330 -0
  551. package/src/impersonation/dto/start-impersonation.dto.ts +5 -2
  552. package/src/impersonation/impersonation.service.spec.ts +24 -1
  553. package/src/impersonation/impersonation.service.ts +14 -4
  554. package/src/incident/incident.controller.ts +9 -1
  555. package/src/incident/incident.service.ts +7 -0
  556. package/src/index.ts +17 -0
  557. package/src/integration-profile/integration-profile.secrets.ts +7 -0
  558. package/src/integration-profile/integration-profile.service.ts +7 -64
  559. package/src/integration-profile/integration-profile.utils.spec.ts +9 -0
  560. package/src/integration-profile/integration-profile.utils.ts +5 -5
  561. package/src/integration-profile/testers/index.ts +2 -0
  562. package/src/integration-profile/testers/remaining.testers.spec.ts +79 -0
  563. package/src/integration-profile/testers/shipping.testers.ts +94 -0
  564. package/src/mail/dto/send.dto.ts +6 -1
  565. package/src/mail/mail-template.spec.ts +58 -1
  566. package/src/mail/mail.service.spec.ts +112 -0
  567. package/src/mail/mail.service.ts +42 -4
  568. package/src/mail-sent/mail-sent.service.ts +3 -0
  569. package/src/mail-sent/mail-sent.sort.ts +19 -0
  570. package/src/mcp/filters/mcp-challenge.filter.spec.ts +76 -0
  571. package/src/mcp/filters/mcp-challenge.filter.ts +70 -0
  572. package/src/mcp/guards/mcp-auth.guard.spec.ts +51 -2
  573. package/src/mcp/guards/mcp-auth.guard.ts +24 -1
  574. package/src/mcp/guards/mcp-permission.guard.spec.ts +109 -15
  575. package/src/mcp/guards/mcp-permission.guard.ts +76 -51
  576. package/src/mcp/mcp-audit.service.spec.ts +107 -0
  577. package/src/mcp/mcp-audit.service.ts +37 -1
  578. package/src/mcp/mcp-permission.service.spec.ts +197 -0
  579. package/src/mcp/mcp-permission.service.ts +184 -0
  580. package/src/mcp/mcp-server.service.spec.ts +84 -2
  581. package/src/mcp/mcp-server.service.ts +111 -87
  582. package/src/mcp/mcp.controller.ts +8 -1
  583. package/src/mcp/mcp.module.ts +5 -1
  584. package/src/mcp/tools/core-ai.mcp-tools.ts +1 -1
  585. package/src/mcp/tools/core-dashboard-items.mcp-tools.ts +1 -1
  586. package/src/mcp/tools/core-dashboard.mcp-tools.ts +1 -1
  587. package/src/mcp/tools/core-event-webhooks.mcp-tools.ts +1 -2
  588. package/src/mcp/tools/core-files.mcp-tools.ts +202 -22
  589. package/src/mcp/tools/core-integration-events.mcp-tools.ts +1 -1
  590. package/src/mcp/tools/core-mail-sent.mcp-tools.ts +1 -1
  591. package/src/mcp/tools/core-mail.mcp-tools.ts +1 -1
  592. package/src/mcp/tools/core-menus.mcp-tools.ts +1 -2
  593. package/src/mcp/tools/core-notifications.mcp-tools.ts +0 -1
  594. package/src/mcp/tools/core-roles.mcp-tools.ts +1 -5
  595. package/src/mcp/tools/core-routes.mcp-tools.ts +1 -3
  596. package/src/mcp/tools/core-screens.mcp-tools.ts +1 -3
  597. package/src/mcp/tools/core-sessions.mcp-tools.ts +0 -2
  598. package/src/mcp/tools/core-settings.mcp-tools.ts +1 -2
  599. package/src/mcp/tools/core-users.mcp-tools.ts +1 -1
  600. package/src/mcp/tools/core-webhooks.mcp-tools.ts +1 -2
  601. package/src/mcp/types/mcp-context.type.ts +15 -6
  602. package/src/mcp-chat/mcp-chat.service.ts +8 -0
  603. package/src/meeting/meeting-provider.registry.ts +121 -0
  604. package/src/meeting/meeting.constants.ts +74 -0
  605. package/src/menu/menu.service.spec.ts +89 -0
  606. package/src/menu/menu.service.ts +29 -11
  607. package/src/message-template/dto/update-message-template.dto.ts +22 -0
  608. package/src/message-template/message-template-admin.service.spec.ts +163 -0
  609. package/src/message-template/message-template-admin.service.ts +239 -0
  610. package/src/message-template/message-template.controller.ts +52 -0
  611. package/src/message-template/message-template.module.ts +21 -0
  612. package/src/message-template/message-template.registry.spec.ts +62 -0
  613. package/src/message-template/message-template.registry.ts +125 -0
  614. package/src/message-template/message-template.service.spec.ts +149 -0
  615. package/src/message-template/message-template.service.ts +149 -0
  616. package/src/notification/notification.constants.ts +10 -0
  617. package/src/notification/notification.module.ts +3 -0
  618. package/src/notification/notification.service.spec.ts +75 -1
  619. package/src/notification/notification.service.ts +39 -1
  620. package/src/oauth/oauth.controller.ts +0 -1
  621. package/src/oauth/oauth.errors.ts +7 -0
  622. package/src/oauth/oauth.module.ts +6 -1
  623. package/src/oauth/oauth.service.spec.ts +58 -7
  624. package/src/oauth/oauth.service.ts +71 -32
  625. package/src/oauth/providers/abstract.provider.spec.ts +192 -0
  626. package/src/oauth/providers/abstract.provider.ts +46 -14
  627. package/src/oauth/providers/github.provider.ts +57 -34
  628. package/src/oauth/providers/microsoft-entra-id.provider.ts +8 -1
  629. package/src/observability/monitored-cron.spec.ts +164 -31
  630. package/src/observability/monitored-cron.ts +154 -62
  631. package/src/profile/dto/change-password.dto.ts +25 -7
  632. package/src/profile/profile.service.spec.ts +97 -0
  633. package/src/profile/profile.service.ts +9 -3
  634. package/src/realtime/realtime-tick.coalescer.spec.ts +92 -0
  635. package/src/realtime/realtime-tick.coalescer.ts +60 -0
  636. package/src/realtime/realtime.service.spec.ts +33 -0
  637. package/src/realtime/realtime.service.ts +28 -2
  638. package/src/redis/redis-kv.service.ts +261 -0
  639. package/src/redis/redis-master.spec.ts +111 -0
  640. package/src/redis/redis-master.ts +86 -0
  641. package/src/redis/redis-pubsub.ts +27 -3
  642. package/src/redis/redis.module.ts +17 -0
  643. package/src/session/session.service.spec.ts +121 -42
  644. package/src/session/session.service.ts +279 -82
  645. package/src/setting/setting.service.ts +44 -3
  646. package/src/task/task.service.spec.ts +41 -0
  647. package/src/task/task.service.ts +53 -13
  648. package/src/token/token.service.spec.ts +90 -0
  649. package/src/token/token.service.ts +48 -2
  650. package/src/user/user-credential.util.ts +14 -5
  651. package/src/user/user.service.ts +2 -12
  652. package/src/user/user.sort.ts +25 -0
  653. package/src/utils/abbreviate-name.spec.ts +50 -0
  654. package/src/utils/abbreviate-name.ts +44 -0
  655. package/src/utils/date-range-query.dto.ts +56 -0
  656. package/src/utils/date-range.spec.ts +175 -0
  657. package/src/utils/date-range.ts +246 -0
  658. package/src/webhook-integration/webhook-utils.spec.ts +67 -0
  659. package/src/webhook-integration/webhook-utils.ts +26 -0
  660. package/src/whatsapp-sender/whatsapp-recipients.spec.ts +89 -0
  661. package/src/whatsapp-sender/whatsapp-recipients.ts +83 -0
  662. package/src/whatsapp-sender/whatsapp-sender.service.spec.ts +112 -0
  663. package/src/whatsapp-sender/whatsapp-sender.service.ts +58 -5
  664. package/hedhog/query/device_pairing_request.sql +0 -46
  665. package/hedhog/query/impersonation_grant.sql +0 -71
  666. package/hedhog/query/oauth_authorize_pkce.sql +0 -58
  667. package/hedhog/query/oauth_mobile_state_token.sql +0 -30
  668. package/hedhog/query/oauth_web_ref_token.sql +0 -25
@@ -0,0 +1,513 @@
1
+ import { Prisma, PrismaService } from '@hed-hog/api-prisma';
2
+ import {
3
+ BadRequestException,
4
+ forwardRef,
5
+ Inject,
6
+ Injectable,
7
+ Logger,
8
+ NotFoundException,
9
+ } from '@nestjs/common';
10
+ import { JwtService } from '@nestjs/jwt';
11
+ import { createHash } from 'crypto';
12
+ import { SettingService } from '../setting/setting.service';
13
+ import { FileService } from './file.service';
14
+ import { findMimetypeConflict, MIMETYPE_SNIFF_BYTES } from './mimetype-sniff.util';
15
+
16
+ /** Tamanho, hash e cabeçalho — o suficiente para validar sem carregar o arquivo. */
17
+ export interface UploadedContentDigest {
18
+ bytes: number;
19
+ sha256: string;
20
+ header: Buffer;
21
+ }
22
+
23
+ /**
24
+ * Upload cujo binário não viaja dentro da chamada.
25
+ *
26
+ * O cliente abre um ticket, manda os bytes por fora (um PUT assinado, ou em partes quando
27
+ * não consegue falar HTTP) e só então usa o `fileId` na tool que precisa do arquivo. O
28
+ * ticket é o que amarra esse vaivém a um usuário, a um nome, a um mimetype e a um
29
+ * tamanho declarados — sem ele o endpoint de upload seria uma porta aberta, já que ele
30
+ * responde sem sessão, autenticado apenas pelo token.
31
+ *
32
+ * Por que não uma URL pré-assinada do próprio bucket: nenhum dos cinco providers
33
+ * (`s3`, `spaces`, `gcs`, `abs`, `local`) tem presign de escrita hoje — `getSignedUrl` só
34
+ * aparece com `GetObjectCommand` —, o provider `local` do dev não teria caminho nenhum, e
35
+ * validar o mimetype pelo conteúdo só seria possível depois do objeto já estar no bucket.
36
+ * O PUT assinado da própria API resolve os cinco de uma vez e mantém a validação antes da
37
+ * gravação. Os bytes ainda passam pela API, mas o objetivo era tirá-los da conversa.
38
+ */
39
+
40
+ export type UploadTicketMode = 'signed_url' | 'chunked';
41
+
42
+ export interface CreateUploadTicketParams {
43
+ userId: number;
44
+ fileName: string;
45
+ mimeType: string;
46
+ sizeBytes: number;
47
+ destination?: string;
48
+ isPrivate?: boolean;
49
+ sha256?: string;
50
+ idempotencyKey?: string;
51
+ mode: UploadTicketMode;
52
+ }
53
+
54
+ const DEFAULT_UPLOAD_TTL_SECONDS = 900;
55
+ const DEFAULT_CHUNK_BYTES = 65536;
56
+ /** Onde caem os uploads que ainda não têm dono no domínio (o título, a tarefa, a página). */
57
+ const DEFAULT_DESTINATION = 'mcp/uploads';
58
+
59
+ @Injectable()
60
+ export class FileUploadTicketService {
61
+ private readonly logger = new Logger(FileUploadTicketService.name);
62
+
63
+ constructor(
64
+ private readonly prismaService: PrismaService,
65
+ private readonly jwtService: JwtService,
66
+ @Inject(forwardRef(() => SettingService))
67
+ private readonly settingService: SettingService,
68
+ @Inject(forwardRef(() => FileService))
69
+ private readonly fileService: FileService,
70
+ ) {}
71
+
72
+ private async limits() {
73
+ const settings = await this.settingService.getSettingValues([
74
+ 'storage-max-size',
75
+ 'storage-upload-url-ttl',
76
+ 'mcp-upload-chunk-bytes',
77
+ ]);
78
+
79
+ return {
80
+ maxBytes: Number(settings['storage-max-size']) || 10485760,
81
+ ttlSeconds:
82
+ Number(settings['storage-upload-url-ttl']) || DEFAULT_UPLOAD_TTL_SECONDS,
83
+ chunkBytes: Number(settings['mcp-upload-chunk-bytes']) || DEFAULT_CHUNK_BYTES,
84
+ };
85
+ }
86
+
87
+ /**
88
+ * Abre o ticket. Repetir a mesma `idempotencyKey` devolve o ticket anterior em vez de
89
+ * abrir outro — o retry de um cliente que não viu a resposta não deve render dois
90
+ * uploads nem dois arquivos.
91
+ */
92
+ async create(params: CreateUploadTicketParams) {
93
+ const { maxBytes, ttlSeconds, chunkBytes } = await this.limits();
94
+
95
+ if (!params.fileName?.trim()) {
96
+ throw new BadRequestException(`fileName is required`);
97
+ }
98
+
99
+ if (!params.mimeType?.trim()) {
100
+ throw new BadRequestException(`mimeType is required`);
101
+ }
102
+
103
+ if (!Number.isInteger(params.sizeBytes) || params.sizeBytes <= 0) {
104
+ throw new BadRequestException(`sizeBytes must be a positive integer`);
105
+ }
106
+
107
+ if (params.sizeBytes > maxBytes) {
108
+ throw new BadRequestException(
109
+ `File too large: ${params.sizeBytes} bytes. The storage-max-size setting allows ${maxBytes}.`,
110
+ );
111
+ }
112
+
113
+ // Barra o tipo já na abertura: deixar para o fim faria o cliente subir o arquivo
114
+ // inteiro para só então descobrir que ele nunca seria aceito.
115
+ if (!(await this.fileService.acceptMimetypes(params.mimeType))) {
116
+ throw new BadRequestException(`Invalid file type: ${params.mimeType}`);
117
+ }
118
+
119
+ if (params.sha256 && !/^[0-9a-f]{64}$/i.test(params.sha256)) {
120
+ throw new BadRequestException(`sha256 must be 64 hexadecimal characters`);
121
+ }
122
+
123
+ if (params.idempotencyKey) {
124
+ const existing = await this.prismaService.file_upload_ticket.findFirst({
125
+ where: {
126
+ user_id: params.userId,
127
+ idempotency_key: params.idempotencyKey,
128
+ },
129
+ });
130
+
131
+ if (existing) {
132
+ return { ticket: existing, chunkBytes, reused: true };
133
+ }
134
+ }
135
+
136
+ // Tipado como Unchecked de propósito: extrair o literal para uma variável faz o
137
+ // TypeScript perder a união discriminada do Prisma, e `user_id` (escalar, e não a
138
+ // relação `user`) passa a bater na variante Checked, onde ele é `never`.
139
+ const data: Prisma.file_upload_ticketUncheckedCreateInput = {
140
+ user_id: params.userId,
141
+ filename: params.fileName.trim().slice(0, 255),
142
+ mimetype: params.mimeType.trim(),
143
+ size_bytes: params.sizeBytes,
144
+ destination: (params.destination || DEFAULT_DESTINATION).slice(0, 255),
145
+ is_private: params.isPrivate ?? false,
146
+ sha256: params.sha256 ? params.sha256.toLowerCase() : null,
147
+ mode: params.mode,
148
+ status: 'pending' as const,
149
+ idempotency_key: params.idempotencyKey || null,
150
+ expires_at: new Date(Date.now() + ttlSeconds * 1000),
151
+ };
152
+
153
+ try {
154
+ const ticket = await this.prismaService.file_upload_ticket.create({ data });
155
+ return { ticket, chunkBytes, reused: false };
156
+ } catch (error: any) {
157
+ // A unicidade de (user_id, idempotency_key) é um índice PARCIAL, e o Prisma não
158
+ // modela índice parcial — ele não aparece no schema e o cliente não o conhece.
159
+ // A garantia continua sendo do Postgres, mas a violação chega aqui como P2002 cru
160
+ // em vez de ser evitada pelo `findFirst` acima, que perde a corrida por milissegundos.
161
+ if (error?.code === 'P2002' && params.idempotencyKey) {
162
+ const existing = await this.prismaService.file_upload_ticket.findFirst({
163
+ where: {
164
+ user_id: params.userId,
165
+ idempotency_key: params.idempotencyKey,
166
+ },
167
+ });
168
+
169
+ if (existing) {
170
+ return { ticket: existing, chunkBytes, reused: true };
171
+ }
172
+ }
173
+
174
+ throw error;
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Token do PUT assinado. Carrega só o id do ticket: tudo o mais (usuário, tamanho,
180
+ * tipo, validade) é lido da linha, que é a fonte da verdade e pode ser invalidada.
181
+ */
182
+ signUploadToken(ticketId: number, ttlSeconds: number): string {
183
+ return this.jwtService.sign(
184
+ { t: 'file-upload', ticketId },
185
+ {
186
+ secret: process.env.JWT_SECRET,
187
+ expiresIn: `${Math.max(1, Math.floor(ttlSeconds))}s`,
188
+ },
189
+ );
190
+ }
191
+
192
+ async buildUploadUrl(ticketId: number, req?: any) {
193
+ const { ttlSeconds } = await this.limits();
194
+ const token = this.signUploadToken(ticketId, ttlSeconds);
195
+ const origin = await this.fileService.resolvePublicBaseUrl(
196
+ req ?? ({ protocol: 'https', get: () => '' } as any),
197
+ );
198
+
199
+ return `${origin}/file/upload/${encodeURIComponent(token)}`;
200
+ }
201
+
202
+ /** Lê o ticket do token, sem consumi-lo. */
203
+ async resolveTicketFromToken(token: string) {
204
+ let payload: any;
205
+
206
+ try {
207
+ payload = this.jwtService.verify(token, { secret: process.env.JWT_SECRET });
208
+ } catch {
209
+ throw new BadRequestException(`Invalid or expired upload token`);
210
+ }
211
+
212
+ if (payload?.t !== 'file-upload' || !payload?.ticketId) {
213
+ throw new BadRequestException(`Token is not an upload token`);
214
+ }
215
+
216
+ const ticket = await this.prismaService.file_upload_ticket.findUnique({
217
+ where: { id: Number(payload.ticketId) },
218
+ });
219
+
220
+ if (!ticket) {
221
+ throw new NotFoundException(`Upload ticket not found`);
222
+ }
223
+
224
+ return ticket;
225
+ }
226
+
227
+ /**
228
+ * Marca o ticket como consumido, e só devolve `true` para quem venceu a corrida.
229
+ *
230
+ * O `updateMany` condicional é o que dá uso único sem abrir transação: dois PUTs
231
+ * simultâneos com o mesmo token entram aqui juntos, o Postgres serializa o UPDATE e o
232
+ * segundo enxerga `count: 0` porque o status já não é `pending`.
233
+ */
234
+ async claim(ticketId: number): Promise<boolean> {
235
+ const claimed = await this.prismaService.file_upload_ticket.updateMany({
236
+ where: {
237
+ id: ticketId,
238
+ status: 'pending',
239
+ expires_at: { gt: new Date() },
240
+ },
241
+ data: { status: 'completed', consumed_at: new Date() },
242
+ });
243
+
244
+ return claimed.count === 1;
245
+ }
246
+
247
+ async markFailed(ticketId: number) {
248
+ await this.prismaService.file_upload_ticket
249
+ .update({ where: { id: ticketId }, data: { status: 'failed' } })
250
+ .catch((error: any) =>
251
+ this.logger.warn(`Failed to mark upload ticket ${ticketId}: ${error.message}`),
252
+ );
253
+ }
254
+
255
+ async attachFile(ticketId: number, fileId: number) {
256
+ await this.prismaService.file_upload_ticket.update({
257
+ where: { id: ticketId },
258
+ data: { file_id: fileId },
259
+ });
260
+ }
261
+
262
+ /**
263
+ * O que basta saber sobre o conteúdo para conferi-lo contra o ticket.
264
+ *
265
+ * Separado do buffer de propósito: o PUT assinado escreve direto no disco e nunca tem o
266
+ * arquivo inteiro em memória, então ele produz estes três valores durante o stream. O
267
+ * modo em partes, que monta o buffer de qualquer forma, deriva os mesmos com
268
+ * `describeUploadedBuffer`.
269
+ */
270
+ static describeUploadedBuffer(buffer: Buffer): UploadedContentDigest {
271
+ return {
272
+ bytes: buffer.length,
273
+ sha256: createHash('sha256').update(buffer).digest('hex'),
274
+ header: buffer.subarray(0, MIMETYPE_SNIFF_BYTES),
275
+ };
276
+ }
277
+
278
+ /**
279
+ * Confere tamanho, integridade e o tipo real contra o declarado.
280
+ *
281
+ * Roda para os dois modos, no ponto em que os bytes já existem por inteiro — é aqui que
282
+ * um `.exe` declarado como `application/pdf` é recusado, coisa que a validação por
283
+ * header nunca pegaria, e que o `storage-accept-mimetype` sozinho também não pega
284
+ * porque ele só olha a string que o cliente mandou.
285
+ */
286
+ async assertContentMatchesTicket(ticket: any, digest: UploadedContentDigest) {
287
+ const { maxBytes } = await this.limits();
288
+
289
+ if (digest.bytes === 0) {
290
+ throw new BadRequestException(`Uploaded content is empty`);
291
+ }
292
+
293
+ if (digest.bytes > maxBytes) {
294
+ throw new BadRequestException(
295
+ `File too large: ${digest.bytes} bytes. The storage-max-size setting allows ${maxBytes}.`,
296
+ );
297
+ }
298
+
299
+ if (digest.bytes !== ticket.size_bytes) {
300
+ throw new BadRequestException(
301
+ `Uploaded ${digest.bytes} bytes but the ticket declared ${ticket.size_bytes}`,
302
+ );
303
+ }
304
+
305
+ if (ticket.sha256 && digest.sha256 !== ticket.sha256) {
306
+ throw new BadRequestException(
307
+ `sha256 mismatch: declared ${ticket.sha256}, uploaded content hashes to ${digest.sha256}`,
308
+ );
309
+ }
310
+
311
+ const conflict = findMimetypeConflict(ticket.mimetype, digest.header);
312
+
313
+ if (conflict) {
314
+ throw new BadRequestException(
315
+ `Declared mimeType ${ticket.mimetype} but the content is ${conflict}`,
316
+ );
317
+ }
318
+ }
319
+
320
+ // ── Modo em partes ─────────────────────────────────────────────────────────
321
+
322
+ /**
323
+ * Grava uma parte. Reenviar o mesmo índice sobrescreve, para que o retry de uma parte
324
+ * perdida não duplique nem desalinhe a montagem.
325
+ */
326
+ async appendChunk(
327
+ uploadId: number,
328
+ index: number,
329
+ chunkBase64: string,
330
+ userId: number,
331
+ ) {
332
+ const ticket = await this.requireOwnPendingTicket(uploadId, userId);
333
+
334
+ if (ticket.mode !== 'chunked') {
335
+ throw new BadRequestException(
336
+ `Upload ${uploadId} was opened for direct upload; use the signed URL instead of append`,
337
+ );
338
+ }
339
+
340
+ if (!Number.isInteger(index) || index < 0) {
341
+ throw new BadRequestException(`index must be a non-negative integer`);
342
+ }
343
+
344
+ if (!chunkBase64) {
345
+ throw new BadRequestException(`chunkBase64 is required`);
346
+ }
347
+
348
+ const { chunkBytes } = await this.limits();
349
+ const data = Buffer.from(chunkBase64, 'base64');
350
+
351
+ if (data.length === 0) {
352
+ throw new BadRequestException(`chunkBase64 decoded to zero bytes`);
353
+ }
354
+
355
+ if (data.length > chunkBytes) {
356
+ throw new BadRequestException(
357
+ `Chunk ${index} has ${data.length} bytes, above the ${chunkBytes} allowed by the mcp-upload-chunk-bytes setting`,
358
+ );
359
+ }
360
+
361
+ await this.prismaService.file_upload_chunk.upsert({
362
+ where: { ticket_id_index: { ticket_id: uploadId, index } },
363
+ create: { ticket_id: uploadId, index, data },
364
+ update: { data },
365
+ });
366
+
367
+ const received = await this.prismaService.file_upload_chunk.count({
368
+ where: { ticket_id: uploadId },
369
+ });
370
+
371
+ const expected = Math.ceil(ticket.size_bytes / chunkBytes);
372
+
373
+ return {
374
+ uploadId,
375
+ index,
376
+ received,
377
+ expected,
378
+ remaining: Math.max(0, expected - received),
379
+ };
380
+ }
381
+
382
+ private async requireOwnPendingTicket(uploadId: number, userId: number) {
383
+ const ticket = await this.prismaService.file_upload_ticket.findUnique({
384
+ where: { id: uploadId },
385
+ });
386
+
387
+ if (!ticket) {
388
+ throw new NotFoundException(`Upload ticket not found: ${uploadId}`);
389
+ }
390
+
391
+ // O ticket é do usuário que o abriu, sem exceção para admin: ele não é um recurso
392
+ // administrável, é um passo intermediário de quem está subindo o arquivo.
393
+ if (ticket.user_id !== userId) {
394
+ throw new NotFoundException(`Upload ticket not found: ${uploadId}`);
395
+ }
396
+
397
+ if (ticket.status !== 'pending') {
398
+ throw new BadRequestException(
399
+ `Upload ticket ${uploadId} is ${ticket.status} and cannot receive more content`,
400
+ );
401
+ }
402
+
403
+ if (ticket.expires_at.getTime() <= Date.now()) {
404
+ throw new BadRequestException(`Upload ticket ${uploadId} has expired`);
405
+ }
406
+
407
+ return ticket;
408
+ }
409
+
410
+ /**
411
+ * Fecha o upload e devolve o arquivo.
412
+ *
413
+ * Serve aos dois modos e é idempotente: um ticket que já gerou arquivo devolve o mesmo
414
+ * `fileId` em vez de erro, porque o retry de um `complete` cuja resposta se perdeu não
415
+ * pode render um segundo arquivo.
416
+ */
417
+ async complete(uploadId: number, userId: number) {
418
+ const ticket = await this.prismaService.file_upload_ticket.findUnique({
419
+ where: { id: uploadId },
420
+ });
421
+
422
+ if (!ticket || ticket.user_id !== userId) {
423
+ throw new NotFoundException(`Upload ticket not found: ${uploadId}`);
424
+ }
425
+
426
+ if (ticket.file_id) {
427
+ return this.fileService.get(ticket.file_id);
428
+ }
429
+
430
+ if (ticket.mode === 'signed_url') {
431
+ throw new BadRequestException(
432
+ ticket.status === 'pending'
433
+ ? `Upload ticket ${uploadId} has no content yet; PUT the file to the signed URL first`
434
+ : `Upload ticket ${uploadId} is ${ticket.status} and produced no file`,
435
+ );
436
+ }
437
+
438
+ await this.requireOwnPendingTicket(uploadId, userId);
439
+
440
+ // Reivindica antes de montar: dois `complete` simultâneos entrariam os dois no
441
+ // `uploadFromPath` e gerariam dois arquivos para o mesmo ticket.
442
+ if (!(await this.claim(uploadId))) {
443
+ const current = await this.prismaService.file_upload_ticket.findUnique({
444
+ where: { id: uploadId },
445
+ });
446
+
447
+ if (current?.file_id) {
448
+ return this.fileService.get(current.file_id);
449
+ }
450
+
451
+ throw new BadRequestException(`Upload ticket ${uploadId} is already being completed`);
452
+ }
453
+
454
+ try {
455
+ const chunks = await this.prismaService.file_upload_chunk.findMany({
456
+ where: { ticket_id: uploadId },
457
+ orderBy: { index: 'asc' },
458
+ });
459
+
460
+ if (chunks.length === 0) {
461
+ throw new BadRequestException(`Upload ticket ${uploadId} has no chunks`);
462
+ }
463
+
464
+ // Índice faltando significa parte perdida no caminho; montar assim geraria um
465
+ // arquivo silenciosamente corrompido, que é pior do que recusar.
466
+ chunks.forEach((chunk, position) => {
467
+ if (chunk.index !== position) {
468
+ throw new BadRequestException(
469
+ `Upload ticket ${uploadId} is missing chunk ${position}`,
470
+ );
471
+ }
472
+ });
473
+
474
+ const buffer = Buffer.concat(chunks.map((chunk) => Buffer.from(chunk.data)));
475
+
476
+ await this.assertContentMatchesTicket(
477
+ ticket,
478
+ FileUploadTicketService.describeUploadedBuffer(buffer),
479
+ );
480
+
481
+ const file = await this.fileService.upload(
482
+ ticket.destination,
483
+ {
484
+ fieldname: 'file',
485
+ originalname: ticket.filename,
486
+ encoding: '7bit',
487
+ mimetype: ticket.mimetype,
488
+ size: buffer.length,
489
+ destination: '',
490
+ filename: ticket.filename,
491
+ path: '',
492
+ buffer,
493
+ },
494
+ undefined,
495
+ {
496
+ isPrivate: ticket.is_private,
497
+ createdByUserId: ticket.user_id,
498
+ },
499
+ );
500
+
501
+ await this.attachFile(uploadId, file.id);
502
+ // As partes já cumpriram o papel e somam o arquivo inteiro no banco.
503
+ await this.prismaService.file_upload_chunk.deleteMany({
504
+ where: { ticket_id: uploadId },
505
+ });
506
+
507
+ return file;
508
+ } catch (error) {
509
+ await this.markFailed(uploadId);
510
+ throw error;
511
+ }
512
+ }
513
+ }
@@ -31,6 +31,7 @@ import { join } from 'path';
31
31
  import { DeleteDTO } from './dto/delete.dto';
32
32
  import { UploadFileDTO } from './dto/upload.dto';
33
33
  import { FileService } from './file.service';
34
+ import { FileUploadTicketService } from './file-upload-ticket.service';
34
35
 
35
36
  // Teto duro do multipart, avaliado enquanto o corpo ainda está chegando. É
36
37
  // diferente do setting `storage-max-size`, que só roda depois do arquivo inteiro
@@ -46,6 +47,8 @@ export class FileController {
46
47
  constructor(
47
48
  @Inject(forwardRef(() => FileService))
48
49
  private readonly fileService: FileService,
50
+ @Inject(forwardRef(() => FileUploadTicketService))
51
+ private readonly uploadTickets: FileUploadTicketService,
49
52
  ) {}
50
53
 
51
54
  private renderDownloadErrorHtml(locale: string, error: any): string {
@@ -123,6 +126,68 @@ export class FileController {
123
126
  };
124
127
  }
125
128
 
129
+ /**
130
+ * Recebe o binário de um upload aberto por `core.files.create-upload-url`.
131
+ *
132
+ * É `@Public()` porque a autorização é o próprio token: ele é assinado, vale por
133
+ * minutos, aponta para um único ticket e só serve uma vez. Existe para tirar o arquivo
134
+ * do corpo da chamada MCP — base64 de um PDF de 131 KB já passa de 175 mil caracteres,
135
+ * acima do que o modelo consegue emitir.
136
+ *
137
+ * O corpo é o binário cru, sem multipart: `express.json` não o toca porque o
138
+ * content-type não é JSON, e o stream vai direto para um arquivo temporário com
139
+ * contador de bytes, que é o que impede um corpo sem `Content-Length` de encher a
140
+ * memória do pod.
141
+ */
142
+ @Public()
143
+ @Put('upload/:token')
144
+ async uploadSigned(@Param('token') token: string, @Req() req: Request) {
145
+ const ticket = await this.uploadTickets.resolveTicketFromToken(token);
146
+
147
+ // Reivindica ANTES de gravar: dois PUTs simultâneos com o mesmo token subiriam os
148
+ // dois e deixariam um blob órfão no storage, além de dois registros para um ticket.
149
+ if (!(await this.uploadTickets.claim(ticket.id))) {
150
+ throw new BadRequestException(
151
+ `Upload token already used or expired for ticket ${ticket.id}`,
152
+ );
153
+ }
154
+
155
+ const tempPath = join(tmpdir(), `hedhog-upload-${ticket.id}-${Date.now()}`);
156
+
157
+ try {
158
+ // Uma passada só: grava, conta, hasheia e guarda o cabeçalho para o sniff.
159
+ const digest = await this.fileService.writeStreamToPath(
160
+ req as any,
161
+ tempPath,
162
+ ticket.size_bytes,
163
+ );
164
+
165
+ await this.uploadTickets.assertContentMatchesTicket(ticket, digest);
166
+
167
+ const file = await this.fileService.uploadFromPath(ticket.destination, tempPath, {
168
+ originalname: ticket.filename,
169
+ mimetype: ticket.mimetype,
170
+ size: digest.bytes,
171
+ isPrivate: ticket.is_private,
172
+ createdByUserId: ticket.user_id,
173
+ });
174
+
175
+ await this.uploadTickets.attachFile(ticket.id, file.id);
176
+
177
+ return {
178
+ uploadId: ticket.id,
179
+ fileId: file.id,
180
+ filename: file.filename,
181
+ size: file.size,
182
+ };
183
+ } catch (error) {
184
+ await this.uploadTickets.markFailed(ticket.id);
185
+ throw error;
186
+ } finally {
187
+ await rm(tempPath, { force: true }).catch(() => undefined);
188
+ }
189
+ }
190
+
126
191
  @Public()
127
192
  @Get('download/:token')
128
193
  async download(
@@ -5,7 +5,9 @@ import { JwtModule } from '@nestjs/jwt';
5
5
  import { SettingModule } from '../setting/setting.module';
6
6
  import { FileController } from './file.controller';
7
7
  import { FileService } from './file.service';
8
+ import { FileUploadTicketService } from './file-upload-ticket.service';
8
9
  import { ImageOptimizationService } from './image-optimization.service';
10
+ import { McpFileSourceService } from './mcp-file-source.service';
9
11
 
10
12
  @Module({
11
13
  imports: [
@@ -16,8 +18,18 @@ import { ImageOptimizationService } from './image-optimization.service';
16
18
  JwtModule,
17
19
  ),
18
20
  ],
19
- providers: [FileService, ImageOptimizationService],
20
- exports: [FileService, ImageOptimizationService],
21
+ providers: [
22
+ FileService,
23
+ ImageOptimizationService,
24
+ FileUploadTicketService,
25
+ McpFileSourceService,
26
+ ],
27
+ exports: [
28
+ FileService,
29
+ ImageOptimizationService,
30
+ FileUploadTicketService,
31
+ McpFileSourceService,
32
+ ],
21
33
  controllers: [FileController],
22
34
  })
23
35
  export class FileModule { }