@teleporthq/teleport-plugin-next-workflows 0.43.65 → 0.43.67

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 (305) hide show
  1. package/__tests__/_helpers/bind-workflow-utils.ts +30 -0
  2. package/__tests__/_helpers/run-generated-middleware.ts +11 -2
  3. package/__tests__/admin-form-row-hydration.test.ts +55 -0
  4. package/__tests__/cart-clear-db-mirror.test.ts +12 -0
  5. package/__tests__/cart-get-total-regional-pricing.test.ts +166 -0
  6. package/__tests__/client-config-redaction.test.ts +53 -0
  7. package/__tests__/continue-on-error.test.ts +119 -0
  8. package/__tests__/email-locale-module.test.ts +323 -0
  9. package/__tests__/email-locale-senders.test.ts +268 -0
  10. package/__tests__/invoice-delivery-fee.test.ts +104 -0
  11. package/__tests__/invoice-regional-tax.test.ts +126 -0
  12. package/__tests__/locale-aware-redirects.test.ts +355 -0
  13. package/__tests__/navigation-go-to-page.test.ts +43 -0
  14. package/__tests__/node-handler-file-inline-map.test.ts +29 -3
  15. package/__tests__/payment-redirect-and-order-notification.test.ts +6 -0
  16. package/__tests__/paypal-webhook-order-notification.test.ts +41 -0
  17. package/__tests__/resolve-config-localized-templates.test.ts +262 -0
  18. package/__tests__/sent-email-log-module.test.ts +381 -0
  19. package/__tests__/sent-email-log-wiring.test.ts +267 -0
  20. package/dist/cjs/account-delete-route-generator.d.ts +20 -0
  21. package/dist/cjs/account-delete-route-generator.d.ts.map +1 -1
  22. package/dist/cjs/account-delete-route-generator.js +29 -26
  23. package/dist/cjs/account-delete-route-generator.js.map +1 -1
  24. package/dist/cjs/api-route-generator.d.ts.map +1 -1
  25. package/dist/cjs/api-route-generator.js +57 -11
  26. package/dist/cjs/api-route-generator.js.map +1 -1
  27. package/dist/cjs/auth-generator.d.ts +2 -1
  28. package/dist/cjs/auth-generator.d.ts.map +1 -1
  29. package/dist/cjs/auth-generator.js +55 -18
  30. package/dist/cjs/auth-generator.js.map +1 -1
  31. package/dist/cjs/data-api-route-generator.d.ts.map +1 -1
  32. package/dist/cjs/data-api-route-generator.js +19 -0
  33. package/dist/cjs/data-api-route-generator.js.map +1 -1
  34. package/dist/cjs/email-locale/email-locale-code.d.ts +25 -0
  35. package/dist/cjs/email-locale/email-locale-code.d.ts.map +1 -0
  36. package/dist/cjs/email-locale/email-locale-code.js +228 -0
  37. package/dist/cjs/email-locale/email-locale-code.js.map +1 -0
  38. package/dist/cjs/email-locale/email-locale-scope.d.ts +46 -0
  39. package/dist/cjs/email-locale/email-locale-scope.d.ts.map +1 -0
  40. package/dist/cjs/email-locale/email-locale-scope.js +51 -0
  41. package/dist/cjs/email-locale/email-locale-scope.js.map +1 -0
  42. package/dist/cjs/email-locale/index.d.ts +11 -0
  43. package/dist/cjs/email-locale/index.d.ts.map +1 -0
  44. package/dist/cjs/email-locale/index.js +40 -0
  45. package/dist/cjs/email-locale/index.js.map +1 -0
  46. package/dist/cjs/executor-generator.d.ts +11 -1
  47. package/dist/cjs/executor-generator.d.ts.map +1 -1
  48. package/dist/cjs/executor-generator.js +49 -7
  49. package/dist/cjs/executor-generator.js.map +1 -1
  50. package/dist/cjs/index.d.ts +2 -0
  51. package/dist/cjs/index.d.ts.map +1 -1
  52. package/dist/cjs/index.js +9 -1
  53. package/dist/cjs/index.js.map +1 -1
  54. package/dist/cjs/invoice/api-routes-code.d.ts.map +1 -1
  55. package/dist/cjs/invoice/api-routes-code.js +55 -6
  56. package/dist/cjs/invoice/api-routes-code.js.map +1 -1
  57. package/dist/cjs/invoice/email-sender-code.d.ts.map +1 -1
  58. package/dist/cjs/invoice/email-sender-code.js +72 -31
  59. package/dist/cjs/invoice/email-sender-code.js.map +1 -1
  60. package/dist/cjs/invoice/index.d.ts +1 -4
  61. package/dist/cjs/invoice/index.d.ts.map +1 -1
  62. package/dist/cjs/invoice/index.js +8 -19
  63. package/dist/cjs/invoice/index.js.map +1 -1
  64. package/dist/cjs/invoice/invoice-html-code.d.ts.map +1 -1
  65. package/dist/cjs/invoice/invoice-html-code.js +31 -8
  66. package/dist/cjs/invoice/invoice-html-code.js.map +1 -1
  67. package/dist/cjs/invoice/regional-invoice-tax-code.d.ts +25 -0
  68. package/dist/cjs/invoice/regional-invoice-tax-code.d.ts.map +1 -0
  69. package/dist/cjs/invoice/regional-invoice-tax-code.js +116 -0
  70. package/dist/cjs/invoice/regional-invoice-tax-code.js.map +1 -0
  71. package/dist/cjs/invoice/resolve-data-source.d.ts +6 -0
  72. package/dist/cjs/invoice/resolve-data-source.d.ts.map +1 -0
  73. package/dist/cjs/invoice/resolve-data-source.js +23 -0
  74. package/dist/cjs/invoice/resolve-data-source.js.map +1 -0
  75. package/dist/cjs/nodes/account/account-delete-current.d.ts.map +1 -1
  76. package/dist/cjs/nodes/account/account-delete-current.js +10 -3
  77. package/dist/cjs/nodes/account/account-delete-current.js.map +1 -1
  78. package/dist/cjs/nodes/account/account-login.d.ts.map +1 -1
  79. package/dist/cjs/nodes/account/account-login.js +3 -1
  80. package/dist/cjs/nodes/account/account-login.js.map +1 -1
  81. package/dist/cjs/nodes/account/account-logout.d.ts.map +1 -1
  82. package/dist/cjs/nodes/account/account-logout.js +4 -2
  83. package/dist/cjs/nodes/account/account-logout.js.map +1 -1
  84. package/dist/cjs/nodes/account/account-signup.d.ts.map +1 -1
  85. package/dist/cjs/nodes/account/account-signup.js +12 -2
  86. package/dist/cjs/nodes/account/account-signup.js.map +1 -1
  87. package/dist/cjs/nodes/account/account-social-login.d.ts.map +1 -1
  88. package/dist/cjs/nodes/account/account-social-login.js +4 -2
  89. package/dist/cjs/nodes/account/account-social-login.js.map +1 -1
  90. package/dist/cjs/nodes/cart/cart-clear.d.ts.map +1 -1
  91. package/dist/cjs/nodes/cart/cart-clear.js +6 -0
  92. package/dist/cjs/nodes/cart/cart-clear.js.map +1 -1
  93. package/dist/cjs/nodes/cart/cart-get-total.d.ts.map +1 -1
  94. package/dist/cjs/nodes/cart/cart-get-total.js +81 -5
  95. package/dist/cjs/nodes/cart/cart-get-total.js.map +1 -1
  96. package/dist/cjs/nodes/data/data-create-item.d.ts.map +1 -1
  97. package/dist/cjs/nodes/data/data-create-item.js +16 -0
  98. package/dist/cjs/nodes/data/data-create-item.js.map +1 -1
  99. package/dist/cjs/nodes/ecommerce/ecommerce-generate-invoice.d.ts.map +1 -1
  100. package/dist/cjs/nodes/ecommerce/ecommerce-generate-invoice.js +6 -0
  101. package/dist/cjs/nodes/ecommerce/ecommerce-generate-invoice.js.map +1 -1
  102. package/dist/cjs/nodes/navigation/navigation-go-to-page.d.ts.map +1 -1
  103. package/dist/cjs/nodes/navigation/navigation-go-to-page.js +4 -1
  104. package/dist/cjs/nodes/navigation/navigation-go-to-page.js.map +1 -1
  105. package/dist/cjs/nodes/navigation/navigation-navigate-to-url.d.ts.map +1 -1
  106. package/dist/cjs/nodes/navigation/navigation-navigate-to-url.js +5 -2
  107. package/dist/cjs/nodes/navigation/navigation-navigate-to-url.js.map +1 -1
  108. package/dist/cjs/nodes/payment/payment-charge-user.d.ts.map +1 -1
  109. package/dist/cjs/nodes/payment/payment-charge-user.js +7 -2
  110. package/dist/cjs/nodes/payment/payment-charge-user.js.map +1 -1
  111. package/dist/cjs/segment-splitter.d.ts +1 -1
  112. package/dist/cjs/segment-splitter.d.ts.map +1 -1
  113. package/dist/cjs/segment-splitter.js +29 -2
  114. package/dist/cjs/segment-splitter.js.map +1 -1
  115. package/dist/cjs/sent-email-log/index.d.ts +16 -0
  116. package/dist/cjs/sent-email-log/index.d.ts.map +1 -0
  117. package/dist/cjs/sent-email-log/index.js +53 -0
  118. package/dist/cjs/sent-email-log/index.js.map +1 -0
  119. package/dist/cjs/sent-email-log/sent-email-log-code.d.ts +4 -0
  120. package/dist/cjs/sent-email-log/sent-email-log-code.d.ts.map +1 -0
  121. package/dist/cjs/sent-email-log/sent-email-log-code.js +415 -0
  122. package/dist/cjs/sent-email-log/sent-email-log-code.js.map +1 -0
  123. package/dist/cjs/sent-email-log/sent-email-log-scope.d.ts +21 -0
  124. package/dist/cjs/sent-email-log/sent-email-log-scope.d.ts.map +1 -0
  125. package/dist/cjs/sent-email-log/sent-email-log-scope.js +36 -0
  126. package/dist/cjs/sent-email-log/sent-email-log-scope.js.map +1 -0
  127. package/dist/cjs/transactional-email-code.d.ts +39 -1
  128. package/dist/cjs/transactional-email-code.d.ts.map +1 -1
  129. package/dist/cjs/transactional-email-code.js +86 -12
  130. package/dist/cjs/transactional-email-code.js.map +1 -1
  131. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  132. package/dist/cjs/webhook-generator.d.ts.map +1 -1
  133. package/dist/cjs/webhook-generator.js +9 -2
  134. package/dist/cjs/webhook-generator.js.map +1 -1
  135. package/dist/cjs/workflow-component-plugin.js +4 -3
  136. package/dist/cjs/workflow-component-plugin.js.map +1 -1
  137. package/dist/cjs/workflow-project-plugin.d.ts.map +1 -1
  138. package/dist/cjs/workflow-project-plugin.js +31 -3
  139. package/dist/cjs/workflow-project-plugin.js.map +1 -1
  140. package/dist/cjs/workflow-utils-alias.d.ts +21 -0
  141. package/dist/cjs/workflow-utils-alias.d.ts.map +1 -0
  142. package/dist/cjs/workflow-utils-alias.js +27 -0
  143. package/dist/cjs/workflow-utils-alias.js.map +1 -0
  144. package/dist/esm/account-delete-route-generator.d.ts +20 -0
  145. package/dist/esm/account-delete-route-generator.d.ts.map +1 -1
  146. package/dist/esm/account-delete-route-generator.js +30 -27
  147. package/dist/esm/account-delete-route-generator.js.map +1 -1
  148. package/dist/esm/api-route-generator.d.ts.map +1 -1
  149. package/dist/esm/api-route-generator.js +57 -11
  150. package/dist/esm/api-route-generator.js.map +1 -1
  151. package/dist/esm/auth-generator.d.ts +2 -1
  152. package/dist/esm/auth-generator.d.ts.map +1 -1
  153. package/dist/esm/auth-generator.js +56 -19
  154. package/dist/esm/auth-generator.js.map +1 -1
  155. package/dist/esm/data-api-route-generator.d.ts.map +1 -1
  156. package/dist/esm/data-api-route-generator.js +19 -0
  157. package/dist/esm/data-api-route-generator.js.map +1 -1
  158. package/dist/esm/email-locale/email-locale-code.d.ts +25 -0
  159. package/dist/esm/email-locale/email-locale-code.d.ts.map +1 -0
  160. package/dist/esm/email-locale/email-locale-code.js +222 -0
  161. package/dist/esm/email-locale/email-locale-code.js.map +1 -0
  162. package/dist/esm/email-locale/email-locale-scope.d.ts +46 -0
  163. package/dist/esm/email-locale/email-locale-scope.d.ts.map +1 -0
  164. package/dist/esm/email-locale/email-locale-scope.js +47 -0
  165. package/dist/esm/email-locale/email-locale-scope.js.map +1 -0
  166. package/dist/esm/email-locale/index.d.ts +11 -0
  167. package/dist/esm/email-locale/index.d.ts.map +1 -0
  168. package/dist/esm/email-locale/index.js +28 -0
  169. package/dist/esm/email-locale/index.js.map +1 -0
  170. package/dist/esm/executor-generator.d.ts +11 -1
  171. package/dist/esm/executor-generator.d.ts.map +1 -1
  172. package/dist/esm/executor-generator.js +49 -7
  173. package/dist/esm/executor-generator.js.map +1 -1
  174. package/dist/esm/index.d.ts +2 -0
  175. package/dist/esm/index.d.ts.map +1 -1
  176. package/dist/esm/index.js +2 -0
  177. package/dist/esm/index.js.map +1 -1
  178. package/dist/esm/invoice/api-routes-code.d.ts.map +1 -1
  179. package/dist/esm/invoice/api-routes-code.js +55 -6
  180. package/dist/esm/invoice/api-routes-code.js.map +1 -1
  181. package/dist/esm/invoice/email-sender-code.d.ts.map +1 -1
  182. package/dist/esm/invoice/email-sender-code.js +72 -31
  183. package/dist/esm/invoice/email-sender-code.js.map +1 -1
  184. package/dist/esm/invoice/index.d.ts +1 -4
  185. package/dist/esm/invoice/index.d.ts.map +1 -1
  186. package/dist/esm/invoice/index.js +7 -18
  187. package/dist/esm/invoice/index.js.map +1 -1
  188. package/dist/esm/invoice/invoice-html-code.d.ts.map +1 -1
  189. package/dist/esm/invoice/invoice-html-code.js +31 -8
  190. package/dist/esm/invoice/invoice-html-code.js.map +1 -1
  191. package/dist/esm/invoice/regional-invoice-tax-code.d.ts +25 -0
  192. package/dist/esm/invoice/regional-invoice-tax-code.d.ts.map +1 -0
  193. package/dist/esm/invoice/regional-invoice-tax-code.js +113 -0
  194. package/dist/esm/invoice/regional-invoice-tax-code.js.map +1 -0
  195. package/dist/esm/invoice/resolve-data-source.d.ts +6 -0
  196. package/dist/esm/invoice/resolve-data-source.d.ts.map +1 -0
  197. package/dist/esm/invoice/resolve-data-source.js +19 -0
  198. package/dist/esm/invoice/resolve-data-source.js.map +1 -0
  199. package/dist/esm/nodes/account/account-delete-current.d.ts.map +1 -1
  200. package/dist/esm/nodes/account/account-delete-current.js +10 -3
  201. package/dist/esm/nodes/account/account-delete-current.js.map +1 -1
  202. package/dist/esm/nodes/account/account-login.d.ts.map +1 -1
  203. package/dist/esm/nodes/account/account-login.js +3 -1
  204. package/dist/esm/nodes/account/account-login.js.map +1 -1
  205. package/dist/esm/nodes/account/account-logout.d.ts.map +1 -1
  206. package/dist/esm/nodes/account/account-logout.js +4 -2
  207. package/dist/esm/nodes/account/account-logout.js.map +1 -1
  208. package/dist/esm/nodes/account/account-signup.d.ts.map +1 -1
  209. package/dist/esm/nodes/account/account-signup.js +12 -2
  210. package/dist/esm/nodes/account/account-signup.js.map +1 -1
  211. package/dist/esm/nodes/account/account-social-login.d.ts.map +1 -1
  212. package/dist/esm/nodes/account/account-social-login.js +4 -2
  213. package/dist/esm/nodes/account/account-social-login.js.map +1 -1
  214. package/dist/esm/nodes/cart/cart-clear.d.ts.map +1 -1
  215. package/dist/esm/nodes/cart/cart-clear.js +6 -0
  216. package/dist/esm/nodes/cart/cart-clear.js.map +1 -1
  217. package/dist/esm/nodes/cart/cart-get-total.d.ts.map +1 -1
  218. package/dist/esm/nodes/cart/cart-get-total.js +81 -5
  219. package/dist/esm/nodes/cart/cart-get-total.js.map +1 -1
  220. package/dist/esm/nodes/data/data-create-item.d.ts.map +1 -1
  221. package/dist/esm/nodes/data/data-create-item.js +16 -0
  222. package/dist/esm/nodes/data/data-create-item.js.map +1 -1
  223. package/dist/esm/nodes/ecommerce/ecommerce-generate-invoice.d.ts.map +1 -1
  224. package/dist/esm/nodes/ecommerce/ecommerce-generate-invoice.js +6 -0
  225. package/dist/esm/nodes/ecommerce/ecommerce-generate-invoice.js.map +1 -1
  226. package/dist/esm/nodes/navigation/navigation-go-to-page.d.ts.map +1 -1
  227. package/dist/esm/nodes/navigation/navigation-go-to-page.js +4 -1
  228. package/dist/esm/nodes/navigation/navigation-go-to-page.js.map +1 -1
  229. package/dist/esm/nodes/navigation/navigation-navigate-to-url.d.ts.map +1 -1
  230. package/dist/esm/nodes/navigation/navigation-navigate-to-url.js +5 -2
  231. package/dist/esm/nodes/navigation/navigation-navigate-to-url.js.map +1 -1
  232. package/dist/esm/nodes/payment/payment-charge-user.d.ts.map +1 -1
  233. package/dist/esm/nodes/payment/payment-charge-user.js +7 -2
  234. package/dist/esm/nodes/payment/payment-charge-user.js.map +1 -1
  235. package/dist/esm/segment-splitter.d.ts +1 -1
  236. package/dist/esm/segment-splitter.d.ts.map +1 -1
  237. package/dist/esm/segment-splitter.js +29 -2
  238. package/dist/esm/segment-splitter.js.map +1 -1
  239. package/dist/esm/sent-email-log/index.d.ts +16 -0
  240. package/dist/esm/sent-email-log/index.d.ts.map +1 -0
  241. package/dist/esm/sent-email-log/index.js +45 -0
  242. package/dist/esm/sent-email-log/index.js.map +1 -0
  243. package/dist/esm/sent-email-log/sent-email-log-code.d.ts +4 -0
  244. package/dist/esm/sent-email-log/sent-email-log-code.d.ts.map +1 -0
  245. package/dist/esm/sent-email-log/sent-email-log-code.js +411 -0
  246. package/dist/esm/sent-email-log/sent-email-log-code.js.map +1 -0
  247. package/dist/esm/sent-email-log/sent-email-log-scope.d.ts +21 -0
  248. package/dist/esm/sent-email-log/sent-email-log-scope.d.ts.map +1 -0
  249. package/dist/esm/sent-email-log/sent-email-log-scope.js +31 -0
  250. package/dist/esm/sent-email-log/sent-email-log-scope.js.map +1 -0
  251. package/dist/esm/transactional-email-code.d.ts +39 -1
  252. package/dist/esm/transactional-email-code.d.ts.map +1 -1
  253. package/dist/esm/transactional-email-code.js +81 -10
  254. package/dist/esm/transactional-email-code.js.map +1 -1
  255. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  256. package/dist/esm/webhook-generator.d.ts.map +1 -1
  257. package/dist/esm/webhook-generator.js +9 -2
  258. package/dist/esm/webhook-generator.js.map +1 -1
  259. package/dist/esm/workflow-component-plugin.js +4 -3
  260. package/dist/esm/workflow-component-plugin.js.map +1 -1
  261. package/dist/esm/workflow-project-plugin.d.ts.map +1 -1
  262. package/dist/esm/workflow-project-plugin.js +32 -4
  263. package/dist/esm/workflow-project-plugin.js.map +1 -1
  264. package/dist/esm/workflow-utils-alias.d.ts +21 -0
  265. package/dist/esm/workflow-utils-alias.d.ts.map +1 -0
  266. package/dist/esm/workflow-utils-alias.js +21 -0
  267. package/dist/esm/workflow-utils-alias.js.map +1 -0
  268. package/package.json +4 -4
  269. package/src/account-delete-route-generator.ts +36 -7
  270. package/src/api-route-generator.ts +64 -11
  271. package/src/auth-generator.ts +63 -18
  272. package/src/data-api-route-generator.ts +19 -0
  273. package/src/email-locale/email-locale-code.ts +239 -0
  274. package/src/email-locale/email-locale-scope.ts +65 -0
  275. package/src/email-locale/index.ts +46 -0
  276. package/src/executor-generator.ts +65 -7
  277. package/src/index.ts +8 -0
  278. package/src/invoice/api-routes-code.ts +65 -6
  279. package/src/invoice/email-sender-code.ts +72 -31
  280. package/src/invoice/index.ts +7 -23
  281. package/src/invoice/invoice-html-code.ts +31 -8
  282. package/src/invoice/regional-invoice-tax-code.ts +112 -0
  283. package/src/invoice/resolve-data-source.ts +25 -0
  284. package/src/nodes/account/account-delete-current.ts +10 -3
  285. package/src/nodes/account/account-login.ts +3 -1
  286. package/src/nodes/account/account-logout.ts +4 -2
  287. package/src/nodes/account/account-signup.ts +12 -2
  288. package/src/nodes/account/account-social-login.ts +7 -2
  289. package/src/nodes/cart/cart-clear.ts +6 -0
  290. package/src/nodes/cart/cart-get-total.ts +94 -5
  291. package/src/nodes/data/data-create-item.ts +16 -0
  292. package/src/nodes/ecommerce/ecommerce-generate-invoice.ts +6 -0
  293. package/src/nodes/navigation/navigation-go-to-page.ts +5 -1
  294. package/src/nodes/navigation/navigation-navigate-to-url.ts +6 -2
  295. package/src/nodes/payment/payment-charge-user.ts +13 -2
  296. package/src/nodes/workflow-utils-global.d.ts +12 -0
  297. package/src/segment-splitter.ts +33 -2
  298. package/src/sent-email-log/index.ts +57 -0
  299. package/src/sent-email-log/sent-email-log-code.ts +419 -0
  300. package/src/sent-email-log/sent-email-log-scope.ts +36 -0
  301. package/src/transactional-email-code.ts +112 -4
  302. package/src/webhook-generator.ts +11 -2
  303. package/src/workflow-component-plugin.ts +4 -3
  304. package/src/workflow-project-plugin.ts +36 -4
  305. package/src/workflow-utils-alias.ts +26 -0
@@ -0,0 +1,411 @@
1
+ import { generatePgClientCode } from '../pg-client-code';
2
+ /**
3
+ * Emits `utils/email/sent-email-log.js` — the ONE place every email the
4
+ * generated app sends is recorded into `teleport_sent_emails`.
5
+ *
6
+ * Callers (in this order of coverage):
7
+ * - workflow `email-*` / Gmail / Outlook nodes: wrapped per server route by
8
+ * `wrapEmailNodeHandler` (see `generateNodeHandlersForSegment`);
9
+ * - the invoice sender (`utils/invoices/email-sender.js`);
10
+ * - the welcome / farewell routes (`transactional-email-code.ts`);
11
+ * - the order-notification / low-stock routes (`utils/ecommerce/email-sender.js`).
12
+ *
13
+ * Contract: `recordSentEmail` never throws and never rejects, the send is
14
+ * never delayed by it, and a route drains it before replying (a serverless
15
+ * function may be frozen the instant it responds). Only an explicit allow-list
16
+ * of fields is stored — a node config carries credentials.
17
+ *
18
+ * `pgSupported=false` (a MySQL / Mongo / Firestore project) emits a module with
19
+ * the same exports that records nothing, so consumers need no branching.
20
+ */
21
+ const PG_REQUIRE_LINE = "const { Client } = require('pg');";
22
+ /**
23
+ * The shared `getClient()` boilerplate with its eager `require('pg')` swapped
24
+ * for the lazy loader above: a project can carry an email node and no
25
+ * Postgres driver, and a top-level require would fail the build of every
26
+ * workflow route ("Collecting page data"). `new Client(opts)` keeps working —
27
+ * a constructor that returns an object yields that object.
28
+ */
29
+ const lazyPgClientCode = () => {
30
+ const code = generatePgClientCode();
31
+ if (!code.startsWith(PG_REQUIRE_LINE)) {
32
+ throw new Error('sent-email-log: generatePgClientCode() no longer starts with the pg require line');
33
+ }
34
+ return code.replace(PG_REQUIRE_LINE, 'function Client(opts) { var pg = __loadPg(); return new pg.Client(opts); }');
35
+ };
36
+ export const generateSentEmailLogCode = (options) => {
37
+ if (!options.pgSupported) {
38
+ return `/**
39
+ * Sent-email ledger — disabled: the project's data source is not Postgres.
40
+ */
41
+ function recordSentEmail() { return Promise.resolve(false); }
42
+ function settleSentEmailLog() { return Promise.resolve(); }
43
+ function wrapEmailNodeHandler(_nodeType, handler) { return handler; }
44
+
45
+ module.exports = { recordSentEmail, settleSentEmailLog, wrapEmailNodeHandler };
46
+ `;
47
+ }
48
+ return `/**
49
+ * Sent-email ledger.
50
+ *
51
+ * Every email the app sends — workflow email nodes, the invoice sender, the
52
+ * welcome/farewell routes, order and stock alerts — lands here as one row of
53
+ * \`teleport_sent_emails\`: who it went to, what it said, the values the
54
+ * template was filled with, and whether the provider accepted it.
55
+ *
56
+ * Never awaited by the send itself; never throws; drained before a route
57
+ * replies (see settleSentEmailLog).
58
+ */
59
+ var __pg = null;
60
+ var __pgLoadFailed = false;
61
+ function __loadPg() {
62
+ if (__pg || __pgLoadFailed) return __pg;
63
+ try { __pg = require('pg'); } catch (_e) { __pgLoadFailed = true; __pg = null; }
64
+ return __pg;
65
+ }
66
+
67
+ ${lazyPgClientCode()}
68
+
69
+ var TABLE_NAME = 'teleport_sent_emails';
70
+ var BODY_MAX_CHARS = 1000000;
71
+ var PAYLOAD_MAX_CHARS = 200000;
72
+ var SUBJECT_MAX_CHARS = 2000;
73
+ var ADDRESS_MAX_CHARS = 320;
74
+ var TRUNCATION_MARKER = '\\n<!-- truncated by sent-email-log -->';
75
+ var INSERT_TIMEOUT_MS = 15000;
76
+ var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
77
+ // Template parameters whose VALUE must not be persisted: a reset link carries
78
+ // a live token, and the ledger is readable from the admin panel.
79
+ var SENSITIVE_PARAM_KEY_RE = /token|password|secret|otp|reset|verif|magic|passcode/i;
80
+ var REDACTED = '[redacted]';
81
+
82
+ var __pending = [];
83
+ var __disabledReason = '';
84
+ var __consecutiveFailures = 0;
85
+ var MAX_CONSECUTIVE_FAILURES = 3;
86
+
87
+ function __disable(reason) {
88
+ if (__disabledReason) return;
89
+ __disabledReason = reason;
90
+ console.warn('[sent-email-log] disabled for this process: ' + reason);
91
+ }
92
+
93
+ function __hasDatabaseEnv() {
94
+ return !!(process.env.TELEPORT_DB_CONNECTION_STRING || process.env.TELEPORT_DB_HOST);
95
+ }
96
+
97
+ function __toArray(value) {
98
+ if (value == null || value === '') return [];
99
+ if (Array.isArray(value)) {
100
+ var out = [];
101
+ for (var i = 0; i < value.length; i++) { out = out.concat(__toArray(value[i])); }
102
+ return out;
103
+ }
104
+ if (typeof value === 'object') {
105
+ // Provider SDK shapes: { email, name } / { address }.
106
+ var addr = value.email || value.address || value.emailAddress;
107
+ return addr ? [String(addr)] : [];
108
+ }
109
+ return String(value).split(',').map(function (s) { return s.trim(); }).filter(Boolean);
110
+ }
111
+
112
+ function __truncate(text, max) {
113
+ if (text == null) return null;
114
+ var str = String(text);
115
+ if (str.length <= max) return str;
116
+ return str.slice(0, max) + TRUNCATION_MARKER;
117
+ }
118
+
119
+ function __safeStringify(value, max) {
120
+ if (value == null) return null;
121
+ var json;
122
+ try {
123
+ json = JSON.stringify(value, function (_k, v) {
124
+ if (typeof v === 'bigint') return String(v);
125
+ if (v && typeof v === 'object' && v.type === 'Buffer' && Array.isArray(v.data)) return '[buffer ' + v.data.length + ' bytes]';
126
+ return v;
127
+ });
128
+ } catch (_e) {
129
+ return '"[unserializable]"';
130
+ }
131
+ if (json == null) return null;
132
+ return __truncate(json, max);
133
+ }
134
+
135
+ // "Acme Billing <billing@acme.com>" → { name, email }; "billing@acme.com" → { name: '', email }.
136
+ function __parseAddress(from) {
137
+ var str = String(from || '').trim();
138
+ if (!str) return { name: '', email: '' };
139
+ var m = /^(.*)<([^<>]+)>\\s*$/.exec(str);
140
+ if (m) return { name: m[1].trim().replace(/^"|"$/g, ''), email: m[2].trim() };
141
+ return { name: '', email: str };
142
+ }
143
+
144
+ function __uuidOrNull(value) {
145
+ if (typeof value !== 'string' || !UUID_RE.test(value)) return null;
146
+ return value;
147
+ }
148
+
149
+ // templateParams arrive as [{ key, value }] (workflow nodes) or as a plain
150
+ // object (routes). Returns { payload, redactedValues } where redactedValues
151
+ // are the string values of sensitive keys, to be scrubbed from the body too.
152
+ function __normalizePayload(params) {
153
+ var payload = {};
154
+ var redactedValues = [];
155
+ var entries = [];
156
+ if (Array.isArray(params)) {
157
+ for (var i = 0; i < params.length; i++) {
158
+ var p = params[i];
159
+ if (p && typeof p === 'object' && typeof p.key === 'string') entries.push([p.key, p.value]);
160
+ }
161
+ } else if (params && typeof params === 'object') {
162
+ var keys = Object.keys(params);
163
+ for (var k = 0; k < keys.length; k++) entries.push([keys[k], params[keys[k]]]);
164
+ }
165
+ for (var e = 0; e < entries.length; e++) {
166
+ var key = entries[e][0];
167
+ var value = entries[e][1];
168
+ if (SENSITIVE_PARAM_KEY_RE.test(key)) {
169
+ if (typeof value === 'string' && value.length >= 8) redactedValues.push(value);
170
+ payload[key] = REDACTED;
171
+ } else {
172
+ payload[key] = value;
173
+ }
174
+ }
175
+ return { payload: entries.length ? payload : null, redactedValues: redactedValues };
176
+ }
177
+
178
+ function __scrub(text, redactedValues) {
179
+ if (!text) return text;
180
+ var out = String(text);
181
+ for (var i = 0; i < redactedValues.length; i++) {
182
+ out = out.split(redactedValues[i]).join(REDACTED);
183
+ }
184
+ return out;
185
+ }
186
+
187
+ function __normalizeAttachments(attachments) {
188
+ if (!Array.isArray(attachments) || attachments.length === 0) return null;
189
+ var out = [];
190
+ for (var i = 0; i < attachments.length; i++) {
191
+ var a = attachments[i] || {};
192
+ out.push({
193
+ filename: a.filename || a.name || a.Name || 'attachment',
194
+ contentType: a.contentType || a.type || a.ContentType || null,
195
+ sizeBytes: typeof a.sizeBytes === 'number' ? a.sizeBytes : null,
196
+ url: a.url || null,
197
+ });
198
+ }
199
+ return __safeStringify(out, PAYLOAD_MAX_CHARS);
200
+ }
201
+
202
+ /**
203
+ * Maps a loose entry onto the table's columns. Returns null when there is
204
+ * nothing to record (no recipient at all).
205
+ *
206
+ * entry: { emailType, audience, to, cc, bcc, from, fromName, replyTo, subject,
207
+ * html, payload, attachments, provider, providerMessageId, status,
208
+ * error, source, sourceRef, orderId, userId, referenceType, referenceId }
209
+ */
210
+ function buildSentEmailRow(entry) {
211
+ var e = entry || {};
212
+ var recipients = __toArray(e.to);
213
+ if (recipients.length === 0) return null;
214
+ var from = __parseAddress(e.from);
215
+ var fromName = e.fromName ? String(e.fromName) : from.name;
216
+ var normalized = __normalizePayload(e.payload);
217
+ var cc = __toArray(e.cc);
218
+ var bcc = __toArray(e.bcc);
219
+ var status = e.status === 'failed' ? 'failed' : 'sent';
220
+ return {
221
+ email_type: __truncate(e.emailType || 'custom', 100),
222
+ audience: __truncate(e.audience || 'other', 20),
223
+ recipient_email: __truncate(recipients[0], ADDRESS_MAX_CHARS),
224
+ recipients: JSON.stringify(recipients),
225
+ cc: cc.length ? JSON.stringify(cc) : null,
226
+ bcc: bcc.length ? JSON.stringify(bcc) : null,
227
+ reply_to: e.replyTo ? __truncate(__toArray(e.replyTo)[0] || '', ADDRESS_MAX_CHARS) : null,
228
+ from_email: from.email ? __truncate(from.email, ADDRESS_MAX_CHARS) : null,
229
+ from_name: fromName ? __truncate(fromName, 255) : null,
230
+ subject: __truncate(__scrub(e.subject, normalized.redactedValues), SUBJECT_MAX_CHARS),
231
+ body_html: __truncate(__scrub(e.html, normalized.redactedValues), BODY_MAX_CHARS) || '',
232
+ payload: __safeStringify(normalized.payload, PAYLOAD_MAX_CHARS),
233
+ attachments: __normalizeAttachments(e.attachments),
234
+ provider: e.provider ? __truncate(e.provider, 50) : null,
235
+ provider_message_id: e.providerMessageId ? __truncate(String(e.providerMessageId), 255) : null,
236
+ status: status,
237
+ error_message: e.error ? __truncate(String(e.error), 4000) : null,
238
+ source: __truncate(e.source || 'app', 50),
239
+ source_ref: e.sourceRef ? __truncate(String(e.sourceRef), 255) : null,
240
+ order_id: __uuidOrNull(e.orderId),
241
+ user_id: __uuidOrNull(e.userId),
242
+ reference_type: e.referenceType ? __truncate(String(e.referenceType), 50) : null,
243
+ reference_id: e.referenceId ? __truncate(String(e.referenceId), 255) : null,
244
+ };
245
+ }
246
+
247
+ function __newId() {
248
+ try {
249
+ var crypto = require('crypto');
250
+ if (typeof crypto.randomUUID === 'function') return crypto.randomUUID();
251
+ var b = crypto.randomBytes(16);
252
+ b[6] = (b[6] & 0x0f) | 0x40;
253
+ b[8] = (b[8] & 0x3f) | 0x80;
254
+ var h = b.toString('hex');
255
+ return h.slice(0, 8) + '-' + h.slice(8, 12) + '-' + h.slice(12, 16) + '-' + h.slice(16, 20) + '-' + h.slice(20);
256
+ } catch (_e) {
257
+ return null;
258
+ }
259
+ }
260
+
261
+ function __withTimeout(promise, ms) {
262
+ var timer;
263
+ var timeout = new Promise(function (_resolve, reject) {
264
+ timer = setTimeout(function () { reject(new Error('sent-email-log insert timed out after ' + ms + 'ms')); }, ms);
265
+ });
266
+ return Promise.race([promise, timeout]).then(function (v) { clearTimeout(timer); return v; }, function (err) { clearTimeout(timer); throw err; });
267
+ }
268
+
269
+ async function __insert(row) {
270
+ var columns = Object.keys(row);
271
+ var values = columns.map(function (c) { return row[c]; });
272
+ var id = __newId();
273
+ if (id) { columns.unshift('id'); values.unshift(id); }
274
+ var placeholders = values.map(function (_v, i) { return '$' + (i + 1); });
275
+ var sql = 'INSERT INTO "' + TABLE_NAME + '" (' + columns.map(function (c) { return '"' + c + '"'; }).join(', ') + ') VALUES (' + placeholders.join(', ') + ')';
276
+ var client = getClient();
277
+ await client.connect();
278
+ try {
279
+ await __withTimeout(client.query(sql, values), INSERT_TIMEOUT_MS);
280
+ } finally {
281
+ try { await client.end(); } catch (_e) {}
282
+ }
283
+ }
284
+
285
+ /**
286
+ * Records one send attempt. Resolves to true when the row landed, false
287
+ * otherwise. NEVER rejects.
288
+ */
289
+ function recordSentEmail(entry) {
290
+ var task = (async function () {
291
+ if (__disabledReason) return false;
292
+ if (!__hasDatabaseEnv()) { __disable('no database connection configured'); return false; }
293
+ if (!__loadPg()) { __disable('the pg driver is not installed'); return false; }
294
+ var row;
295
+ try { row = buildSentEmailRow(entry); } catch (buildErr) {
296
+ console.error('[sent-email-log] could not build the row:', buildErr && buildErr.message ? buildErr.message : buildErr);
297
+ return false;
298
+ }
299
+ if (!row) return false;
300
+ try {
301
+ await __insert(row);
302
+ __consecutiveFailures = 0;
303
+ return true;
304
+ } catch (err) {
305
+ var code = err && err.code;
306
+ if (code === '42P01') { __disable('table ' + TABLE_NAME + ' does not exist — re-run the feature activation in the editor'); return false; }
307
+ if (code === '42703') { __disable('table ' + TABLE_NAME + ' is missing a column — re-run the feature activation in the editor'); return false; }
308
+ __consecutiveFailures += 1;
309
+ console.error('[sent-email-log] insert failed: ' + (err && err.message ? err.message : String(err)));
310
+ if (__consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) __disable('repeated insert failures');
311
+ return false;
312
+ }
313
+ })();
314
+ __pending.push(task);
315
+ task.then(function () { __forget(task); }, function () { __forget(task); });
316
+ return task;
317
+ }
318
+
319
+ function __forget(task) {
320
+ var idx = __pending.indexOf(task);
321
+ if (idx >= 0) __pending.splice(idx, 1);
322
+ }
323
+
324
+ /** Awaits every in-flight record. Never rejects. */
325
+ async function settleSentEmailLog() {
326
+ for (var pass = 0; pass < 5 && __pending.length > 0; pass++) {
327
+ await Promise.all(__pending.slice());
328
+ }
329
+ }
330
+
331
+ // Provider name from a node type: 'email-resend' → 'resend', 'integration-gmail' → 'gmail'.
332
+ function __providerOf(nodeType) {
333
+ var t = String(nodeType || '');
334
+ if (t.indexOf('email-') === 0) return t.slice(6);
335
+ if (t.indexOf('integration-') === 0) return t.slice(12);
336
+ return t || null;
337
+ }
338
+
339
+ function __shouldRecordNode(nodeType, config) {
340
+ if (String(nodeType).indexOf('email-') === 0) return true;
341
+ return !!config && config.action === 'send-email';
342
+ }
343
+
344
+ function __entryFromNode(nodeType, config, result, error) {
345
+ var c = config || {};
346
+ var r = result || {};
347
+ var failed = !!error || r.success === false || (typeof r.error === 'string' && r.error) || r.error === true;
348
+ var message = r.message && typeof r.message === 'object' ? r.message : null;
349
+ var providerMessageId = r.messageId || r.id || (message && message.id) || null;
350
+ var errorText = error ? (error.message || String(error)) : (typeof r.error === 'string' ? r.error : (r.error === true && typeof r.message === 'string' ? r.message : null));
351
+ return {
352
+ emailType: c.emailPurpose || 'custom',
353
+ audience: c.emailAudience || 'other',
354
+ to: c.to,
355
+ cc: c.cc,
356
+ bcc: c.bcc,
357
+ from: c.from,
358
+ fromName: c.fromName,
359
+ replyTo: c.replyTo,
360
+ subject: c.subject,
361
+ html: c.body != null ? c.body : (c.html != null ? c.html : c.text),
362
+ payload: c.templateParams,
363
+ provider: __providerOf(nodeType),
364
+ providerMessageId: providerMessageId,
365
+ status: failed ? 'failed' : 'sent',
366
+ error: errorText,
367
+ source: 'workflow',
368
+ sourceRef: nodeType,
369
+ };
370
+ }
371
+
372
+ /**
373
+ * Wraps a server node handler so every send is recorded. The record is
374
+ * registered on the workflow context's fire-and-forget queue — the same one
375
+ * \`settlePendingNodePromises\` drains before the route replies — and pushed
376
+ * BEFORE the handler's result is returned, so the drain always sees it.
377
+ * Extra arguments (a streaming callback) are forwarded untouched.
378
+ */
379
+ function wrapEmailNodeHandler(nodeType, handler) {
380
+ if (typeof handler !== 'function') return handler;
381
+ return async function (config, context) {
382
+ if (!__shouldRecordNode(nodeType, config)) {
383
+ return handler.apply(this, arguments);
384
+ }
385
+ var result;
386
+ try {
387
+ result = await handler.apply(this, arguments);
388
+ } catch (err) {
389
+ __register(context, recordSentEmail(__entryFromNode(nodeType, config, null, err)));
390
+ throw err;
391
+ }
392
+ __register(context, recordSentEmail(__entryFromNode(nodeType, config, result, null)));
393
+ return result;
394
+ };
395
+ }
396
+
397
+ function __register(context, promise) {
398
+ if (!context || typeof context !== 'object') return;
399
+ if (!Array.isArray(context.__pendingNodePromises)) context.__pendingNodePromises = [];
400
+ context.__pendingNodePromises.push(promise);
401
+ }
402
+
403
+ module.exports = {
404
+ recordSentEmail: recordSentEmail,
405
+ settleSentEmailLog: settleSentEmailLog,
406
+ wrapEmailNodeHandler: wrapEmailNodeHandler,
407
+ buildSentEmailRow: buildSentEmailRow,
408
+ };
409
+ `;
410
+ };
411
+ //# sourceMappingURL=sent-email-log-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sent-email-log-code.js","sourceRoot":"","sources":["../../../src/sent-email-log/sent-email-log-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAExD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,eAAe,GAAG,mCAAmC,CAAA;AAE3D;;;;;;GAMG;AACH,MAAM,gBAAgB,GAAG,GAAW,EAAE;IACpC,MAAM,IAAI,GAAG,oBAAoB,EAAE,CAAA;IACnC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE;QACrC,MAAM,IAAI,KAAK,CACb,kFAAkF,CACnF,CAAA;KACF;IACD,OAAO,IAAI,CAAC,OAAO,CACjB,eAAe,EACf,4EAA4E,CAC7E,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,OAAiC,EAAU,EAAE;IACpF,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;QACxB,OAAO;;;;;;;;CAQV,CAAA;KACE;IAED,OAAO;;;;;;;;;;;;;;;;;;;EAmBP,gBAAgB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsVnB,CAAA;AACD,CAAC,CAAA"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Which generated code sends email, and therefore which projects get the
3
+ * sent-email ledger module (`utils/email/sent-email-log.js`).
4
+ *
5
+ * Every emitter of a send path calls `ensureSentEmailLogModule` itself, so the
6
+ * module exists exactly when something `require`s it. This file only holds the
7
+ * node-type vocabulary the route generators share.
8
+ */
9
+ export declare const SENT_EMAIL_LOG_FILE_KEY = "sent-email-log";
10
+ export declare const SENT_EMAIL_LOG_PATH: string[];
11
+ export declare const SENT_EMAIL_LOG_FILE_NAME = "sent-email-log";
12
+ /** Provider send-email nodes: `email-resend`, `email-sendgrid`, … */
13
+ export declare const EMAIL_NODE_TYPE_PREFIX = "email-";
14
+ /**
15
+ * Integration nodes that can send mail among other actions. Only their
16
+ * `send-email` action is recorded; the wrapper checks the resolved config.
17
+ */
18
+ export declare const EMAIL_CAPABLE_INTEGRATION_NODE_TYPES: Set<string>;
19
+ export declare const isEmailSendingNodeType: (nodeType: string) => boolean;
20
+ export declare const hasEmailSendingNodeType: (nodeTypes: Iterable<string>) => boolean;
21
+ //# sourceMappingURL=sent-email-log-scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sent-email-log-scope.d.ts","sourceRoot":"","sources":["../../../src/sent-email-log/sent-email-log-scope.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,eAAO,MAAM,uBAAuB,mBAAmB,CAAA;AACvD,eAAO,MAAM,mBAAmB,UAAqB,CAAA;AACrD,eAAO,MAAM,wBAAwB,mBAAmB,CAAA;AAExD,qEAAqE;AACrE,eAAO,MAAM,sBAAsB,WAAW,CAAA;AAE9C;;;GAGG;AACH,eAAO,MAAM,oCAAoC,aAG/C,CAAA;AAEF,eAAO,MAAM,sBAAsB,aAAc,MAAM,KAAG,OACyC,CAAA;AAEnG,eAAO,MAAM,uBAAuB,cAAe,SAAS,MAAM,CAAC,KAAG,OAOrE,CAAA"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Which generated code sends email, and therefore which projects get the
3
+ * sent-email ledger module (`utils/email/sent-email-log.js`).
4
+ *
5
+ * Every emitter of a send path calls `ensureSentEmailLogModule` itself, so the
6
+ * module exists exactly when something `require`s it. This file only holds the
7
+ * node-type vocabulary the route generators share.
8
+ */
9
+ export const SENT_EMAIL_LOG_FILE_KEY = 'sent-email-log';
10
+ export const SENT_EMAIL_LOG_PATH = ['utils', 'email'];
11
+ export const SENT_EMAIL_LOG_FILE_NAME = 'sent-email-log';
12
+ /** Provider send-email nodes: `email-resend`, `email-sendgrid`, … */
13
+ export const EMAIL_NODE_TYPE_PREFIX = 'email-';
14
+ /**
15
+ * Integration nodes that can send mail among other actions. Only their
16
+ * `send-email` action is recorded; the wrapper checks the resolved config.
17
+ */
18
+ export const EMAIL_CAPABLE_INTEGRATION_NODE_TYPES = new Set([
19
+ 'integration-gmail',
20
+ 'integration-outlook',
21
+ ]);
22
+ export const isEmailSendingNodeType = (nodeType) => nodeType.startsWith(EMAIL_NODE_TYPE_PREFIX) || EMAIL_CAPABLE_INTEGRATION_NODE_TYPES.has(nodeType);
23
+ export const hasEmailSendingNodeType = (nodeTypes) => {
24
+ for (const nodeType of nodeTypes) {
25
+ if (isEmailSendingNodeType(nodeType)) {
26
+ return true;
27
+ }
28
+ }
29
+ return false;
30
+ };
31
+ //# sourceMappingURL=sent-email-log-scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sent-email-log-scope.js","sourceRoot":"","sources":["../../../src/sent-email-log/sent-email-log-scope.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,CAAC,MAAM,uBAAuB,GAAG,gBAAgB,CAAA;AACvD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;AACrD,MAAM,CAAC,MAAM,wBAAwB,GAAG,gBAAgB,CAAA;AAExD,qEAAqE;AACrE,MAAM,CAAC,MAAM,sBAAsB,GAAG,QAAQ,CAAA;AAE9C;;;GAGG;AACH,MAAM,CAAC,MAAM,oCAAoC,GAAG,IAAI,GAAG,CAAC;IAC1D,mBAAmB;IACnB,qBAAqB;CACtB,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,QAAgB,EAAW,EAAE,CAClE,QAAQ,CAAC,UAAU,CAAC,sBAAsB,CAAC,IAAI,oCAAoC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;AAEnG,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,SAA2B,EAAW,EAAE;IAC9E,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE;QAChC,IAAI,sBAAsB,CAAC,QAAQ,CAAC,EAAE;YACpC,OAAO,IAAI,CAAA;SACZ;KACF;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA"}
@@ -1,6 +1,44 @@
1
+ /**
2
+ * Shared building blocks for generated server routes that send a transactional
3
+ * email (account-delete farewell, account-signup welcome). Keeps the provider
4
+ * dispatch, template filler, dependency map, and config-key list in ONE place so
5
+ * every route stays byte-for-byte consistent.
6
+ */
7
+ import { UIDLLocalizedEmailTemplates } from '@teleporthq/teleport-types';
1
8
  export declare const SUPPORTED_EMAIL_PROVIDERS: Set<string>;
2
9
  export declare const transactionalEmailDependencies: (provider?: string | null) => Record<string, string>;
3
- export declare const generateProviderSendFunction: (provider?: string | null) => string;
10
+ /**
11
+ * Where a transactional route's sends are recorded in the sent-email ledger:
12
+ * the purpose slug, the `source` column and the route file, plus the require
13
+ * prefix from the route's directory back to the project root.
14
+ */
15
+ export interface TransactionalEmailLedger {
16
+ emailType: string;
17
+ source: string;
18
+ sourceRef: string;
19
+ relativePrefix: string;
20
+ }
21
+ export declare const generateProviderSendFunction: (provider?: string | null, ledger?: TransactionalEmailLedger) => string;
4
22
  export declare const generateFillTemplateFn: () => string;
23
+ /**
24
+ * The per-language copies of a transactional route's email, as the UIDL mapper
25
+ * wrote them on the node config. Anything that is not a locale→copy map is
26
+ * treated as "no copies", so a hand-edited config can never break the route.
27
+ */
28
+ export declare const readLocalizedEmailTemplates: (value: unknown) => UIDLLocalizedEmailTemplates;
29
+ /** The `require` of the shared locale module from a route `relativePrefix` deep. */
30
+ export declare const generateEmailLocaleRequire: (relativePrefix: string) => string;
31
+ /**
32
+ * Emits `function <fnName>(locale)` returning `{ subject, body, locale }` — the
33
+ * copy of the route's email for the language a request came from, read from
34
+ * the baked constants. The default language and any language without a copy
35
+ * fall back to the base subject/body.
36
+ */
37
+ export declare const generateLocalizedEmailCopyFn: (params: {
38
+ fnName: string;
39
+ subjectConst: string;
40
+ bodyConst: string;
41
+ localizedConst: string;
42
+ }) => string;
5
43
  export declare const WELCOME_EMAIL_CONFIG_KEYS: string[];
6
44
  //# sourceMappingURL=transactional-email-code.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"transactional-email-code.d.ts","sourceRoot":"","sources":["../../src/transactional-email-code.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,yBAAyB,aAMpC,CAAA;AAIF,eAAO,MAAM,8BAA8B,cAC9B,MAAM,GAAG,IAAI,KACvB,OAAO,MAAM,EAAE,MAAM,CAKvB,CAAA;AAKD,eAAO,MAAM,4BAA4B,cAAe,MAAM,GAAG,IAAI,KAAG,MAmDvE,CAAA;AAID,eAAO,MAAM,sBAAsB,QAAO,MASxC,CAAA;AAKF,eAAO,MAAM,yBAAyB,UAYrC,CAAA"}
1
+ {"version":3,"file":"transactional-email-code.d.ts","sourceRoot":"","sources":["../../src/transactional-email-code.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAA;AAIxE,eAAO,MAAM,yBAAyB,aAMpC,CAAA;AAIF,eAAO,MAAM,8BAA8B,cAC9B,MAAM,GAAG,IAAI,KACvB,OAAO,MAAM,EAAE,MAAM,CAKvB,CAAA;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,MAAM,CAAA;CACvB;AAQD,eAAO,MAAM,4BAA4B,cAC5B,MAAM,GAAG,IAAI,WACf,wBAAwB,KAChC,MAqCF,CAAA;AAyDD,eAAO,MAAM,sBAAsB,QAAO,MASxC,CAAA;AAEF;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,UAAW,OAAO,KAAG,2BAgB5D,CAAA;AAED,oFAAoF;AACpF,eAAO,MAAM,0BAA0B,mBAAoB,MAAM,KAAG,MAGlC,CAAA;AAElC;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,WAAY;IACnD,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,MAAM,CAAA;CACvB,KAAG,MAMF,CAAA;AAKF,eAAO,MAAM,yBAAyB,UAarC,CAAA"}
@@ -1,10 +1,5 @@
1
- /**
2
- * Shared building blocks for generated server routes that send a transactional
3
- * email (account-delete farewell, account-signup welcome). Keeps the provider
4
- * dispatch, template filler, dependency map, and config-key list in ONE place so
5
- * every route stays byte-for-byte consistent.
6
- */
7
1
  import { getEmailProviderDependencies } from './invoice/email-sender-code';
2
+ import { EMAIL_LOCALE_FILE_NAME, EMAIL_LOCALE_PATH } from './email-locale/email-locale-scope';
8
3
  export const SUPPORTED_EMAIL_PROVIDERS = new Set([
9
4
  'resend',
10
5
  'sendgrid',
@@ -20,10 +15,48 @@ export const transactionalEmailDependencies = (provider) => {
20
15
  }
21
16
  return getEmailProviderDependencies(provider);
22
17
  };
23
- // Provider-specific `__sendProviderEmail({ from, to, subject, html, apiKey })`.
24
- // No attachment (unlike the invoice sender). When no provider is configured the
25
- // function is a no-op so the route stays self-contained and never throws.
26
- export const generateProviderSendFunction = (provider) => {
18
+ // Provider-specific `__sendProviderEmail({ from, to, subject, html, apiKey,
19
+ // tokenValues?, userId? })`. No attachment (unlike the invoice sender). When
20
+ // no provider is configured the function is a no-op so the route stays
21
+ // self-contained and never throws. With `ledger`, the provider function is
22
+ // emitted as `__sendProviderEmailRaw` and `__sendProviderEmail` records every
23
+ // attempt (success or throw) before returning / rethrowing.
24
+ export const generateProviderSendFunction = (provider, ledger) => {
25
+ const raw = generateRawProviderSendFunction(provider);
26
+ if (!ledger || !provider || !SUPPORTED_EMAIL_PROVIDERS.has(provider)) {
27
+ return raw;
28
+ }
29
+ return `${raw.replace('async function __sendProviderEmail(', 'async function __sendProviderEmailRaw(')}
30
+
31
+ var __sentEmailLog = require('${ledger.relativePrefix}/utils/email/sent-email-log');
32
+
33
+ async function __sendProviderEmail(msg) {
34
+ var failure = null;
35
+ try {
36
+ await __sendProviderEmailRaw(msg);
37
+ } catch (err) {
38
+ failure = err;
39
+ }
40
+ // Recorded in the background; the route settles the ledger before it replies.
41
+ __sentEmailLog.recordSentEmail({
42
+ emailType: ${JSON.stringify(ledger.emailType)},
43
+ audience: 'customer',
44
+ to: msg.to,
45
+ from: msg.from,
46
+ subject: msg.subject,
47
+ html: msg.html,
48
+ payload: msg.tokenValues,
49
+ provider: ${JSON.stringify(provider)},
50
+ status: failure ? 'failed' : 'sent',
51
+ error: failure ? (failure.message || String(failure)) : null,
52
+ source: ${JSON.stringify(ledger.source)},
53
+ sourceRef: ${JSON.stringify(ledger.sourceRef)},
54
+ userId: msg.userId,
55
+ });
56
+ if (failure) { throw failure; }
57
+ }`;
58
+ };
59
+ const generateRawProviderSendFunction = (provider) => {
27
60
  switch (provider) {
28
61
  case 'resend':
29
62
  return `async function __sendProviderEmail(msg) {
@@ -87,6 +120,43 @@ export const generateFillTemplateFn = () => `function fillTemplate(str, values)
87
120
  }
88
121
  return out;
89
122
  }`;
123
+ /**
124
+ * The per-language copies of a transactional route's email, as the UIDL mapper
125
+ * wrote them on the node config. Anything that is not a locale→copy map is
126
+ * treated as "no copies", so a hand-edited config can never break the route.
127
+ */
128
+ export const readLocalizedEmailTemplates = (value) => {
129
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
130
+ return {};
131
+ }
132
+ const copies = {};
133
+ for (const [locale, copy] of Object.entries(value)) {
134
+ if (!copy || typeof copy !== 'object') {
135
+ continue;
136
+ }
137
+ const { body, subject } = copy;
138
+ if (typeof body !== 'string' || !body) {
139
+ continue;
140
+ }
141
+ copies[locale] = typeof subject === 'string' && subject ? { body, subject } : { body };
142
+ }
143
+ return copies;
144
+ };
145
+ /** The `require` of the shared locale module from a route `relativePrefix` deep. */
146
+ export const generateEmailLocaleRequire = (relativePrefix) => `var __emailLocale = require('${relativePrefix}/${EMAIL_LOCALE_PATH.join('/')}/${EMAIL_LOCALE_FILE_NAME}');`;
147
+ /**
148
+ * Emits `function <fnName>(locale)` returning `{ subject, body, locale }` — the
149
+ * copy of the route's email for the language a request came from, read from
150
+ * the baked constants. The default language and any language without a copy
151
+ * fall back to the base subject/body.
152
+ */
153
+ export const generateLocalizedEmailCopyFn = (params) => `function ${params.fnName}(locale) {
154
+ return __emailLocale.pickLocalizedTemplate(
155
+ { subject: ${params.subjectConst}, body: ${params.bodyConst} },
156
+ ${params.localizedConst},
157
+ locale
158
+ );
159
+ }`;
90
160
  // The account-signup node's welcome-email config keys. They must NEVER be
91
161
  // forwarded from the client signup handler to /api/auth/signup nor inserted as
92
162
  // user columns (they'd corrupt createUser and leak into the client bundle).
@@ -102,5 +172,6 @@ export const WELCOME_EMAIL_CONFIG_KEYS = [
102
172
  'bodyComponentId',
103
173
  'bodyTemplatePurpose',
104
174
  'templateParams',
175
+ 'localizedTemplates',
105
176
  ];
106
177
  //# sourceMappingURL=transactional-email-code.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transactional-email-code.js","sourceRoot":"","sources":["../../src/transactional-email-code.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAA;AAE1E,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,GAAG,CAAC;IAC/C,QAAQ;IACR,UAAU;IACV,UAAU;IACV,SAAS;IACT,YAAY;CACb,CAAC,CAAA;AAEF,+EAA+E;AAC/E,8BAA8B;AAC9B,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAC5C,QAAwB,EACA,EAAE;IAC1B,IAAI,CAAC,QAAQ,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;QACzD,OAAO,EAAE,CAAA;KACV;IACD,OAAO,4BAA4B,CAAC,QAAQ,CAAC,CAAA;AAC/C,CAAC,CAAA;AAED,gFAAgF;AAChF,gFAAgF;AAChF,0EAA0E;AAC1E,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,QAAwB,EAAU,EAAE;IAC/E,QAAQ,QAAQ,EAAE;QAChB,KAAK,QAAQ;YACX,OAAO;;;;;EAKX,CAAA;QACE,KAAK,UAAU;YACb,OAAO;;;;EAIX,CAAA;QACE,KAAK,UAAU;YACb,OAAO;;;;EAIX,CAAA;QACE,KAAK,SAAS;YACZ,OAAO;;;;;;;;EAQX,CAAA;QACE,KAAK,YAAY;YACf,OAAO;;;;;;;;;;;;;EAaX,CAAA;QACE;YACE,OAAO;;EAEX,CAAA;KACC;AACH,CAAC,CAAA;AAED,iFAAiF;AACjF,0CAA0C;AAC1C,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAW,EAAE,CAAC;;;;;;;;;EASlD,CAAA;AAEF,0EAA0E;AAC1E,+EAA+E;AAC/E,4EAA4E;AAC5E,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,eAAe;IACf,MAAM;IACN,UAAU;IACV,QAAQ;IACR,aAAa;IACb,SAAS;IACT,MAAM;IACN,YAAY;IACZ,iBAAiB;IACjB,qBAAqB;IACrB,gBAAgB;CACjB,CAAA"}
1
+ {"version":3,"file":"transactional-email-code.js","sourceRoot":"","sources":["../../src/transactional-email-code.ts"],"names":[],"mappings":"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"}