@hed-hog/core 0.0.398 → 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 (664) 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 +30 -6
  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 +78 -4
  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 +385 -36
  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.controller.d.ts +9 -9
  356. package/dist/pairing/pairing.service.d.ts +15 -11
  357. package/dist/pairing/pairing.service.d.ts.map +1 -1
  358. package/dist/profile/dto/change-password.dto.d.ts.map +1 -1
  359. package/dist/profile/dto/change-password.dto.js +4 -6
  360. package/dist/profile/dto/change-password.dto.js.map +1 -1
  361. package/dist/profile/profile.controller.d.ts +1 -1
  362. package/dist/profile/profile.service.d.ts +1 -1
  363. package/dist/profile/profile.service.d.ts.map +1 -1
  364. package/dist/profile/profile.service.js +9 -3
  365. package/dist/profile/profile.service.js.map +1 -1
  366. package/dist/realtime/realtime-tick.coalescer.d.ts +34 -0
  367. package/dist/realtime/realtime-tick.coalescer.d.ts.map +1 -0
  368. package/dist/realtime/realtime-tick.coalescer.js +60 -0
  369. package/dist/realtime/realtime-tick.coalescer.js.map +1 -0
  370. package/dist/realtime/realtime.service.d.ts +2 -0
  371. package/dist/realtime/realtime.service.d.ts.map +1 -1
  372. package/dist/realtime/realtime.service.js +22 -2
  373. package/dist/realtime/realtime.service.js.map +1 -1
  374. package/dist/redis/redis-kv.service.d.ts +90 -0
  375. package/dist/redis/redis-kv.service.d.ts.map +1 -0
  376. package/dist/redis/redis-kv.service.js +247 -0
  377. package/dist/redis/redis-kv.service.js.map +1 -0
  378. package/dist/redis/redis-master.d.ts +29 -0
  379. package/dist/redis/redis-master.d.ts.map +1 -0
  380. package/dist/redis/redis-master.js +81 -0
  381. package/dist/redis/redis-master.js.map +1 -0
  382. package/dist/redis/redis-pubsub.d.ts +12 -0
  383. package/dist/redis/redis-pubsub.d.ts.map +1 -1
  384. package/dist/redis/redis-pubsub.js +25 -2
  385. package/dist/redis/redis-pubsub.js.map +1 -1
  386. package/dist/redis/redis.module.d.ts +11 -0
  387. package/dist/redis/redis.module.d.ts.map +1 -0
  388. package/dist/redis/redis.module.js +30 -0
  389. package/dist/redis/redis.module.js.map +1 -0
  390. package/dist/session/session.controller.d.ts +6 -2
  391. package/dist/session/session.controller.d.ts.map +1 -1
  392. package/dist/session/session.service.d.ts +118 -15
  393. package/dist/session/session.service.d.ts.map +1 -1
  394. package/dist/session/session.service.js +251 -77
  395. package/dist/session/session.service.js.map +1 -1
  396. package/dist/setting/setting.controller.d.ts +5 -0
  397. package/dist/setting/setting.controller.d.ts.map +1 -1
  398. package/dist/setting/setting.service.d.ts +7 -0
  399. package/dist/setting/setting.service.d.ts.map +1 -1
  400. package/dist/setting/setting.service.js +38 -3
  401. package/dist/setting/setting.service.js.map +1 -1
  402. package/dist/task/task.service.d.ts +17 -0
  403. package/dist/task/task.service.d.ts.map +1 -1
  404. package/dist/task/task.service.js +48 -13
  405. package/dist/task/task.service.js.map +1 -1
  406. package/dist/token/token.service.d.ts +19 -1
  407. package/dist/token/token.service.d.ts.map +1 -1
  408. package/dist/token/token.service.js +39 -2
  409. package/dist/token/token.service.js.map +1 -1
  410. package/dist/user/user-credential.util.d.ts +10 -0
  411. package/dist/user/user-credential.util.d.ts.map +1 -1
  412. package/dist/user/user-credential.util.js +14 -1
  413. package/dist/user/user-credential.util.js.map +1 -1
  414. package/dist/user/user.service.d.ts +12 -4
  415. package/dist/user/user.service.d.ts.map +1 -1
  416. package/dist/user/user.service.js +2 -11
  417. package/dist/user/user.service.js.map +1 -1
  418. package/dist/user/user.sort.d.ts +16 -0
  419. package/dist/user/user.sort.d.ts.map +1 -0
  420. package/dist/user/user.sort.js +25 -0
  421. package/dist/user/user.sort.js.map +1 -0
  422. package/dist/utils/abbreviate-name.d.ts +13 -0
  423. package/dist/utils/abbreviate-name.d.ts.map +1 -0
  424. package/dist/utils/abbreviate-name.js +42 -0
  425. package/dist/utils/abbreviate-name.js.map +1 -0
  426. package/dist/utils/date-range-query.dto.d.ts +11 -0
  427. package/dist/utils/date-range-query.dto.d.ts.map +1 -0
  428. package/dist/utils/date-range-query.dto.js +63 -0
  429. package/dist/utils/date-range-query.dto.js.map +1 -0
  430. package/dist/utils/date-range.d.ts +96 -0
  431. package/dist/utils/date-range.d.ts.map +1 -0
  432. package/dist/utils/date-range.js +172 -0
  433. package/dist/utils/date-range.js.map +1 -0
  434. package/dist/webhook-integration/webhook-utils.d.ts.map +1 -1
  435. package/dist/webhook-integration/webhook-utils.js +24 -0
  436. package/dist/webhook-integration/webhook-utils.js.map +1 -1
  437. package/dist/whatsapp-sender/whatsapp-recipients.d.ts +49 -0
  438. package/dist/whatsapp-sender/whatsapp-recipients.d.ts.map +1 -0
  439. package/dist/whatsapp-sender/whatsapp-recipients.js +66 -0
  440. package/dist/whatsapp-sender/whatsapp-recipients.js.map +1 -0
  441. package/dist/whatsapp-sender/whatsapp-sender.service.d.ts +25 -0
  442. package/dist/whatsapp-sender/whatsapp-sender.service.d.ts.map +1 -1
  443. package/dist/whatsapp-sender/whatsapp-sender.service.js +46 -5
  444. package/dist/whatsapp-sender/whatsapp-sender.service.js.map +1 -1
  445. package/hedhog/data/integration_provider.yaml +9 -0
  446. package/hedhog/data/integration_type.yaml +6 -0
  447. package/hedhog/data/locale.yaml +0 -1
  448. package/hedhog/data/mail.yaml +2 -2
  449. package/hedhog/data/mail_layout.yaml +6 -3
  450. package/hedhog/data/menu.yaml +25 -5
  451. package/hedhog/data/route.yaml +140 -0
  452. package/hedhog/data/setting_group.yaml +137 -3
  453. package/hedhog/frontend/app/access-log/page.tsx.ejs +47 -53
  454. package/hedhog/frontend/app/account/components/active-sessions.tsx.ejs +33 -8
  455. package/hedhog/frontend/app/account/components/mcp-tokens.tsx.ejs +54 -13
  456. package/hedhog/frontend/app/account/components/mfa-method-card.tsx.ejs +7 -1
  457. package/hedhog/frontend/app/account/components/recovery-codes-dialog.tsx.ejs +1 -0
  458. package/hedhog/frontend/app/account/components/tokens.tsx.ejs +47 -17
  459. package/hedhog/frontend/app/ai_agent/page.tsx.ejs +46 -5
  460. package/hedhog/frontend/app/ai_instruction/_components/ai-instruction-form.tsx.ejs +101 -30
  461. package/hedhog/frontend/app/ai_instruction/_components/ai-instruction-versions.tsx.ejs +24 -8
  462. package/hedhog/frontend/app/ai_instruction/page.tsx.ejs +80 -15
  463. package/hedhog/frontend/app/configurations/[slug]/components/image-optimization-action.tsx.ejs +166 -0
  464. package/hedhog/frontend/app/configurations/[slug]/components/setting-field.test.tsx.ejs +145 -45
  465. package/hedhog/frontend/app/configurations/[slug]/components/setting-field.tsx.ejs +99 -219
  466. package/hedhog/frontend/app/configurations/[slug]/page.tsx.ejs +19 -1
  467. package/hedhog/frontend/app/configurations/layout.tsx.ejs +19 -5
  468. package/hedhog/frontend/app/dashboard/[slug]/widget-renderer.tsx.ejs +2 -8
  469. package/hedhog/frontend/app/dashboard/components/dynamic-widget.tsx.ejs +3 -0
  470. package/hedhog/frontend/app/dashboard/components/widget-wrapper.tsx.ejs +4 -0
  471. package/hedhog/frontend/app/dashboard/dashboard-home-tabs.tsx.ejs +43 -44
  472. package/hedhog/frontend/app/dashboard/management/tabs/component-roles-tab.tsx.ejs +41 -3
  473. package/hedhog/frontend/app/dashboard/management/tabs/components-tab.tsx.ejs +42 -2
  474. package/hedhog/frontend/app/dashboard/management/tabs/dashboard-roles-tab.tsx.ejs +41 -3
  475. package/hedhog/frontend/app/dashboard/management/tabs/dashboards-tab.tsx.ejs +39 -4
  476. package/hedhog/frontend/app/dashboard/management/tabs/items-tab.tsx.ejs +42 -3
  477. package/hedhog/frontend/app/incidents/page.tsx.ejs +60 -31
  478. package/hedhog/frontend/app/integration/profiles/page.tsx.ejs +45 -5
  479. package/hedhog/frontend/app/integrations-webhooks/page.tsx.ejs +92 -15
  480. package/hedhog/frontend/app/mail/log/page.tsx.ejs +109 -61
  481. package/hedhog/frontend/app/mail/template/page.tsx.ejs +125 -23
  482. package/hedhog/frontend/app/mcp_chat/chat-components.tsx.ejs +13 -15
  483. package/hedhog/frontend/app/mcp_chat/page.tsx.ejs +116 -110
  484. package/hedhog/frontend/app/message-templates/_components/message-template-sheet.tsx.ejs +245 -0
  485. package/hedhog/frontend/app/message-templates/_lib/types.ts.ejs +24 -0
  486. package/hedhog/frontend/app/message-templates/page.tsx.ejs +182 -0
  487. package/hedhog/frontend/app/pages/_components/page-wizard-sheet.tsx.ejs +1 -0
  488. package/hedhog/frontend/app/pages/page.tsx.ejs +94 -9
  489. package/hedhog/frontend/app/roles/menus.tsx.ejs +4 -4
  490. package/hedhog/frontend/app/roles/routes.tsx.ejs +4 -4
  491. package/hedhog/frontend/app/roles/users.tsx.ejs +4 -4
  492. package/hedhog/frontend/app/setting-list/page.tsx.ejs +71 -9
  493. package/hedhog/frontend/app/users/page.tsx.ejs +77 -67
  494. package/hedhog/frontend/messages/en.json +183 -36
  495. package/hedhog/frontend/messages/pt.json +183 -36
  496. package/hedhog/table/cron_lock.yaml +17 -0
  497. package/hedhog/table/file.yaml +13 -1
  498. package/hedhog/table/file_upload_chunk.yaml +23 -0
  499. package/hedhog/table/file_upload_ticket.yaml +67 -0
  500. package/hedhog/table/mcp_tool_call_log.yaml +30 -22
  501. package/hedhog/table/message_template.yaml +33 -0
  502. package/hedhog/table/setting.yaml +8 -0
  503. package/hedhog/table/user_session.yaml +36 -1
  504. package/package.json +8 -6
  505. package/src/ai/ai-agent.sort.ts +21 -0
  506. package/src/ai/ai.service.spec.ts +173 -1
  507. package/src/ai/ai.service.ts +64 -193
  508. package/src/ai-instruction/ai-instruction.service.ts +32 -28
  509. package/src/ai-instruction/ai-instruction.sort.ts +32 -0
  510. package/src/auth/auth.module.ts +8 -1
  511. package/src/auth/auth.service.spec.ts +108 -1
  512. package/src/auth/auth.service.ts +59 -5
  513. package/src/auth/guards/auth.guard.ts +9 -1
  514. package/src/authorize/authorize.controller.ts +126 -11
  515. package/src/authorize/authorize.errors.ts +55 -0
  516. package/src/authorize/authorize.module.ts +6 -1
  517. package/src/authorize/authorize.service.spec.ts +379 -7
  518. package/src/authorize/authorize.service.ts +309 -23
  519. package/src/authorize/dto/authorize-info.dto.ts +21 -3
  520. package/src/authorize/dto/consent.dto.ts +21 -3
  521. package/src/authorize/dto/token.dto.ts +24 -2
  522. package/src/authorize/oauth-exception.filter.ts +58 -0
  523. package/src/authorize/oauth-metadata.service.ts +67 -0
  524. package/src/authorize/well-known.controller.spec.ts +84 -0
  525. package/src/authorize/well-known.controller.ts +96 -0
  526. package/src/captcha/captcha.service.spec.ts +211 -4
  527. package/src/captcha/captcha.service.ts +127 -10
  528. package/src/core.module.ts +6 -0
  529. package/src/dashboard/dashboard-component-role/dashboard-component-role.service.ts +2 -3
  530. package/src/dashboard/dashboard-component-role/dashboard-component-role.sort.ts +18 -0
  531. package/src/dashboard/dashboard-item/dashboard-item.service.ts +2 -3
  532. package/src/dashboard/dashboard-item/dashboard-item.sort.ts +19 -0
  533. package/src/dashboard/dashboard-role/dashboard-role.service.ts +2 -3
  534. package/src/dashboard/dashboard-role/dashboard-role.sort.ts +16 -0
  535. package/src/file/file-upload-ticket.service.spec.ts +422 -0
  536. package/src/file/file-upload-ticket.service.ts +513 -0
  537. package/src/file/file.controller.ts +65 -0
  538. package/src/file/file.module.ts +14 -2
  539. package/src/file/file.service.spec.ts +94 -0
  540. package/src/file/file.service.ts +432 -30
  541. package/src/file/filename-encoding.util.spec.ts +54 -0
  542. package/src/file/filename-encoding.util.ts +67 -0
  543. package/src/file/image-optimization.service.spec.ts +156 -19
  544. package/src/file/image-optimization.service.ts +106 -21
  545. package/src/file/mcp-file-source.schema.ts +83 -0
  546. package/src/file/mcp-file-source.service.spec.ts +473 -0
  547. package/src/file/mcp-file-source.service.ts +445 -0
  548. package/src/file/mimetype-sniff.util.spec.ts +126 -0
  549. package/src/file/mimetype-sniff.util.ts +265 -0
  550. package/src/file/remote-fetch.util.spec.ts +117 -0
  551. package/src/file/remote-fetch.util.ts +330 -0
  552. package/src/impersonation/dto/start-impersonation.dto.ts +5 -2
  553. package/src/impersonation/impersonation.service.spec.ts +24 -1
  554. package/src/impersonation/impersonation.service.ts +14 -4
  555. package/src/incident/incident.controller.ts +9 -1
  556. package/src/incident/incident.service.ts +7 -0
  557. package/src/index.ts +17 -0
  558. package/src/integration-profile/integration-profile.secrets.ts +7 -0
  559. package/src/integration-profile/integration-profile.service.ts +7 -64
  560. package/src/integration-profile/integration-profile.utils.spec.ts +9 -0
  561. package/src/integration-profile/integration-profile.utils.ts +5 -5
  562. package/src/integration-profile/testers/index.ts +2 -0
  563. package/src/integration-profile/testers/remaining.testers.spec.ts +79 -0
  564. package/src/integration-profile/testers/shipping.testers.ts +94 -0
  565. package/src/mail/dto/send.dto.ts +6 -1
  566. package/src/mail/mail-template.spec.ts +58 -1
  567. package/src/mail/mail.service.spec.ts +112 -0
  568. package/src/mail/mail.service.ts +42 -4
  569. package/src/mail-sent/mail-sent.service.ts +3 -0
  570. package/src/mail-sent/mail-sent.sort.ts +19 -0
  571. package/src/mcp/filters/mcp-challenge.filter.spec.ts +76 -0
  572. package/src/mcp/filters/mcp-challenge.filter.ts +70 -0
  573. package/src/mcp/guards/mcp-auth.guard.spec.ts +51 -2
  574. package/src/mcp/guards/mcp-auth.guard.ts +24 -1
  575. package/src/mcp/guards/mcp-permission.guard.spec.ts +109 -15
  576. package/src/mcp/guards/mcp-permission.guard.ts +76 -51
  577. package/src/mcp/mcp-audit.service.spec.ts +107 -0
  578. package/src/mcp/mcp-audit.service.ts +37 -1
  579. package/src/mcp/mcp-permission.service.spec.ts +197 -0
  580. package/src/mcp/mcp-permission.service.ts +184 -0
  581. package/src/mcp/mcp-server.service.spec.ts +84 -2
  582. package/src/mcp/mcp-server.service.ts +111 -87
  583. package/src/mcp/mcp.controller.ts +8 -1
  584. package/src/mcp/mcp.module.ts +5 -1
  585. package/src/mcp/tools/core-ai.mcp-tools.ts +1 -1
  586. package/src/mcp/tools/core-dashboard-items.mcp-tools.ts +1 -1
  587. package/src/mcp/tools/core-dashboard.mcp-tools.ts +1 -1
  588. package/src/mcp/tools/core-event-webhooks.mcp-tools.ts +1 -2
  589. package/src/mcp/tools/core-files.mcp-tools.ts +202 -22
  590. package/src/mcp/tools/core-integration-events.mcp-tools.ts +1 -1
  591. package/src/mcp/tools/core-mail-sent.mcp-tools.ts +1 -1
  592. package/src/mcp/tools/core-mail.mcp-tools.ts +1 -1
  593. package/src/mcp/tools/core-menus.mcp-tools.ts +1 -2
  594. package/src/mcp/tools/core-notifications.mcp-tools.ts +0 -1
  595. package/src/mcp/tools/core-roles.mcp-tools.ts +1 -5
  596. package/src/mcp/tools/core-routes.mcp-tools.ts +1 -3
  597. package/src/mcp/tools/core-screens.mcp-tools.ts +1 -3
  598. package/src/mcp/tools/core-sessions.mcp-tools.ts +0 -2
  599. package/src/mcp/tools/core-settings.mcp-tools.ts +1 -2
  600. package/src/mcp/tools/core-users.mcp-tools.ts +1 -1
  601. package/src/mcp/tools/core-webhooks.mcp-tools.ts +1 -2
  602. package/src/mcp/types/mcp-context.type.ts +15 -6
  603. package/src/mcp-chat/mcp-chat.service.ts +8 -0
  604. package/src/meeting/meeting-provider.registry.ts +121 -0
  605. package/src/meeting/meeting.constants.ts +74 -0
  606. package/src/menu/menu.service.spec.ts +89 -0
  607. package/src/menu/menu.service.ts +29 -11
  608. package/src/message-template/dto/update-message-template.dto.ts +22 -0
  609. package/src/message-template/message-template-admin.service.spec.ts +163 -0
  610. package/src/message-template/message-template-admin.service.ts +239 -0
  611. package/src/message-template/message-template.controller.ts +52 -0
  612. package/src/message-template/message-template.module.ts +21 -0
  613. package/src/message-template/message-template.registry.spec.ts +62 -0
  614. package/src/message-template/message-template.registry.ts +125 -0
  615. package/src/message-template/message-template.service.spec.ts +149 -0
  616. package/src/message-template/message-template.service.ts +149 -0
  617. package/src/notification/notification.constants.ts +10 -0
  618. package/src/notification/notification.module.ts +3 -0
  619. package/src/notification/notification.service.spec.ts +75 -1
  620. package/src/notification/notification.service.ts +39 -1
  621. package/src/oauth/oauth.controller.ts +0 -1
  622. package/src/oauth/oauth.errors.ts +7 -0
  623. package/src/oauth/oauth.module.ts +6 -1
  624. package/src/oauth/oauth.service.spec.ts +58 -7
  625. package/src/oauth/oauth.service.ts +71 -32
  626. package/src/oauth/providers/abstract.provider.spec.ts +192 -0
  627. package/src/oauth/providers/abstract.provider.ts +46 -14
  628. package/src/oauth/providers/github.provider.ts +57 -34
  629. package/src/oauth/providers/microsoft-entra-id.provider.ts +8 -1
  630. package/src/observability/monitored-cron.spec.ts +164 -31
  631. package/src/observability/monitored-cron.ts +154 -62
  632. package/src/profile/dto/change-password.dto.ts +25 -7
  633. package/src/profile/profile.service.spec.ts +97 -0
  634. package/src/profile/profile.service.ts +9 -3
  635. package/src/realtime/realtime-tick.coalescer.spec.ts +92 -0
  636. package/src/realtime/realtime-tick.coalescer.ts +60 -0
  637. package/src/realtime/realtime.service.spec.ts +33 -0
  638. package/src/realtime/realtime.service.ts +28 -2
  639. package/src/redis/redis-kv.service.ts +261 -0
  640. package/src/redis/redis-master.spec.ts +111 -0
  641. package/src/redis/redis-master.ts +86 -0
  642. package/src/redis/redis-pubsub.ts +27 -3
  643. package/src/redis/redis.module.ts +17 -0
  644. package/src/session/session.service.spec.ts +121 -42
  645. package/src/session/session.service.ts +279 -82
  646. package/src/setting/setting.service.ts +44 -3
  647. package/src/task/task.service.spec.ts +41 -0
  648. package/src/task/task.service.ts +53 -13
  649. package/src/token/token.service.spec.ts +90 -0
  650. package/src/token/token.service.ts +48 -2
  651. package/src/user/user-credential.util.ts +14 -5
  652. package/src/user/user.service.ts +2 -12
  653. package/src/user/user.sort.ts +25 -0
  654. package/src/utils/abbreviate-name.spec.ts +50 -0
  655. package/src/utils/abbreviate-name.ts +44 -0
  656. package/src/utils/date-range-query.dto.ts +56 -0
  657. package/src/utils/date-range.spec.ts +175 -0
  658. package/src/utils/date-range.ts +246 -0
  659. package/src/webhook-integration/webhook-utils.spec.ts +67 -0
  660. package/src/webhook-integration/webhook-utils.ts +26 -0
  661. package/src/whatsapp-sender/whatsapp-recipients.spec.ts +89 -0
  662. package/src/whatsapp-sender/whatsapp-recipients.ts +83 -0
  663. package/src/whatsapp-sender/whatsapp-sender.service.spec.ts +112 -0
  664. package/src/whatsapp-sender/whatsapp-sender.service.ts +58 -5
@@ -0,0 +1,163 @@
1
+ import { BadRequestException, NotFoundException } from '@nestjs/common';
2
+
3
+ import { MessageTemplateAdminService } from './message-template-admin.service';
4
+ import {
5
+ clearMessageTemplateRegistry,
6
+ registerMessageTemplates,
7
+ } from './message-template.registry';
8
+
9
+ /**
10
+ * O CRUD da tela, que no SAC não tinha cobertura nenhuma.
11
+ *
12
+ * O que estes testes protegem é o desenho: a listagem vem do REGISTRY e o banco
13
+ * entra por cima. Um modelo recém-declarado por uma library precisa aparecer
14
+ * antes de existir linha no banco — senão volta a dor dos prompts de IA, em que
15
+ * prompt sem seed simplesmente não aparece.
16
+ */
17
+ describe('MessageTemplateAdminService', () => {
18
+ let prisma: any;
19
+ let service: MessageTemplateAdminService;
20
+
21
+ const SLUG = 'demo.aviso';
22
+
23
+ beforeEach(() => {
24
+ clearMessageTemplateRegistry();
25
+ registerMessageTemplates([
26
+ {
27
+ slug: SLUG,
28
+ moduleSlug: 'demo',
29
+ name: { pt: 'Aviso' },
30
+ description: { pt: 'Sai quando algo acontece.' },
31
+ fallback: { pt: 'Padrão {{protocol}}', en: 'Default {{protocol}}' },
32
+ variables: { protocol: { sample: '202609-000045' } },
33
+ },
34
+ {
35
+ slug: 'outro.aviso',
36
+ moduleSlug: 'outro',
37
+ name: { pt: 'Outro' },
38
+ fallback: { pt: 'Outro padrão' },
39
+ variables: {},
40
+ },
41
+ ]);
42
+
43
+ prisma = {
44
+ message_template: {
45
+ findMany: jest.fn().mockResolvedValue([]),
46
+ findUnique: jest.fn().mockResolvedValue(null),
47
+ upsert: jest.fn().mockResolvedValue({ id: 7, slug: SLUG }),
48
+ delete: jest.fn().mockResolvedValue({}),
49
+ },
50
+ message_template_locale: { upsert: jest.fn().mockResolvedValue({}) },
51
+ locale: { findFirst: jest.fn().mockResolvedValue({ id: 1 }) },
52
+ };
53
+
54
+ service = new MessageTemplateAdminService(prisma);
55
+ });
56
+
57
+ describe('list', () => {
58
+ it('mostra o modelo antes de existir linha no banco', async () => {
59
+ const { data } = await service.list();
60
+
61
+ expect(data).toHaveLength(2);
62
+ const item = data.find((d) => d.slug === SLUG)!;
63
+ expect(item.customized).toBe(false);
64
+ expect(item.is_active).toBe(true);
65
+ expect(item.body.pt).toBe('Padrão {{protocol}}');
66
+ });
67
+
68
+ it('o texto editado vence o padrão, por idioma', async () => {
69
+ prisma.message_template.findMany.mockResolvedValue([
70
+ {
71
+ slug: SLUG,
72
+ is_active: true,
73
+ message_template_locale: [
74
+ { body: 'Editado {{protocol}}', locale: { code: 'pt' } },
75
+ ],
76
+ },
77
+ ]);
78
+
79
+ const { data } = await service.list();
80
+ const item = data.find((d) => d.slug === SLUG)!;
81
+
82
+ expect(item.customized).toBe(true);
83
+ expect(item.body.pt).toBe('Editado {{protocol}}');
84
+ // O inglês não foi editado: segue o padrão do código.
85
+ expect(item.body.en).toBe('Default {{protocol}}');
86
+ // E o padrão continua exposto, para a tela poder restaurar.
87
+ expect(item.fallback.pt).toBe('Padrão {{protocol}}');
88
+ });
89
+
90
+ it('filtra por módulo, para o agrupamento da tela', async () => {
91
+ const { data } = await service.list('outro');
92
+ expect(data.map((d) => d.slug)).toEqual(['outro.aviso']);
93
+ });
94
+ });
95
+
96
+ describe('update', () => {
97
+ it('cria a linha na primeira edição', async () => {
98
+ await service.update(SLUG, { locale: { pt: { body: 'Novo {{protocol}}' } } });
99
+
100
+ expect(prisma.message_template.upsert).toHaveBeenCalledWith(
101
+ expect.objectContaining({ where: { slug: SLUG } }),
102
+ );
103
+ expect(prisma.message_template_locale.upsert).toHaveBeenCalled();
104
+ });
105
+
106
+ it('recusa corpo com sintaxe quebrada antes de gravar', async () => {
107
+ // Aceitar deixaria a tela dizendo "salvo" enquanto o aviso sai com o texto
108
+ // padrão, sem explicação nenhuma.
109
+ await expect(
110
+ service.update(SLUG, { locale: { pt: { body: '{{#if x}}sem fechar' } } }),
111
+ ).rejects.toThrow(BadRequestException);
112
+
113
+ expect(prisma.message_template.upsert).not.toHaveBeenCalled();
114
+ });
115
+
116
+ it('não mexe em is_active quando o corpo não o menciona', async () => {
117
+ await service.update(SLUG, { locale: { pt: { body: 'ok' } } });
118
+
119
+ expect(prisma.message_template.upsert).toHaveBeenCalledWith(
120
+ expect.objectContaining({ update: {} }),
121
+ );
122
+ });
123
+
124
+ it('recusa slug que nenhuma library registrou', async () => {
125
+ await expect(service.update('demo.fantasma', {})).rejects.toThrow(
126
+ NotFoundException,
127
+ );
128
+ });
129
+ });
130
+
131
+ describe('restore', () => {
132
+ it('apaga a linha em vez de copiar o padrão para dentro dela', async () => {
133
+ // Copiar congelaria o texto na versão de hoje, e a próxima melhoria que
134
+ // viesse por deploy não chegaria a quem restaurou.
135
+ await service.restore(SLUG);
136
+
137
+ expect(prisma.message_template.delete).toHaveBeenCalledWith({
138
+ where: { slug: SLUG },
139
+ });
140
+ });
141
+
142
+ it('restaurar um modelo que nunca foi editado não é erro', async () => {
143
+ prisma.message_template.delete.mockRejectedValue(new Error('não existe'));
144
+ await expect(service.restore(SLUG)).resolves.toBeDefined();
145
+ });
146
+ });
147
+
148
+ describe('preview', () => {
149
+ it('renderiza com as amostras declaradas pelo registry', () => {
150
+ expect(service.preview(SLUG, 'Chamado {{protocol}}')).toEqual({
151
+ text: 'Chamado 202609-000045',
152
+ });
153
+ });
154
+
155
+ it('recusa sintaxe quebrada', () => {
156
+ expect(() => service.preview(SLUG, '{{#if x}}')).toThrow(BadRequestException);
157
+ });
158
+ });
159
+
160
+ it('modules lista os módulos que declararam algum modelo', () => {
161
+ expect(service.modules()).toEqual({ data: ['demo', 'outro'] });
162
+ });
163
+ });
@@ -0,0 +1,239 @@
1
+ import { PrismaService } from '@hed-hog/api-prisma';
2
+ import {
3
+ BadRequestException,
4
+ Inject,
5
+ Injectable,
6
+ NotFoundException,
7
+ forwardRef,
8
+ } from '@nestjs/common';
9
+ import * as Handlebars from 'handlebars';
10
+
11
+ import { UpdateMessageTemplateDTO } from './dto/update-message-template.dto';
12
+ import {
13
+ DEFAULT_MESSAGE_LOCALE,
14
+ MessageTemplateService,
15
+ } from './message-template.service';
16
+ import {
17
+ MessageTemplateDefinition,
18
+ getMessageTemplateDefinition,
19
+ listMessageTemplateDefinitions,
20
+ listMessageTemplateModules,
21
+ } from './message-template.registry';
22
+
23
+ /** Uma linha da tela: o que o código declara, com o que o banco sobrescreveu. */
24
+ export type MessageTemplateListItem = {
25
+ slug: string;
26
+ module: string;
27
+ name: Record<string, string>;
28
+ description: Record<string, string>;
29
+ /** O texto em vigor por locale — o editado quando existe, senão o padrão. */
30
+ body: Record<string, string>;
31
+ /** O texto padrão, para a tela poder mostrar o diff e restaurar. */
32
+ fallback: Record<string, string>;
33
+ variables: MessageTemplateDefinition['variables'];
34
+ is_active: boolean;
35
+ /** Há linha no banco? É o que acende o selo e habilita "restaurar padrão". */
36
+ customized: boolean;
37
+ };
38
+
39
+ /**
40
+ * O que a tela de Modelos de Mensagem faz.
41
+ *
42
+ * A listagem é o **registry**, não um `SELECT`: modelo declarado por uma library
43
+ * recém-instalada já aparece, sem migration nenhuma. O banco entra por cima,
44
+ * como override — é daí que vêm `is_active`, o corpo editado e o selo
45
+ * "personalizado".
46
+ *
47
+ * Não expõe create nem delete de modelo: cada um existe porque há código que o
48
+ * procura pelo slug. Criar pela tela geraria registro que nada lê; apagar
49
+ * derrubaria o texto sem ninguém entender por quê. O que a tela faz é editar o
50
+ * texto, ligar/desligar e restaurar o padrão.
51
+ */
52
+ @Injectable()
53
+ export class MessageTemplateAdminService {
54
+ constructor(
55
+ @Inject(forwardRef(() => PrismaService))
56
+ private readonly prisma: PrismaService,
57
+ ) {}
58
+
59
+ /** Os módulos que têm modelo registrado, para o agrupamento da tela. */
60
+ modules() {
61
+ return { data: listMessageTemplateModules() };
62
+ }
63
+
64
+ async list(moduleSlug?: string) {
65
+ const definitions = listMessageTemplateDefinitions(moduleSlug);
66
+
67
+ // Uma consulta para a lista inteira, e não uma por modelo: são poucas linhas
68
+ // e a tela pede todas de uma vez.
69
+ const rows = await (this.prisma as any).message_template.findMany({
70
+ where: { slug: { in: definitions.map((d) => d.slug) } },
71
+ include: {
72
+ message_template_locale: {
73
+ select: { body: true, locale: { select: { code: true } } },
74
+ },
75
+ },
76
+ });
77
+
78
+ const bySlug = new Map(rows.map((row: any) => [row.slug, row]));
79
+ const data = definitions.map((definition) =>
80
+ MessageTemplateAdminService.merge(definition, bySlug.get(definition.slug)),
81
+ );
82
+
83
+ return { data, total: data.length };
84
+ }
85
+
86
+ async get(slug: string): Promise<MessageTemplateListItem> {
87
+ const definition = getMessageTemplateDefinition(slug);
88
+
89
+ if (!definition) {
90
+ throw new NotFoundException(`Modelo de mensagem "${slug}" não encontrado.`);
91
+ }
92
+
93
+ const row = await (this.prisma as any).message_template.findUnique({
94
+ where: { slug },
95
+ include: {
96
+ message_template_locale: {
97
+ select: { body: true, locale: { select: { code: true } } },
98
+ },
99
+ },
100
+ });
101
+
102
+ return MessageTemplateAdminService.merge(definition, row);
103
+ }
104
+
105
+ /**
106
+ * Grava o texto editado. **Upsert**, porque a linha pode não existir ainda:
107
+ * ela nasce na primeira edição, e não no seed.
108
+ */
109
+ async update(slug: string, dto: UpdateMessageTemplateDTO) {
110
+ const definition = getMessageTemplateDefinition(slug);
111
+
112
+ if (!definition) {
113
+ throw new NotFoundException(`Modelo de mensagem "${slug}" não encontrado.`);
114
+ }
115
+
116
+ // Valida ANTES de gravar: aceitar um corpo que não compila deixaria a tela
117
+ // dizendo "salvo" enquanto o aviso sai com o texto padrão, sem explicação.
118
+ for (const [locale, body] of Object.entries(dto.locale ?? {})) {
119
+ if (body?.body != null) {
120
+ MessageTemplateAdminService.assertCompiles(locale, body.body);
121
+ }
122
+ }
123
+
124
+ const template = await (this.prisma as any).message_template.upsert({
125
+ where: { slug },
126
+ create: { slug, is_active: dto.is_active ?? true },
127
+ update: dto.is_active == null ? {} : { is_active: dto.is_active },
128
+ });
129
+
130
+ for (const [code, value] of Object.entries(dto.locale ?? {})) {
131
+ if (value?.body == null) continue;
132
+
133
+ const locale = await (this.prisma as any).locale.findFirst({
134
+ where: { code },
135
+ select: { id: true },
136
+ });
137
+
138
+ if (!locale) continue;
139
+
140
+ await (this.prisma as any).message_template_locale.upsert({
141
+ where: {
142
+ message_template_id_locale_id: {
143
+ message_template_id: template.id,
144
+ locale_id: locale.id,
145
+ },
146
+ },
147
+ create: {
148
+ message_template_id: template.id,
149
+ locale_id: locale.id,
150
+ body: value.body,
151
+ },
152
+ update: { body: value.body },
153
+ });
154
+ }
155
+
156
+ return this.get(slug);
157
+ }
158
+
159
+ /**
160
+ * Volta ao texto do código, apagando a linha.
161
+ *
162
+ * Apagar, e não copiar o padrão para dentro do banco: uma cópia congelaria o
163
+ * texto na versão de hoje, e a próxima melhoria que viesse por deploy não
164
+ * chegaria a quem restaurou.
165
+ */
166
+ async restore(slug: string) {
167
+ if (!getMessageTemplateDefinition(slug)) {
168
+ throw new NotFoundException(`Modelo de mensagem "${slug}" não encontrado.`);
169
+ }
170
+
171
+ await (this.prisma as any).message_template
172
+ .delete({ where: { slug } })
173
+ .catch(() => null);
174
+
175
+ return this.get(slug);
176
+ }
177
+
178
+ /**
179
+ * Renderiza um corpo qualquer com as amostras do modelo, sem tocar no banco.
180
+ *
181
+ * É a única forma de ver onde o texto quebra no balão antes de ele chegar ao
182
+ * grupo.
183
+ */
184
+ preview(slug: string, body: string) {
185
+ const definition = getMessageTemplateDefinition(slug);
186
+
187
+ if (!definition) {
188
+ throw new NotFoundException(`Modelo de mensagem "${slug}" não encontrado.`);
189
+ }
190
+
191
+ MessageTemplateAdminService.assertCompiles(DEFAULT_MESSAGE_LOCALE, body);
192
+
193
+ const samples = Object.fromEntries(
194
+ Object.entries(definition.variables).map(([key, spec]) => [key, spec.sample]),
195
+ );
196
+
197
+ return {
198
+ text: Handlebars.compile(body, { noEscape: true })(samples).trim(),
199
+ };
200
+ }
201
+
202
+ private static assertCompiles(locale: string, body: string) {
203
+ try {
204
+ Handlebars.compile(body, { noEscape: true })({});
205
+ } catch (error) {
206
+ throw new BadRequestException(
207
+ `O corpo em "${locale}" tem sintaxe inválida: ${
208
+ (error as Error)?.message ?? 'erro desconhecido'
209
+ }`,
210
+ );
211
+ }
212
+ }
213
+
214
+ /** Junta a declaração do código com o que o banco sobrescreveu. */
215
+ private static merge(
216
+ definition: MessageTemplateDefinition,
217
+ row: any,
218
+ ): MessageTemplateListItem {
219
+ const edited: Record<string, string> = {};
220
+
221
+ for (const locale of row?.message_template_locale ?? []) {
222
+ const code = locale.locale?.code;
223
+ const body = String(locale.body ?? '').trim();
224
+ if (code && body) edited[code] = locale.body;
225
+ }
226
+
227
+ return {
228
+ slug: definition.slug,
229
+ module: definition.moduleSlug,
230
+ name: definition.name,
231
+ description: definition.description ?? {},
232
+ body: { ...definition.fallback, ...edited },
233
+ fallback: definition.fallback,
234
+ variables: definition.variables,
235
+ is_active: row?.is_active ?? true,
236
+ customized: Boolean(row),
237
+ };
238
+ }
239
+ }
@@ -0,0 +1,52 @@
1
+ import { Role } from '@hed-hog/api';
2
+ import { Body, Controller, Get, Param, Patch, Post, Query } from '@nestjs/common';
3
+
4
+ import { MessageTemplateAdminService } from './message-template-admin.service';
5
+ import { UpdateMessageTemplateDTO } from './dto/update-message-template.dto';
6
+
7
+ /**
8
+ * Modelos de mensagem, endereçados por SLUG e não por id.
9
+ *
10
+ * O id seria o identificador errado aqui: a linha do banco só existe depois da
11
+ * primeira edição, então um modelo ainda no padrão não teria id nenhum para a
12
+ * tela usar. O slug existe desde que a library o registra.
13
+ */
14
+ @Role()
15
+ @Controller('message-templates')
16
+ export class MessageTemplateController {
17
+ constructor(private readonly templates: MessageTemplateAdminService) {}
18
+
19
+ @Get()
20
+ async list(@Query('module') module?: string) {
21
+ return this.templates.list(module?.trim() || undefined);
22
+ }
23
+
24
+ // Antes de :slug — o Nest resolve rotas na ordem em que estão declaradas.
25
+ @Get('modules')
26
+ async modules() {
27
+ return this.templates.modules();
28
+ }
29
+
30
+ @Post(':slug/preview')
31
+ async preview(@Param('slug') slug: string, @Body() body: { body: string }) {
32
+ return this.templates.preview(slug, body?.body ?? '');
33
+ }
34
+
35
+ @Post(':slug/restore')
36
+ async restore(@Param('slug') slug: string) {
37
+ return this.templates.restore(slug);
38
+ }
39
+
40
+ @Get(':slug')
41
+ async get(@Param('slug') slug: string) {
42
+ return this.templates.get(slug);
43
+ }
44
+
45
+ @Patch(':slug')
46
+ async update(
47
+ @Param('slug') slug: string,
48
+ @Body() data: UpdateMessageTemplateDTO,
49
+ ) {
50
+ return this.templates.update(slug, data);
51
+ }
52
+ }
@@ -0,0 +1,21 @@
1
+ import { PrismaModule } from '@hed-hog/api-prisma';
2
+ import { Module, forwardRef } from '@nestjs/common';
3
+
4
+ import { MessageTemplateAdminService } from './message-template-admin.service';
5
+ import { MessageTemplateController } from './message-template.controller';
6
+ import { MessageTemplateService } from './message-template.service';
7
+
8
+ /**
9
+ * Modelos de mensagem para canal que não é e-mail.
10
+ *
11
+ * Exporta o `MessageTemplateService` porque quem renderiza são as libraries: o
12
+ * SAC para o aviso de chamado, o commerce para o de venda. O serviço da tela
13
+ * fica dentro, que ninguém fora daqui edita template por código.
14
+ */
15
+ @Module({
16
+ imports: [forwardRef(() => PrismaModule)],
17
+ controllers: [MessageTemplateController],
18
+ providers: [MessageTemplateService, MessageTemplateAdminService],
19
+ exports: [MessageTemplateService],
20
+ })
21
+ export class MessageTemplateModule {}
@@ -0,0 +1,62 @@
1
+ import {
2
+ clearMessageTemplateRegistry,
3
+ listMessageTemplateDefinitions,
4
+ registerMessageTemplates,
5
+ } from './message-template.registry';
6
+
7
+ /** Uma definição válida; cada teste sobrescreve só o que lhe interessa. */
8
+ const definicao = (overrides: Record<string, unknown> = {}) => ({
9
+ slug: 'demo.aviso',
10
+ moduleSlug: 'demo',
11
+ name: { pt: 'Aviso' },
12
+ fallback: { pt: 'Olá {{nome}}' },
13
+ variables: { nome: { sample: 'Fulano' } },
14
+ ...overrides,
15
+ });
16
+
17
+ describe('registerMessageTemplates', () => {
18
+ beforeEach(() => clearMessageTemplateRegistry());
19
+
20
+ it('aceita uma definição bem formada', () => {
21
+ registerMessageTemplates([definicao() as any]);
22
+ expect(listMessageTemplateDefinitions('demo')).toHaveLength(1);
23
+ });
24
+
25
+ it('recusa slug fora da gramática <module>.<nome>', () => {
26
+ // Sem a gramática, duas libraries brigariam por um slug curto como "paid" e
27
+ // a tela não teria como dizer de quem é o modelo.
28
+ expect(() =>
29
+ registerMessageTemplates([definicao({ slug: 'aviso' }) as any]),
30
+ ).toThrow(/inválido/);
31
+ });
32
+
33
+ it('recusa moduleSlug que não bate com o slug', () => {
34
+ expect(() =>
35
+ registerMessageTemplates([
36
+ definicao({ slug: 'sac.aviso', moduleSlug: 'commerce' }) as any,
37
+ ]),
38
+ ).toThrow(/moduleSlug/);
39
+ });
40
+
41
+ it('recusa modelo sem texto padrão em português', () => {
42
+ // Sem o padrão, uma linha quebrada no banco deixaria o aviso mudo.
43
+ expect(() =>
44
+ registerMessageTemplates([definicao({ fallback: { en: 'Hi' } }) as any]),
45
+ ).toThrow(/texto padrão/);
46
+ });
47
+
48
+ it('recusa slug duplicado em vez de deixar uma library sobrescrever a outra', () => {
49
+ registerMessageTemplates([definicao() as any]);
50
+ expect(() =>
51
+ registerMessageTemplates([definicao({ name: { pt: 'Outro' } }) as any]),
52
+ ).toThrow(/já está registrado/);
53
+ });
54
+
55
+ it('registrar a mesma definição duas vezes é inofensivo', () => {
56
+ // Acontece de verdade: o arquivo de templates é importado por mais de um
57
+ // módulo, e o Jest reavalia o módulo entre suites.
58
+ const mesma = definicao() as any;
59
+ registerMessageTemplates([mesma]);
60
+ expect(() => registerMessageTemplates([mesma])).not.toThrow();
61
+ });
62
+ });
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Declaração de um modelo de mensagem cujo texto canônico vive em código.
3
+ *
4
+ * O registry é o que faz da tabela `message_template` um **override** em vez da
5
+ * única cópia: o render cai no `fallback` sempre que a linha do banco falta,
6
+ * está desligada, vazia ou com sintaxe quebrada; a tela oferece "restaurar
7
+ * padrão"; e uma library recém-instalada já aparece na tela sem migration
8
+ * nenhuma — a listagem é o registry, não um `SELECT`.
9
+ *
10
+ * Esse último ponto é a diferença deliberada em relação aos prompts de IA, que
11
+ * seguem o mesmo desenho mas listam do banco: lá, prompt registrado sem seed
12
+ * funciona e não aparece na tela, e é preciso uma migration por conjunto.
13
+ */
14
+ export type MessageTemplateVariable = {
15
+ /** Explica o que a variável carrega. Aparece no editor, ao lado do botão. */
16
+ description?: string;
17
+ /**
18
+ * Valor de exemplo, usado no preview.
19
+ *
20
+ * É obrigatório porque o preview é a única forma de ver onde o texto quebra no
21
+ * balão do WhatsApp antes de ele chegar ao grupo.
22
+ */
23
+ sample: string | number | boolean;
24
+ };
25
+
26
+ export type MessageTemplateDefinition = {
27
+ /** `<module>.<nome>` — ver assertSlugGrammar. */
28
+ slug: string;
29
+ /** Precisa ser igual ao primeiro segmento do slug. */
30
+ moduleSlug: string;
31
+ /** Rótulo na tela, por código de locale. `pt` é obrigatório. */
32
+ name: Record<string, string>;
33
+ /** Uma linha dizendo quando a mensagem sai. Opcional, por locale. */
34
+ description?: Record<string, string>;
35
+ /**
36
+ * Texto canônico por locale, em Handlebars com o markdown do WhatsApp.
37
+ *
38
+ * É ele que renderiza enquanto ninguém editou — e continua sendo a rede
39
+ * quando o texto editado falha. `pt` é obrigatório.
40
+ */
41
+ fallback: Record<string, string>;
42
+ variables: Record<string, MessageTemplateVariable>;
43
+ };
44
+
45
+ const registry = new Map<string, MessageTemplateDefinition>();
46
+
47
+ const SLUG_RE = /^([a-z0-9-]+)\.([a-z0-9-]+)$/;
48
+
49
+ /** O locale que todo template precisa ter: é o idioma em que a equipe lê o aviso. */
50
+ const REQUIRED_LOCALE = 'pt';
51
+
52
+ function assertDefinition(definition: MessageTemplateDefinition) {
53
+ const match = SLUG_RE.exec(definition.slug);
54
+
55
+ if (!match) {
56
+ throw new Error(
57
+ `Slug de modelo de mensagem inválido: "${definition.slug}". ` +
58
+ 'Esperado <module>.<nome>, em minúsculas.',
59
+ );
60
+ }
61
+
62
+ // Sem isto, duas libraries poderiam brigar por um slug curto como "paid" e a
63
+ // tela não teria como dizer de quem é o modelo.
64
+ if (match[1] !== definition.moduleSlug) {
65
+ throw new Error(
66
+ `O modelo "${definition.slug}" declara moduleSlug "${definition.moduleSlug}", ` +
67
+ `mas o slug diz "${match[1]}".`,
68
+ );
69
+ }
70
+
71
+ if (!definition.name?.[REQUIRED_LOCALE]?.trim()) {
72
+ throw new Error(`O modelo "${definition.slug}" não tem nome em "${REQUIRED_LOCALE}".`);
73
+ }
74
+
75
+ if (!definition.fallback?.[REQUIRED_LOCALE]?.trim()) {
76
+ throw new Error(
77
+ `O modelo "${definition.slug}" não tem texto padrão em "${REQUIRED_LOCALE}". ` +
78
+ 'Sem ele, uma linha quebrada no banco deixaria o aviso mudo.',
79
+ );
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Chamado no carregamento do módulo de cada library, a partir do
85
+ * `*.message-templates.ts` dela. Slug duplicado lança, então duas libraries não
86
+ * reivindicam o mesmo modelo em silêncio.
87
+ */
88
+ export function registerMessageTemplates(
89
+ definitions: MessageTemplateDefinition[],
90
+ ): void {
91
+ for (const definition of definitions) {
92
+ assertDefinition(definition);
93
+
94
+ const existing = registry.get(definition.slug);
95
+ if (existing && existing !== definition) {
96
+ throw new Error(`O modelo de mensagem "${definition.slug}" já está registrado.`);
97
+ }
98
+
99
+ registry.set(definition.slug, definition);
100
+ }
101
+ }
102
+
103
+ export function getMessageTemplateDefinition(
104
+ slug: string,
105
+ ): MessageTemplateDefinition | undefined {
106
+ return registry.get(slug);
107
+ }
108
+
109
+ export function listMessageTemplateDefinitions(
110
+ moduleSlug?: string,
111
+ ): MessageTemplateDefinition[] {
112
+ const all = [...registry.values()];
113
+ const filtered = moduleSlug ? all.filter((d) => d.moduleSlug === moduleSlug) : all;
114
+ return filtered.sort((a, b) => a.slug.localeCompare(b.slug));
115
+ }
116
+
117
+ /** Os módulos que registraram algum modelo, para o agrupamento da tela. */
118
+ export function listMessageTemplateModules(): string[] {
119
+ return [...new Set([...registry.values()].map((d) => d.moduleSlug))].sort();
120
+ }
121
+
122
+ /** Auxiliar de teste — o registry é estado de módulo. */
123
+ export function clearMessageTemplateRegistry(): void {
124
+ registry.clear();
125
+ }