@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,30 @@
1
+ import { EmailLocaleConfig, generateEmailLocaleModuleCode } from '../../src/email-locale'
2
+ import { WORKFLOW_UTILS_ALIAS } from '../../src/workflow-utils-alias'
3
+
4
+ // A node handler evaluated on its own has no generated file around it to bind
5
+ // `__workflowUtils` (see workflow-utils-alias.ts), so a test that RUNS such a
6
+ // handler binds it here — to the real generated locale helpers, so the
7
+ // behaviour under test is the one a generated project ships.
8
+
9
+ export const TEST_LOCALES: EmailLocaleConfig = { locales: ['en', 'es'], defaultLocale: 'en' }
10
+
11
+ export const loadEmailLocaleModule = (
12
+ config: EmailLocaleConfig = TEST_LOCALES
13
+ ): Record<string, unknown> => {
14
+ const moduleShim = { exports: {} as Record<string, unknown> }
15
+ // eslint-disable-next-line no-new-func
16
+ new Function('module', 'exports', generateEmailLocaleModuleCode(config))(
17
+ moduleShim,
18
+ moduleShim.exports
19
+ )
20
+ return moduleShim.exports
21
+ }
22
+
23
+ /** Binds the alias on the global scope; returns the function that unbinds it. */
24
+ export const bindWorkflowUtils = (config: EmailLocaleConfig = TEST_LOCALES): (() => void) => {
25
+ const globalRef = global as unknown as Record<string, unknown>
26
+ globalRef[WORKFLOW_UTILS_ALIAS] = loadEmailLocaleModule(config)
27
+ return () => {
28
+ delete globalRef[WORKFLOW_UTILS_ALIAS]
29
+ }
30
+ }
@@ -29,6 +29,13 @@ export interface MiddlewareRequestOptions {
29
29
  /** Session user the stubbed `/api/auth/session` returns; omit for a guest. */
30
30
  sessionUser?: MiddlewareSessionUser | null
31
31
  origin?: string
32
+ /**
33
+ * The request's language as Next.js reports it on `nextUrl` — the prefix
34
+ * is already stripped from `pathname`, so pass the bare route. Omit both for
35
+ * a project without internationalization.
36
+ */
37
+ locale?: string
38
+ defaultLocale?: string
32
39
  }
33
40
 
34
41
  interface RawMiddlewareResult {
@@ -113,9 +120,11 @@ export const compileGeneratedMiddleware = (auth: UIDLAuthentication) => {
113
120
 
114
121
  const getTokenStub = async (): Promise<null> => null
115
122
  const middleware = factory(NEXT_RESPONSE_STUB, getTokenStub, fetchImpl)
123
+ const localePrefix =
124
+ options.locale && options.locale !== options.defaultLocale ? `/${options.locale}` : ''
116
125
  const result = await middleware({
117
- nextUrl: { pathname },
118
- url: `${origin}${pathname}`,
126
+ nextUrl: { pathname, locale: options.locale, defaultLocale: options.defaultLocale },
127
+ url: `${origin}${localePrefix}${pathname}`,
119
128
  cookies: {
120
129
  get: (name: string) =>
121
130
  sessionUser && name === 'next-auth.session-token' ? { name, value: 'stub' } : undefined,
@@ -0,0 +1,55 @@
1
+ import { readFileSync } from 'fs'
2
+ import { join } from 'path'
3
+
4
+ // The admin form hydration helpers are emitted verbatim into the generated
5
+ // page from a template literal in the plugin. Pull them out of the source and
6
+ // run them, so what is asserted is what the page runs.
7
+ const pluginSource = readFileSync(join(__dirname, '../src/workflow-component-plugin.ts'), 'utf8')
8
+
9
+ const extractHelper = (name: string): string => {
10
+ const match = pluginSource.match(new RegExp(`function ${name}\\([^)]*\\) \\{[\\s\\S]*?\\n\\}\\n`))
11
+ if (!match) {
12
+ throw new Error(`helper ${name} not found in the plugin source`)
13
+ }
14
+ // Backticks are escaped inside the template literal.
15
+ return match[0].replace(/\\`/g, '`')
16
+ }
17
+
18
+ const helpers = new Function(
19
+ `${extractHelper('__normalizeTagsForFormInput')}\n${extractHelper('__normalizeAdminFormRow')}\n` +
20
+ 'return { normalizeRow: __normalizeAdminFormRow, normalizeTags: __normalizeTagsForFormInput }'
21
+ )() as {
22
+ normalizeRow: (row: unknown, defaults: Record<string, unknown>) => Record<string, unknown>
23
+ normalizeTags: (value: unknown) => string
24
+ }
25
+
26
+ const DEFAULTS = { name: '', tags: '', es_name: '', es_tags: '', zh_tags: '' }
27
+
28
+ describe('__normalizeAdminFormRow', () => {
29
+ it('keeps the per-language columns the form binds', () => {
30
+ const row = { id: 3, name: 'Lamp', es_name: 'Lámpara', color: 'red' }
31
+ expect(helpers.normalizeRow(row, DEFAULTS)).toEqual({
32
+ name: 'Lamp',
33
+ tags: '',
34
+ es_name: 'Lámpara',
35
+ es_tags: '',
36
+ zh_tags: '',
37
+ })
38
+ })
39
+
40
+ it('reshapes a language copy of the tags like the tags themselves', () => {
41
+ const row = { tags: ['light', 'desk'], es_tags: '{"luz","escritorio"}', zh_tags: ['灯'] }
42
+ expect(helpers.normalizeRow(row, DEFAULTS)).toMatchObject({
43
+ tags: 'light, desk',
44
+ es_tags: 'luz, escritorio',
45
+ zh_tags: '灯',
46
+ })
47
+ })
48
+
49
+ it('falls back to the default for a language the row has nothing for', () => {
50
+ expect(helpers.normalizeRow({ name: 'Lamp', es_name: null }, DEFAULTS)).toMatchObject({
51
+ es_name: '',
52
+ es_tags: '',
53
+ })
54
+ })
55
+ })
@@ -1,3 +1,4 @@
1
+ import { RegionalPricing } from '@teleporthq/teleport-shared'
1
2
  import { cartClear } from '../src/nodes/cart/cart-clear'
2
3
 
3
4
  // Regression: after a cash-on-delivery order the buyer's cart came back.
@@ -42,4 +43,15 @@ describe('cart-clear mirrors the empty cart into the database cart', () => {
42
43
  it('stamps the clear so the provider can tell it apart from a first visit', () => {
43
44
  expect(handlerCode).toContain("localStorage.setItem('workflow_cart_cleared_at'")
44
45
  })
46
+
47
+ it('forgets the shipping method picked for the emptied cart', () => {
48
+ // Otherwise the next order silently pre-selects (and charges) a rate the
49
+ // buyer chose for a previous one instead of the cheapest.
50
+ expect(handlerCode).toContain(
51
+ `localStorage.removeItem('${RegionalPricing.SHIPPING_RATE_STORAGE_KEY}')`
52
+ )
53
+ expect(handlerCode).toContain(
54
+ `dispatchEvent(new CustomEvent('${RegionalPricing.SHIPPING_RATE_CHANGED_EVENT}'))`
55
+ )
56
+ })
45
57
  })
@@ -0,0 +1,166 @@
1
+ /* tslint:disable:no-eval */
2
+ import { cartGetTotal } from '../src/nodes/cart/cart-get-total'
3
+ import { resolveHandlerEntryName } from '../src/nodes/types'
4
+
5
+ /**
6
+ * `cart-get-total` is where the place-order workflow's money comes from, so on
7
+ * a store with shipping zones and tax jurisdictions it re-prices the basket AT
8
+ * SUBMIT — for the address on the checkout form at that moment, from the rows
9
+ * the provider displayed — with the same shared rule the provider uses.
10
+ *
11
+ * A store without the feature must come out exactly as before: no `regional`
12
+ * key, and the untouched single-rate fields.
13
+ */
14
+
15
+ function evalHandler(code: string): any {
16
+ return eval('(' + code + ')')
17
+ }
18
+
19
+ const runHandler = async () => evalHandler(cartGetTotal.generateHandler())()
20
+
21
+ function mount(storage: Record<string, unknown>, fields: Record<string, string>): void {
22
+ const store: Record<string, string> = {}
23
+ for (const key of Object.keys(storage)) {
24
+ const value = storage[key]
25
+ store[key] = typeof value === 'string' ? value : JSON.stringify(value)
26
+ }
27
+ ;(global as any).localStorage = {
28
+ getItem: (key: string) => (key in store ? store[key] : null),
29
+ }
30
+ ;(global as any).document = {
31
+ querySelector: (selector: string) => {
32
+ const match = /^\[name="([^"]+)"\]$/.exec(selector)
33
+ const name = match ? match[1] : ''
34
+ return name in fields ? { value: fields[name] } : null
35
+ },
36
+ }
37
+ }
38
+
39
+ afterEach(() => {
40
+ delete (global as any).localStorage
41
+ delete (global as any).document
42
+ })
43
+
44
+ const STORE = {
45
+ deliveryEnabled: true,
46
+ storePickupEnabled: true,
47
+ deliveryPrice: 5,
48
+ freeDeliveryEnabled: false,
49
+ freeDeliveryThreshold: 0,
50
+ defaultTaxRate: 20,
51
+ defaultTaxIncluded: false,
52
+ }
53
+
54
+ const ROWS = {
55
+ zones: [{ id: 'z1', name: 'Germany', countries: 'DE', cod_enabled: 'f', is_active: 't' }],
56
+ rates: [
57
+ { id: 'r1', zone_id: 'z1', name: 'Standard', rate_type: 'flat', price: '10.00' },
58
+ { id: 'r2', zone_id: 'z1', name: 'Express', rate_type: 'flat', price: '20.00', sort_order: 1 },
59
+ ],
60
+ taxRates: [{ id: 't1', country_code: 'DE', rate: '19', tax_mode: 'added', tax_shipping: true }],
61
+ }
62
+
63
+ const CART = [{ id: 'l1', productId: 'p1', price: 100, quantity: 1 }]
64
+
65
+ const settingsWith = (regional: Record<string, unknown> | null) => ({
66
+ maxQuantityPerProduct: null,
67
+ deliveryConfig: { deliveryPrice: 5, freeDeliveryEnabled: false, freeDeliveryThreshold: 0 },
68
+ taxConfig: { storefrontTaxRate: 20 },
69
+ ...(regional ? { regional } : {}),
70
+ })
71
+
72
+ const REGIONAL = {
73
+ store: STORE,
74
+ currency: 'EUR',
75
+ countryCodes: { germany: 'DE', brazil: 'BR' },
76
+ rows: ROWS,
77
+ }
78
+
79
+ describe('cart-get-total — regional pricing', () => {
80
+ it('stays one function expression whose entry point still resolves', () => {
81
+ const source = cartGetTotal.generateHandler()
82
+ expect(source.trim().startsWith('async function cart_get_total()')).toBe(true)
83
+ expect(resolveHandlerEntryName(source, 'cart-get-total')).toBe('cart_get_total')
84
+ })
85
+
86
+ it('adds no regional figures for a store without the feature', async () => {
87
+ mount({ workflow_cart: CART, workflow_cart_settings: settingsWith(null) }, {})
88
+ const out = await runHandler()
89
+ expect(out.regional).toBeUndefined()
90
+ expect(out.tax).toBe(20)
91
+ expect(out.total).toBe(120)
92
+ })
93
+
94
+ it("prices the destination read off the form, with the buyer's chosen rate", async () => {
95
+ mount(
96
+ {
97
+ workflow_cart: CART,
98
+ workflow_cart_settings: settingsWith(REGIONAL),
99
+ workflow_shipping_rate: 'r2',
100
+ },
101
+ { billingCountry: 'Germany', state: '' }
102
+ )
103
+ const out = await runHandler()
104
+ expect(out.subtotal).toBe(100)
105
+ expect(out.tax).toBe(19)
106
+ expect(out.total).toBe(119)
107
+ expect(out.regional).toMatchObject({
108
+ status: 'ok',
109
+ destination: { countryCode: 'DE', countryName: 'Germany' },
110
+ zoneName: 'Germany',
111
+ rateName: 'Express',
112
+ codAvailable: false,
113
+ goodsGross: 119,
114
+ shippingNet: 20,
115
+ shippingTax: 3.8,
116
+ shippingGross: 23.8,
117
+ taxRate: 19,
118
+ lines: [{ key: 'l1', productId: 'p1', unitGross: 119, taxRate: 19 }],
119
+ })
120
+ })
121
+
122
+ it('prices an address no zone lists at the store fee and default rate', async () => {
123
+ mount(
124
+ { workflow_cart: CART, workflow_cart_settings: settingsWith(REGIONAL) },
125
+ { billingCountry: 'Brazil', state: '' }
126
+ )
127
+ const out = await runHandler()
128
+ expect(out.regional).toMatchObject({
129
+ status: 'ok',
130
+ zoneName: '',
131
+ rateName: '',
132
+ codAvailable: true,
133
+ shippingNet: 5,
134
+ shippingGross: 5,
135
+ })
136
+ // Brazil has no tax row: the store default applies.
137
+ expect(out.tax).toBe(20)
138
+ })
139
+
140
+ it('prices the shipping address once its block is on the form', async () => {
141
+ mount(
142
+ { workflow_cart: CART, workflow_cart_settings: settingsWith(REGIONAL) },
143
+ { billingCountry: 'Germany', state: '', shippingCountry: 'Brazil', shippingState: '' }
144
+ )
145
+ const out = await runHandler()
146
+ expect(out.regional).toMatchObject({
147
+ status: 'ok',
148
+ zoneName: '',
149
+ shippingGross: 5,
150
+ destination: { countryCode: 'BR' },
151
+ })
152
+ })
153
+
154
+ it('falls back to the single-rate figures while the rows are still loading', async () => {
155
+ mount(
156
+ {
157
+ workflow_cart: CART,
158
+ workflow_cart_settings: settingsWith({ ...REGIONAL, rows: null }),
159
+ },
160
+ { billingCountry: 'Germany', state: '' }
161
+ )
162
+ const out = await runHandler()
163
+ expect(out.tax).toBe(20)
164
+ expect(out.regional).toMatchObject({ status: 'ok', shippingNet: 5, taxRate: 20 })
165
+ })
166
+ })
@@ -222,3 +222,56 @@ describe('server API route still carries the SQL', () => {
222
222
  expect(route).toContain(DATA_SOURCE_ID)
223
223
  })
224
224
  })
225
+
226
+ describe('route-backed account nodes: the email their route sends never ships to the browser', () => {
227
+ const { redactServerNodeConfig } = require('../src/segment-splitter')
228
+
229
+ const signupConfig = {
230
+ email: { type: 'workflowContext', nodeId: 'form', path: ['form', 'email'] },
231
+ password: { type: 'workflowContext', nodeId: 'form', path: ['form', 'password'] },
232
+ name: 'Jane',
233
+ company: 'Acme',
234
+ emailProvider: 'email-resend',
235
+ apiKey: { type: 'dynamic', content: { referenceType: 'secret', id: 'RESEND_APIKEY' } },
236
+ from: 'hello@example.com',
237
+ subject: 'Welcome {{userName}}',
238
+ body: '<p>SECRET_WELCOME_BODY</p>',
239
+ templateParams: [{ key: 'userName', value: 'Jane' }],
240
+ localizedTemplates: { es: { body: '<p>SECRET_WELCOME_BODY_ES</p>' } },
241
+ }
242
+
243
+ it('keeps the credentials and the user columns of a signup, drops the welcome email', () => {
244
+ const redacted = redactServerNodeConfig(signupConfig, 'client', 'account-signup')
245
+ expect(redacted).toEqual({
246
+ email: signupConfig.email,
247
+ password: signupConfig.password,
248
+ name: 'Jane',
249
+ company: 'Acme',
250
+ })
251
+ })
252
+
253
+ it('keeps what the delete handler reads, drops the farewell email', () => {
254
+ const redacted = redactServerNodeConfig(
255
+ {
256
+ successMessage: 'Bye',
257
+ redirectTo: '/',
258
+ emailProvider: 'email-resend',
259
+ serverToken: 'x',
260
+ domain: 'mg.example.com',
261
+ deletedEmailPattern: 'deleted-{{userId}}@x.invalid',
262
+ subject: 'Goodbye',
263
+ body: '<p>SECRET_FAREWELL</p>',
264
+ localizedTemplates: { es: { body: '<p>SECRET_FAREWELL_ES</p>' } },
265
+ },
266
+ 'client',
267
+ 'account-delete-current'
268
+ )
269
+ expect(redacted).toEqual({ successMessage: 'Bye', redirectTo: '/' })
270
+ })
271
+
272
+ it('leaves every other client node config untouched', () => {
273
+ const config = { message: 'hi', subject: 'kept', body: 'kept' }
274
+ expect(redactServerNodeConfig(config, 'client', 'toast-show')).toBe(config)
275
+ expect(redactServerNodeConfig(config, 'client')).toBe(config)
276
+ })
277
+ })
@@ -0,0 +1,119 @@
1
+ import { generateSharedRuntimeUtilsCode, generateServerSegmentAPIRoute } from '../src'
2
+ import type { WorkflowSegment } from '../src/types'
3
+
4
+ // A node marked `continueOnError` reports a failed RESULT ({ success: false } /
5
+ // { error }) under its id instead of aborting the workflow, so the next
6
+ // if-statement can read `success` and warn. The default is unchanged: a
7
+ // failed result aborts, and so does a handler that throws — with or without
8
+ // the flag, because every provider handler reports failure as a result.
9
+
10
+ interface SharedUtils {
11
+ executeNodes: (
12
+ nodes: unknown[],
13
+ edges: unknown[],
14
+ context: Record<string, unknown>,
15
+ handlers: Record<string, unknown>,
16
+ workflowConfig: unknown,
17
+ callServerSegment: unknown,
18
+ executionId: string
19
+ ) => Promise<void>
20
+ continuesOnError: (node: unknown) => boolean
21
+ }
22
+
23
+ function loadSharedRuntime(): SharedUtils {
24
+ const src = generateSharedRuntimeUtilsCode()
25
+ const wrapper: { exports: Record<string, unknown> } = { exports: {} }
26
+ // eslint-disable-next-line @typescript-eslint/no-implied-eval
27
+ new Function('module', 'exports', src)(wrapper, wrapper.exports)
28
+ return wrapper.exports as unknown as SharedUtils
29
+ }
30
+
31
+ const sendNode = (continueOnError?: boolean) => ({
32
+ id: 'send',
33
+ type: 'email-resend',
34
+ label: 'Send Shipped Email',
35
+ stepNumber: 1,
36
+ config: {
37
+ to: 'jane@example.com',
38
+ ...(continueOnError === undefined ? {} : { continueOnError }),
39
+ },
40
+ })
41
+ const afterNode = { id: 'after', type: 'toast-show', label: 'Toast', stepNumber: 2, config: {} }
42
+ const edges = [{ id: 'e1', source: 'send', target: 'after' }]
43
+
44
+ describe('continuesOnError — classification', () => {
45
+ it('opts in only on an explicit true', () => {
46
+ const utils = loadSharedRuntime()
47
+ expect(utils.continuesOnError(sendNode(true))).toBe(true)
48
+ expect(utils.continuesOnError(sendNode(false))).toBe(false)
49
+ expect(utils.continuesOnError(sendNode())).toBe(false)
50
+ expect(utils.continuesOnError({ id: 'x', type: 'toast-show' })).toBe(false)
51
+ expect(utils.continuesOnError(null)).toBe(false)
52
+ })
53
+ })
54
+
55
+ describe('executeNodes — a refused result on a continueOnError node', () => {
56
+ const refused = { id: '', success: false, error: 'Domain not verified' }
57
+
58
+ it('is published under the node id and the chain goes on', async () => {
59
+ const utils = loadSharedRuntime()
60
+ const ran: string[] = []
61
+ const handlers = {
62
+ 'email-resend': async () => refused,
63
+ 'toast-show': async () => {
64
+ ran.push('toast')
65
+ return { shown: true }
66
+ },
67
+ }
68
+ const context: Record<string, unknown> = {}
69
+ await utils.executeNodes([sendNode(true), afterNode], edges, context, handlers, {}, null, 'x1')
70
+ expect(context.send).toEqual(refused)
71
+ expect(ran).toEqual(['toast'])
72
+ })
73
+
74
+ it('still aborts the chain without the flag', async () => {
75
+ const utils = loadSharedRuntime()
76
+ const ran: string[] = []
77
+ const handlers = {
78
+ 'email-resend': async () => refused,
79
+ 'toast-show': async () => {
80
+ ran.push('toast')
81
+ return { shown: true }
82
+ },
83
+ }
84
+ const context: Record<string, unknown> = {}
85
+ await expect(
86
+ utils.executeNodes([sendNode(), afterNode], edges, context, handlers, {}, null, 'x2')
87
+ ).rejects.toThrow('Domain not verified')
88
+ expect(ran).toEqual([])
89
+ })
90
+
91
+ it('does not swallow a handler that throws', async () => {
92
+ const utils = loadSharedRuntime()
93
+ const handlers = {
94
+ 'email-resend': async () => {
95
+ throw new Error('network down')
96
+ },
97
+ 'toast-show': async () => ({ shown: true }),
98
+ }
99
+ await expect(
100
+ utils.executeNodes([sendNode(true), afterNode], edges, {}, handlers, {}, null, 'x3')
101
+ ).rejects.toThrow('network down')
102
+ })
103
+ })
104
+
105
+ describe('generated server segment route', () => {
106
+ const segment: WorkflowSegment = {
107
+ id: 'server-1',
108
+ env: 'server',
109
+ nodeIds: ['send'],
110
+ nodes: [{ ...sendNode(true), executionEnv: 'server' }],
111
+ edges: [],
112
+ }
113
+ it('gates its fatal-result check on the same predicate', () => {
114
+ const route = generateServerSegmentAPIRoute(segment, 'Send Shipped Email')
115
+ expect(route).toContain(
116
+ 'if (utils.isFatalNodeResult(result) && !utils.continuesOnError(node)) {'
117
+ )
118
+ })
119
+ })