@teleporthq/teleport-plugin-next-workflows 0.44.11 → 0.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (976) hide show
  1. package/__tests__/_helpers/fake-fetch.ts +75 -0
  2. package/__tests__/_helpers/gui-place-order-statements.ts +17 -0
  3. package/__tests__/_helpers/inserted-lines.ts +22 -0
  4. package/__tests__/_helpers/invoice-store.ts +10 -1
  5. package/__tests__/_helpers/load-security-runtime.ts +45 -0
  6. package/__tests__/_helpers/load-server-runtime.ts +26 -3
  7. package/__tests__/_helpers/run-account-delete-route.ts +3 -1
  8. package/__tests__/_helpers/run-generated-middleware.ts +7 -2
  9. package/__tests__/account-delete-owned-rows.test.ts +3 -1
  10. package/__tests__/adopted-element-trigger-code.test.ts +128 -0
  11. package/__tests__/analytics-track-outcome.test.ts +145 -0
  12. package/__tests__/auth-password-change-ends-sessions.test.ts +8 -1
  13. package/__tests__/auth-password-security.test.ts +2275 -0
  14. package/__tests__/auth-session-cost.test.ts +31 -0
  15. package/__tests__/auth-signup-route.test.ts +960 -0
  16. package/__tests__/authored-code-every-path.test.ts +247 -0
  17. package/__tests__/automations-bus.test.ts +3820 -0
  18. package/__tests__/automations-catalog-drift.test.ts +97 -0
  19. package/__tests__/booking-calendar-feed-route.test.ts +20 -3
  20. package/__tests__/cart-price-order.test.ts +336 -1
  21. package/__tests__/code-lookup-rate-limit-route.test.ts +189 -0
  22. package/__tests__/cost-bearing-node-types.test.ts +119 -0
  23. package/__tests__/credential-columns-reply.test.ts +9 -0
  24. package/__tests__/credential-result-reply.test.ts +19 -5
  25. package/__tests__/cron-route-loop-templateparams.test.ts +6 -3
  26. package/__tests__/custom-js-authored-code.test.ts +304 -0
  27. package/__tests__/custom-node-custom-code-gate.test.ts +136 -0
  28. package/__tests__/custom-node-step-handlers.test.ts +251 -0
  29. package/__tests__/custom-node-step-reach.test.ts +63 -0
  30. package/__tests__/data-api-anon-user-id-fallback.test.ts +7 -2
  31. package/__tests__/data-api-browser-reads.test.ts +7 -0
  32. package/__tests__/data-api-business-events.test.ts +403 -0
  33. package/__tests__/data-api-invalid-body.test.ts +7 -0
  34. package/__tests__/data-api-low-stock-autofire.test.ts +30 -4
  35. package/__tests__/data-api-optional-feature-columns.test.ts +44 -0
  36. package/__tests__/data-api-owner-scope-credentials.test.ts +1324 -0
  37. package/__tests__/data-api-protected-tables.test.ts +48 -15
  38. package/__tests__/data-api-retired-table-and-account-fields.test.ts +208 -0
  39. package/__tests__/email-locale-senders.test.ts +5 -3
  40. package/__tests__/expression-injection.test.ts +343 -0
  41. package/__tests__/fixtures/admin-file-workflows.json +242 -0
  42. package/__tests__/form-confirmation-email-template.test.ts +44 -0
  43. package/__tests__/internal-request-headers.test.ts +25 -0
  44. package/__tests__/invoice-pdf-service-project-header.test.ts +120 -0
  45. package/__tests__/invoice-self-call-origin.test.ts +57 -1
  46. package/__tests__/legacy-webhook-self-calls.test.ts +86 -1
  47. package/__tests__/middleware-home-route-protection.test.ts +3 -1
  48. package/__tests__/middleware-subscriber-access.test.ts +1 -1
  49. package/__tests__/newsletter-admin-route.test.ts +649 -0
  50. package/__tests__/newsletter-plugin.test.ts +1248 -0
  51. package/__tests__/outbound-nodes-security.test.ts +1929 -0
  52. package/__tests__/page-access-guard.test.ts +217 -0
  53. package/__tests__/page-access-route-table.test.ts +231 -0
  54. package/__tests__/payment-drivers-module.test.ts +23 -0
  55. package/__tests__/payment-legacy-webhook-routes.test.ts +100 -5
  56. package/__tests__/payment-webhook-route.test.ts +4 -1
  57. package/__tests__/paypal-webhook-signature-verification.test.ts +44 -0
  58. package/__tests__/place-order-guards.test.ts +506 -0
  59. package/__tests__/public-step-guards.test.ts +310 -0
  60. package/__tests__/publish-refusals.test.ts +505 -0
  61. package/__tests__/realtime-identity-routes.test.ts +492 -0
  62. package/__tests__/record-event-writer-server-only.test.ts +975 -0
  63. package/__tests__/resolve-config-template-params.test.ts +3 -3
  64. package/__tests__/runtime-storage-upload-access.test.ts +280 -17
  65. package/__tests__/security-integration-env-names.test.ts +74 -0
  66. package/__tests__/security-lists-parity.test.ts +245 -0
  67. package/__tests__/security-runtime-shadow.test.ts +224 -1
  68. package/__tests__/security-runtime.test.ts +893 -0
  69. package/__tests__/segment-rate-limit-error-branch.test.ts +284 -0
  70. package/__tests__/segment-route-abuse-gate.test.ts +309 -0
  71. package/__tests__/server-job-hops-real-data-api.test.ts +669 -0
  72. package/__tests__/server-session-identity.test.ts +522 -0
  73. package/__tests__/server-step-chain.test.ts +222 -0
  74. package/__tests__/server-step-signing.test.ts +107 -2
  75. package/__tests__/session-cookie-resolver.test.ts +62 -106
  76. package/__tests__/signup-event.test.ts +649 -0
  77. package/__tests__/signup-reply-identical.test.ts +144 -0
  78. package/__tests__/slack-message-escaping.test.ts +123 -0
  79. package/__tests__/visitor-step-limits.test.ts +318 -0
  80. package/__tests__/webhook-delivery-lease.test.ts +4 -1
  81. package/__tests__/webpack-safe-handlers.test.ts +57 -8
  82. package/__tests__/workflow-auth-guard.test.ts +9 -1
  83. package/dist/cjs/account-delete-route-generator.d.ts +1 -0
  84. package/dist/cjs/account-delete-route-generator.d.ts.map +1 -1
  85. package/dist/cjs/account-delete-route-generator.js +18 -3
  86. package/dist/cjs/account-delete-route-generator.js.map +1 -1
  87. package/dist/cjs/api-route-generator.d.ts +52 -3
  88. package/dist/cjs/api-route-generator.d.ts.map +1 -1
  89. package/dist/cjs/api-route-generator.js +600 -145
  90. package/dist/cjs/api-route-generator.js.map +1 -1
  91. package/dist/cjs/auth-generator.d.ts +126 -3
  92. package/dist/cjs/auth-generator.d.ts.map +1 -1
  93. package/dist/cjs/auth-generator.js +1353 -139
  94. package/dist/cjs/auth-generator.js.map +1 -1
  95. package/dist/cjs/automations/activity-kicks.d.ts +12 -0
  96. package/dist/cjs/automations/activity-kicks.d.ts.map +1 -0
  97. package/dist/cjs/automations/activity-kicks.js +123 -0
  98. package/dist/cjs/automations/activity-kicks.js.map +1 -0
  99. package/dist/cjs/automations/app-events-source.d.ts +33 -0
  100. package/dist/cjs/automations/app-events-source.d.ts.map +1 -0
  101. package/dist/cjs/automations/app-events-source.js +109 -0
  102. package/dist/cjs/automations/app-events-source.js.map +1 -0
  103. package/dist/cjs/automations/automations-project-plugin.d.ts +21 -0
  104. package/dist/cjs/automations/automations-project-plugin.d.ts.map +1 -0
  105. package/dist/cjs/automations/automations-project-plugin.js +102 -0
  106. package/dist/cjs/automations/automations-project-plugin.js.map +1 -0
  107. package/dist/cjs/automations/automations-scope.d.ts +104 -0
  108. package/dist/cjs/automations/automations-scope.d.ts.map +1 -0
  109. package/dist/cjs/automations/automations-scope.js +176 -0
  110. package/dist/cjs/automations/automations-scope.js.map +1 -0
  111. package/dist/cjs/automations/dispatcher-source.d.ts +72 -0
  112. package/dist/cjs/automations/dispatcher-source.d.ts.map +1 -0
  113. package/dist/cjs/automations/dispatcher-source.js +1008 -0
  114. package/dist/cjs/automations/dispatcher-source.js.map +1 -0
  115. package/dist/cjs/automations/event-bus-source.d.ts +44 -0
  116. package/dist/cjs/automations/event-bus-source.d.ts.map +1 -0
  117. package/dist/cjs/automations/event-bus-source.js +427 -0
  118. package/dist/cjs/automations/event-bus-source.js.map +1 -0
  119. package/dist/cjs/automations/handler-module-generator.d.ts +25 -0
  120. package/dist/cjs/automations/handler-module-generator.d.ts.map +1 -0
  121. package/dist/cjs/automations/handler-module-generator.js +78 -0
  122. package/dist/cjs/automations/handler-module-generator.js.map +1 -0
  123. package/dist/cjs/automations/hydrators-source.d.ts +33 -0
  124. package/dist/cjs/automations/hydrators-source.d.ts.map +1 -0
  125. package/dist/cjs/automations/hydrators-source.js +571 -0
  126. package/dist/cjs/automations/hydrators-source.js.map +1 -0
  127. package/dist/cjs/booking-calendar-feed-route-generator.d.ts.map +1 -1
  128. package/dist/cjs/booking-calendar-feed-route-generator.js +8 -0
  129. package/dist/cjs/booking-calendar-feed-route-generator.js.map +1 -1
  130. package/dist/cjs/configured-nextauth-url.d.ts +17 -0
  131. package/dist/cjs/configured-nextauth-url.d.ts.map +1 -0
  132. package/dist/cjs/configured-nextauth-url.js +20 -0
  133. package/dist/cjs/configured-nextauth-url.js.map +1 -0
  134. package/dist/cjs/cron-request-verification.d.ts +22 -1
  135. package/dist/cjs/cron-request-verification.d.ts.map +1 -1
  136. package/dist/cjs/cron-request-verification.js +50 -6
  137. package/dist/cjs/cron-request-verification.js.map +1 -1
  138. package/dist/cjs/data-api-route-generator.d.ts +19 -0
  139. package/dist/cjs/data-api-route-generator.d.ts.map +1 -1
  140. package/dist/cjs/data-api-route-generator.js +711 -43
  141. package/dist/cjs/data-api-route-generator.js.map +1 -1
  142. package/dist/cjs/ecommerce/parameterized-stock-chain.d.ts +3 -1
  143. package/dist/cjs/ecommerce/parameterized-stock-chain.d.ts.map +1 -1
  144. package/dist/cjs/ecommerce/parameterized-stock-chain.js +45 -5
  145. package/dist/cjs/ecommerce/parameterized-stock-chain.js.map +1 -1
  146. package/dist/cjs/ecommerce/place-order-guards.d.ts +126 -0
  147. package/dist/cjs/ecommerce/place-order-guards.d.ts.map +1 -0
  148. package/dist/cjs/ecommerce/place-order-guards.js +670 -0
  149. package/dist/cjs/ecommerce/place-order-guards.js.map +1 -0
  150. package/dist/cjs/ecommerce-customhandler-rewriter.d.ts +2 -0
  151. package/dist/cjs/ecommerce-customhandler-rewriter.d.ts.map +1 -1
  152. package/dist/cjs/ecommerce-customhandler-rewriter.js +38 -2
  153. package/dist/cjs/ecommerce-customhandler-rewriter.js.map +1 -1
  154. package/dist/cjs/executor-generator.d.ts.map +1 -1
  155. package/dist/cjs/executor-generator.js +368 -60
  156. package/dist/cjs/executor-generator.js.map +1 -1
  157. package/dist/cjs/graph-utils.d.ts +9 -0
  158. package/dist/cjs/graph-utils.d.ts.map +1 -1
  159. package/dist/cjs/graph-utils.js +32 -1
  160. package/dist/cjs/graph-utils.js.map +1 -1
  161. package/dist/cjs/index.d.ts +20 -1
  162. package/dist/cjs/index.d.ts.map +1 -1
  163. package/dist/cjs/index.js +72 -2
  164. package/dist/cjs/index.js.map +1 -1
  165. package/dist/cjs/invoice/api-routes-code.d.ts +9 -3
  166. package/dist/cjs/invoice/api-routes-code.d.ts.map +1 -1
  167. package/dist/cjs/invoice/api-routes-code.js +9 -7
  168. package/dist/cjs/invoice/api-routes-code.js.map +1 -1
  169. package/dist/cjs/invoice/index.d.ts.map +1 -1
  170. package/dist/cjs/invoice/index.js +12 -7
  171. package/dist/cjs/invoice/index.js.map +1 -1
  172. package/dist/cjs/invoice/invoice-assembly-code.d.ts.map +1 -1
  173. package/dist/cjs/invoice/invoice-assembly-code.js +8 -3
  174. package/dist/cjs/invoice/invoice-assembly-code.js.map +1 -1
  175. package/dist/cjs/invoice/pdf-generator-code.d.ts.map +1 -1
  176. package/dist/cjs/invoice/pdf-generator-code.js +2 -1
  177. package/dist/cjs/invoice/pdf-generator-code.js.map +1 -1
  178. package/dist/cjs/invoice/pdf-service-client-code.d.ts.map +1 -1
  179. package/dist/cjs/invoice/pdf-service-client-code.js +15 -7
  180. package/dist/cjs/invoice/pdf-service-client-code.js.map +1 -1
  181. package/dist/cjs/newsletter/admin-route-code.d.ts +60 -0
  182. package/dist/cjs/newsletter/admin-route-code.d.ts.map +1 -0
  183. package/dist/cjs/newsletter/admin-route-code.js +300 -0
  184. package/dist/cjs/newsletter/admin-route-code.js.map +1 -0
  185. package/dist/cjs/newsletter/helper-code.d.ts +109 -0
  186. package/dist/cjs/newsletter/helper-code.d.ts.map +1 -0
  187. package/dist/cjs/newsletter/helper-code.js +662 -0
  188. package/dist/cjs/newsletter/helper-code.js.map +1 -0
  189. package/dist/cjs/newsletter/newsletter-scope.d.ts +65 -0
  190. package/dist/cjs/newsletter/newsletter-scope.d.ts.map +1 -0
  191. package/dist/cjs/newsletter/newsletter-scope.js +103 -0
  192. package/dist/cjs/newsletter/newsletter-scope.js.map +1 -0
  193. package/dist/cjs/newsletter/project-plugin.d.ts +18 -0
  194. package/dist/cjs/newsletter/project-plugin.d.ts.map +1 -0
  195. package/dist/cjs/newsletter/project-plugin.js +97 -0
  196. package/dist/cjs/newsletter/project-plugin.js.map +1 -0
  197. package/dist/cjs/newsletter/routes-code.d.ts +6 -0
  198. package/dist/cjs/newsletter/routes-code.d.ts.map +1 -0
  199. package/dist/cjs/newsletter/routes-code.js +181 -0
  200. package/dist/cjs/newsletter/routes-code.js.map +1 -0
  201. package/dist/cjs/nodes/account/account-compare-passwords.d.ts.map +1 -1
  202. package/dist/cjs/nodes/account/account-compare-passwords.js +16 -6
  203. package/dist/cjs/nodes/account/account-compare-passwords.js.map +1 -1
  204. package/dist/cjs/nodes/account/account-delete-current.js +1 -1
  205. package/dist/cjs/nodes/account/account-get-current.js +1 -1
  206. package/dist/cjs/nodes/account/account-hash-password.d.ts.map +1 -1
  207. package/dist/cjs/nodes/account/account-hash-password.js +15 -3
  208. package/dist/cjs/nodes/account/account-hash-password.js.map +1 -1
  209. package/dist/cjs/nodes/account/account-login.d.ts.map +1 -1
  210. package/dist/cjs/nodes/account/account-login.js +23 -6
  211. package/dist/cjs/nodes/account/account-login.js.map +1 -1
  212. package/dist/cjs/nodes/account/account-logout.js +1 -1
  213. package/dist/cjs/nodes/account/account-refresh-session.js +1 -1
  214. package/dist/cjs/nodes/account/account-request-password-reset.d.ts +3 -0
  215. package/dist/cjs/nodes/account/account-request-password-reset.d.ts.map +1 -0
  216. package/dist/cjs/nodes/account/account-request-password-reset.js +46 -0
  217. package/dist/cjs/nodes/account/account-request-password-reset.js.map +1 -0
  218. package/dist/cjs/nodes/account/account-reset-password.d.ts +3 -0
  219. package/dist/cjs/nodes/account/account-reset-password.d.ts.map +1 -0
  220. package/dist/cjs/nodes/account/account-reset-password.js +44 -0
  221. package/dist/cjs/nodes/account/account-reset-password.js.map +1 -0
  222. package/dist/cjs/nodes/account/account-signup.d.ts.map +1 -1
  223. package/dist/cjs/nodes/account/account-signup.js +82 -19
  224. package/dist/cjs/nodes/account/account-signup.js.map +1 -1
  225. package/dist/cjs/nodes/account/account-social-login.js +1 -1
  226. package/dist/cjs/nodes/ai/ai-custom-prompt.d.ts.map +1 -1
  227. package/dist/cjs/nodes/ai/ai-custom-prompt.js +20 -5
  228. package/dist/cjs/nodes/ai/ai-custom-prompt.js.map +1 -1
  229. package/dist/cjs/nodes/ai/ai-detect-language.d.ts.map +1 -1
  230. package/dist/cjs/nodes/ai/ai-detect-language.js +20 -5
  231. package/dist/cjs/nodes/ai/ai-detect-language.js.map +1 -1
  232. package/dist/cjs/nodes/ai/ai-generate-text-embedding.d.ts.map +1 -1
  233. package/dist/cjs/nodes/ai/ai-generate-text-embedding.js +10 -2
  234. package/dist/cjs/nodes/ai/ai-generate-text-embedding.js.map +1 -1
  235. package/dist/cjs/nodes/ai/ai-provider-utils-sources.generated.js +2 -2
  236. package/dist/cjs/nodes/ai/ai-provider-utils-sources.generated.js.map +1 -1
  237. package/dist/cjs/nodes/ai/ai-provider-utils.d.ts +31 -2
  238. package/dist/cjs/nodes/ai/ai-provider-utils.d.ts.map +1 -1
  239. package/dist/cjs/nodes/ai/ai-provider-utils.js +125 -11
  240. package/dist/cjs/nodes/ai/ai-provider-utils.js.map +1 -1
  241. package/dist/cjs/nodes/ai/ai-select-database-data.d.ts.map +1 -1
  242. package/dist/cjs/nodes/ai/ai-select-database-data.js +6 -2
  243. package/dist/cjs/nodes/ai/ai-select-database-data.js.map +1 -1
  244. package/dist/cjs/nodes/ai/ai-sentiment-analysis.d.ts.map +1 -1
  245. package/dist/cjs/nodes/ai/ai-sentiment-analysis.js +20 -5
  246. package/dist/cjs/nodes/ai/ai-sentiment-analysis.js.map +1 -1
  247. package/dist/cjs/nodes/ai/ai-summarization.d.ts.map +1 -1
  248. package/dist/cjs/nodes/ai/ai-summarization.js +20 -5
  249. package/dist/cjs/nodes/ai/ai-summarization.js.map +1 -1
  250. package/dist/cjs/nodes/ai/ai-text-classifier.d.ts.map +1 -1
  251. package/dist/cjs/nodes/ai/ai-text-classifier.js +20 -5
  252. package/dist/cjs/nodes/ai/ai-text-classifier.js.map +1 -1
  253. package/dist/cjs/nodes/ai/ai-text-transform.d.ts.map +1 -1
  254. package/dist/cjs/nodes/ai/ai-text-transform.js +20 -5
  255. package/dist/cjs/nodes/ai/ai-text-transform.js.map +1 -1
  256. package/dist/cjs/nodes/analytics/analytics-track-outcome.d.ts +3 -0
  257. package/dist/cjs/nodes/analytics/analytics-track-outcome.d.ts.map +1 -0
  258. package/dist/cjs/nodes/analytics/analytics-track-outcome.js +110 -0
  259. package/dist/cjs/nodes/analytics/analytics-track-outcome.js.map +1 -0
  260. package/dist/cjs/nodes/cart/cart-price-order.d.ts.map +1 -1
  261. package/dist/cjs/nodes/cart/cart-price-order.js +161 -2
  262. package/dist/cjs/nodes/cart/cart-price-order.js.map +1 -1
  263. package/dist/cjs/nodes/cost-bearing-node-types.d.ts +4 -0
  264. package/dist/cjs/nodes/cost-bearing-node-types.d.ts.map +1 -0
  265. package/dist/cjs/nodes/cost-bearing-node-types.js +43 -0
  266. package/dist/cjs/nodes/cost-bearing-node-types.js.map +1 -0
  267. package/dist/cjs/nodes/data/data-select.d.ts.map +1 -1
  268. package/dist/cjs/nodes/data/data-select.js +12 -2
  269. package/dist/cjs/nodes/data/data-select.js.map +1 -1
  270. package/dist/cjs/nodes/email/email-mailersend.d.ts.map +1 -1
  271. package/dist/cjs/nodes/email/email-mailersend.js +15 -11
  272. package/dist/cjs/nodes/email/email-mailersend.js.map +1 -1
  273. package/dist/cjs/nodes/email/email-mailgun.d.ts.map +1 -1
  274. package/dist/cjs/nodes/email/email-mailgun.js +15 -15
  275. package/dist/cjs/nodes/email/email-mailgun.js.map +1 -1
  276. package/dist/cjs/nodes/email/email-postmark.d.ts.map +1 -1
  277. package/dist/cjs/nodes/email/email-postmark.js +15 -15
  278. package/dist/cjs/nodes/email/email-postmark.js.map +1 -1
  279. package/dist/cjs/nodes/email/email-resend.d.ts.map +1 -1
  280. package/dist/cjs/nodes/email/email-resend.js +15 -15
  281. package/dist/cjs/nodes/email/email-resend.js.map +1 -1
  282. package/dist/cjs/nodes/email/email-sendgrid.d.ts.map +1 -1
  283. package/dist/cjs/nodes/email/email-sendgrid.js +15 -15
  284. package/dist/cjs/nodes/email/email-sendgrid.js.map +1 -1
  285. package/dist/cjs/nodes/email/html-escape-code.d.ts +3 -0
  286. package/dist/cjs/nodes/email/html-escape-code.d.ts.map +1 -0
  287. package/dist/cjs/nodes/email/html-escape-code.js +23 -0
  288. package/dist/cjs/nodes/email/html-escape-code.js.map +1 -0
  289. package/dist/cjs/nodes/email/message-trust.d.ts +40 -0
  290. package/dist/cjs/nodes/email/message-trust.d.ts.map +1 -0
  291. package/dist/cjs/nodes/email/message-trust.js +167 -0
  292. package/dist/cjs/nodes/email/message-trust.js.map +1 -0
  293. package/dist/cjs/nodes/email/outbound-message-guard.d.ts +113 -0
  294. package/dist/cjs/nodes/email/outbound-message-guard.d.ts.map +1 -0
  295. package/dist/cjs/nodes/email/outbound-message-guard.js +460 -0
  296. package/dist/cjs/nodes/email/outbound-message-guard.js.map +1 -0
  297. package/dist/cjs/nodes/email/trusted-html-code.d.ts +22 -0
  298. package/dist/cjs/nodes/email/trusted-html-code.d.ts.map +1 -0
  299. package/dist/cjs/nodes/email/trusted-html-code.js +52 -0
  300. package/dist/cjs/nodes/email/trusted-html-code.js.map +1 -0
  301. package/dist/cjs/nodes/general/general-custom-js.d.ts.map +1 -1
  302. package/dist/cjs/nodes/general/general-custom-js.js +44 -7
  303. package/dist/cjs/nodes/general/general-custom-js.js.map +1 -1
  304. package/dist/cjs/nodes/general/general-http-request.d.ts.map +1 -1
  305. package/dist/cjs/nodes/general/general-http-request.js +431 -45
  306. package/dist/cjs/nodes/general/general-http-request.js.map +1 -1
  307. package/dist/cjs/nodes/general/general-rate-limiter.d.ts.map +1 -1
  308. package/dist/cjs/nodes/general/general-rate-limiter.js +46 -78
  309. package/dist/cjs/nodes/general/general-rate-limiter.js.map +1 -1
  310. package/dist/cjs/nodes/general/general-wait.d.ts +3 -0
  311. package/dist/cjs/nodes/general/general-wait.d.ts.map +1 -0
  312. package/dist/cjs/nodes/general/general-wait.js +81 -0
  313. package/dist/cjs/nodes/general/general-wait.js.map +1 -0
  314. package/dist/cjs/nodes/general/visitor-request.d.ts +44 -0
  315. package/dist/cjs/nodes/general/visitor-request.d.ts.map +1 -0
  316. package/dist/cjs/nodes/general/visitor-request.js +72 -0
  317. package/dist/cjs/nodes/general/visitor-request.js.map +1 -0
  318. package/dist/cjs/nodes/index.d.ts.map +1 -1
  319. package/dist/cjs/nodes/index.js +7 -1
  320. package/dist/cjs/nodes/index.js.map +1 -1
  321. package/dist/cjs/nodes/integrations/integration-slack.d.ts.map +1 -1
  322. package/dist/cjs/nodes/integrations/integration-slack.js +17 -6
  323. package/dist/cjs/nodes/integrations/integration-slack.js.map +1 -1
  324. package/dist/cjs/nodes/newsletter/newsletter-confirm.d.ts +3 -0
  325. package/dist/cjs/nodes/newsletter/newsletter-confirm.d.ts.map +1 -0
  326. package/dist/cjs/nodes/newsletter/newsletter-confirm.js +41 -0
  327. package/dist/cjs/nodes/newsletter/newsletter-confirm.js.map +1 -0
  328. package/dist/cjs/nodes/newsletter/newsletter-subscribe.d.ts +7 -0
  329. package/dist/cjs/nodes/newsletter/newsletter-subscribe.d.ts.map +1 -0
  330. package/dist/cjs/nodes/newsletter/newsletter-subscribe.js +69 -0
  331. package/dist/cjs/nodes/newsletter/newsletter-subscribe.js.map +1 -0
  332. package/dist/cjs/nodes/newsletter/newsletter-unsubscribe.d.ts +3 -0
  333. package/dist/cjs/nodes/newsletter/newsletter-unsubscribe.d.ts.map +1 -0
  334. package/dist/cjs/nodes/newsletter/newsletter-unsubscribe.js +42 -0
  335. package/dist/cjs/nodes/newsletter/newsletter-unsubscribe.js.map +1 -0
  336. package/dist/cjs/nodes/realtime/realtime-join-channel.d.ts.map +1 -1
  337. package/dist/cjs/nodes/realtime/realtime-join-channel.js +5 -4
  338. package/dist/cjs/nodes/realtime/realtime-join-channel.js.map +1 -1
  339. package/dist/cjs/nodes/realtime/realtime-send-channel-event.d.ts.map +1 -1
  340. package/dist/cjs/nodes/realtime/realtime-send-channel-event.js +11 -2
  341. package/dist/cjs/nodes/realtime/realtime-send-channel-event.js.map +1 -1
  342. package/dist/cjs/nodes/realtime/realtime-send-channel-message.d.ts.map +1 -1
  343. package/dist/cjs/nodes/realtime/realtime-send-channel-message.js +11 -2
  344. package/dist/cjs/nodes/realtime/realtime-send-channel-message.js.map +1 -1
  345. package/dist/cjs/nodes/sms/sms-infobip.d.ts.map +1 -1
  346. package/dist/cjs/nodes/sms/sms-infobip.js +11 -8
  347. package/dist/cjs/nodes/sms/sms-infobip.js.map +1 -1
  348. package/dist/cjs/nodes/sms/sms-smsapi.d.ts.map +1 -1
  349. package/dist/cjs/nodes/sms/sms-smsapi.js +11 -8
  350. package/dist/cjs/nodes/sms/sms-smsapi.js.map +1 -1
  351. package/dist/cjs/nodes/sms/sms-textmagic.d.ts.map +1 -1
  352. package/dist/cjs/nodes/sms/sms-textmagic.js +11 -8
  353. package/dist/cjs/nodes/sms/sms-textmagic.js.map +1 -1
  354. package/dist/cjs/nodes/sms/sms-twilio.d.ts.map +1 -1
  355. package/dist/cjs/nodes/sms/sms-twilio.js +12 -10
  356. package/dist/cjs/nodes/sms/sms-twilio.js.map +1 -1
  357. package/dist/cjs/nodes/types.d.ts +8 -1
  358. package/dist/cjs/nodes/types.d.ts.map +1 -1
  359. package/dist/cjs/nodes/utility/utility-similarity-scoring.d.ts.map +1 -1
  360. package/dist/cjs/nodes/utility/utility-similarity-scoring.js +29 -10
  361. package/dist/cjs/nodes/utility/utility-similarity-scoring.js.map +1 -1
  362. package/dist/cjs/page-access-guard-generator.d.ts +23 -0
  363. package/dist/cjs/page-access-guard-generator.d.ts.map +1 -0
  364. package/dist/cjs/page-access-guard-generator.js +135 -0
  365. package/dist/cjs/page-access-guard-generator.js.map +1 -0
  366. package/dist/cjs/password-reset-route-generator.d.ts +119 -0
  367. package/dist/cjs/password-reset-route-generator.d.ts.map +1 -0
  368. package/dist/cjs/password-reset-route-generator.js +460 -0
  369. package/dist/cjs/password-reset-route-generator.js.map +1 -0
  370. package/dist/cjs/payments/payment-core-code.d.ts.map +1 -1
  371. package/dist/cjs/payments/payment-core-code.js +12 -7
  372. package/dist/cjs/payments/payment-core-code.js.map +1 -1
  373. package/dist/cjs/project-code-scanner.d.ts +11 -0
  374. package/dist/cjs/project-code-scanner.d.ts.map +1 -0
  375. package/dist/cjs/project-code-scanner.js +80 -0
  376. package/dist/cjs/project-code-scanner.js.map +1 -0
  377. package/dist/cjs/public-step-guards.d.ts +122 -0
  378. package/dist/cjs/public-step-guards.d.ts.map +1 -0
  379. package/dist/cjs/public-step-guards.js +288 -0
  380. package/dist/cjs/public-step-guards.js.map +1 -0
  381. package/dist/cjs/publish-refusals.d.ts +66 -0
  382. package/dist/cjs/publish-refusals.d.ts.map +1 -0
  383. package/dist/cjs/publish-refusals.js +278 -0
  384. package/dist/cjs/publish-refusals.js.map +1 -0
  385. package/dist/cjs/realtime-generator.d.ts +63 -1
  386. package/dist/cjs/realtime-generator.d.ts.map +1 -1
  387. package/dist/cjs/realtime-generator.js +404 -230
  388. package/dist/cjs/realtime-generator.js.map +1 -1
  389. package/dist/cjs/runtime-storage-generator.d.ts +32 -1
  390. package/dist/cjs/runtime-storage-generator.d.ts.map +1 -1
  391. package/dist/cjs/runtime-storage-generator.js +265 -12
  392. package/dist/cjs/runtime-storage-generator.js.map +1 -1
  393. package/dist/cjs/security-runtime/index.d.ts +14 -0
  394. package/dist/cjs/security-runtime/index.d.ts.map +1 -0
  395. package/dist/cjs/security-runtime/index.js +48 -0
  396. package/dist/cjs/security-runtime/index.js.map +1 -0
  397. package/dist/cjs/security-runtime/security-runtime-code.d.ts +53 -0
  398. package/dist/cjs/security-runtime/security-runtime-code.d.ts.map +1 -0
  399. package/dist/cjs/security-runtime/security-runtime-code.js +580 -0
  400. package/dist/cjs/security-runtime/security-runtime-code.js.map +1 -0
  401. package/dist/cjs/security-scanner.d.ts +72 -3
  402. package/dist/cjs/security-scanner.d.ts.map +1 -1
  403. package/dist/cjs/security-scanner.js +220 -8
  404. package/dist/cjs/security-scanner.js.map +1 -1
  405. package/dist/cjs/segment-splitter.d.ts.map +1 -1
  406. package/dist/cjs/segment-splitter.js +10 -2
  407. package/dist/cjs/segment-splitter.js.map +1 -1
  408. package/dist/cjs/segment-trust.d.ts +36 -0
  409. package/dist/cjs/segment-trust.d.ts.map +1 -1
  410. package/dist/cjs/segment-trust.js +147 -3
  411. package/dist/cjs/segment-trust.js.map +1 -1
  412. package/dist/cjs/self-call-headers.d.ts +31 -0
  413. package/dist/cjs/self-call-headers.d.ts.map +1 -0
  414. package/dist/cjs/self-call-headers.js +48 -0
  415. package/dist/cjs/self-call-headers.js.map +1 -0
  416. package/dist/cjs/sent-email-log/index.d.ts +7 -0
  417. package/dist/cjs/sent-email-log/index.d.ts.map +1 -1
  418. package/dist/cjs/sent-email-log/index.js +17 -1
  419. package/dist/cjs/sent-email-log/index.js.map +1 -1
  420. package/dist/cjs/sent-email-log/sent-email-log-code.d.ts +7 -0
  421. package/dist/cjs/sent-email-log/sent-email-log-code.d.ts.map +1 -1
  422. package/dist/cjs/sent-email-log/sent-email-log-code.js +17 -3
  423. package/dist/cjs/sent-email-log/sent-email-log-code.js.map +1 -1
  424. package/dist/cjs/server-custom-node-call.d.ts +79 -0
  425. package/dist/cjs/server-custom-node-call.d.ts.map +1 -0
  426. package/dist/cjs/server-custom-node-call.js +285 -0
  427. package/dist/cjs/server-custom-node-call.js.map +1 -0
  428. package/dist/cjs/server-runtime-code.d.ts +39 -12
  429. package/dist/cjs/server-runtime-code.d.ts.map +1 -1
  430. package/dist/cjs/server-runtime-code.js +484 -41
  431. package/dist/cjs/server-runtime-code.js.map +1 -1
  432. package/dist/cjs/session-cookie-resolver.d.ts +3 -1
  433. package/dist/cjs/session-cookie-resolver.d.ts.map +1 -1
  434. package/dist/cjs/session-revocation-generator.d.ts +39 -0
  435. package/dist/cjs/session-revocation-generator.d.ts.map +1 -0
  436. package/dist/cjs/session-revocation-generator.js +177 -0
  437. package/dist/cjs/session-revocation-generator.js.map +1 -0
  438. package/dist/cjs/slack-message-values.d.ts +6 -0
  439. package/dist/cjs/slack-message-values.d.ts.map +1 -0
  440. package/dist/cjs/slack-message-values.js +73 -0
  441. package/dist/cjs/slack-message-values.js.map +1 -0
  442. package/dist/cjs/transactional-email-code.d.ts +11 -0
  443. package/dist/cjs/transactional-email-code.d.ts.map +1 -1
  444. package/dist/cjs/transactional-email-code.js +29 -5
  445. package/dist/cjs/transactional-email-code.js.map +1 -1
  446. package/dist/cjs/trigger-generator.d.ts +2 -0
  447. package/dist/cjs/trigger-generator.d.ts.map +1 -1
  448. package/dist/cjs/trigger-generator.js +17 -4
  449. package/dist/cjs/trigger-generator.js.map +1 -1
  450. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  451. package/dist/cjs/visitor-step-limits.d.ts +66 -0
  452. package/dist/cjs/visitor-step-limits.d.ts.map +1 -0
  453. package/dist/cjs/visitor-step-limits.js +187 -0
  454. package/dist/cjs/visitor-step-limits.js.map +1 -0
  455. package/dist/cjs/webhook-generator.d.ts.map +1 -1
  456. package/dist/cjs/webhook-generator.js +93 -15
  457. package/dist/cjs/webhook-generator.js.map +1 -1
  458. package/dist/cjs/webhook-signature-verification.d.ts.map +1 -1
  459. package/dist/cjs/webhook-signature-verification.js +13 -3
  460. package/dist/cjs/webhook-signature-verification.js.map +1 -1
  461. package/dist/cjs/workflow-auth-generator.d.ts +4 -1
  462. package/dist/cjs/workflow-auth-generator.d.ts.map +1 -1
  463. package/dist/cjs/workflow-auth-generator.js +8 -3
  464. package/dist/cjs/workflow-auth-generator.js.map +1 -1
  465. package/dist/cjs/workflow-component-plugin.js +11 -3
  466. package/dist/cjs/workflow-component-plugin.js.map +1 -1
  467. package/dist/cjs/workflow-project-plugin.d.ts.map +1 -1
  468. package/dist/cjs/workflow-project-plugin.js +302 -56
  469. package/dist/cjs/workflow-project-plugin.js.map +1 -1
  470. package/dist/cjs/workflow-scope.d.ts.map +1 -1
  471. package/dist/cjs/workflow-scope.js +5 -0
  472. package/dist/cjs/workflow-scope.js.map +1 -1
  473. package/dist/esm/account-delete-route-generator.d.ts +1 -0
  474. package/dist/esm/account-delete-route-generator.d.ts.map +1 -1
  475. package/dist/esm/account-delete-route-generator.js +18 -3
  476. package/dist/esm/account-delete-route-generator.js.map +1 -1
  477. package/dist/esm/api-route-generator.d.ts +52 -3
  478. package/dist/esm/api-route-generator.d.ts.map +1 -1
  479. package/dist/esm/api-route-generator.js +595 -142
  480. package/dist/esm/api-route-generator.js.map +1 -1
  481. package/dist/esm/auth-generator.d.ts +126 -3
  482. package/dist/esm/auth-generator.d.ts.map +1 -1
  483. package/dist/esm/auth-generator.js +1350 -140
  484. package/dist/esm/auth-generator.js.map +1 -1
  485. package/dist/esm/automations/activity-kicks.d.ts +12 -0
  486. package/dist/esm/automations/activity-kicks.d.ts.map +1 -0
  487. package/dist/esm/automations/activity-kicks.js +118 -0
  488. package/dist/esm/automations/activity-kicks.js.map +1 -0
  489. package/dist/esm/automations/app-events-source.d.ts +33 -0
  490. package/dist/esm/automations/app-events-source.d.ts.map +1 -0
  491. package/dist/esm/automations/app-events-source.js +104 -0
  492. package/dist/esm/automations/app-events-source.js.map +1 -0
  493. package/dist/esm/automations/automations-project-plugin.d.ts +21 -0
  494. package/dist/esm/automations/automations-project-plugin.d.ts.map +1 -0
  495. package/dist/esm/automations/automations-project-plugin.js +98 -0
  496. package/dist/esm/automations/automations-project-plugin.js.map +1 -0
  497. package/dist/esm/automations/automations-scope.d.ts +104 -0
  498. package/dist/esm/automations/automations-scope.d.ts.map +1 -0
  499. package/dist/esm/automations/automations-scope.js +165 -0
  500. package/dist/esm/automations/automations-scope.js.map +1 -0
  501. package/dist/esm/automations/dispatcher-source.d.ts +72 -0
  502. package/dist/esm/automations/dispatcher-source.d.ts.map +1 -0
  503. package/dist/esm/automations/dispatcher-source.js +999 -0
  504. package/dist/esm/automations/dispatcher-source.js.map +1 -0
  505. package/dist/esm/automations/event-bus-source.d.ts +44 -0
  506. package/dist/esm/automations/event-bus-source.d.ts.map +1 -0
  507. package/dist/esm/automations/event-bus-source.js +421 -0
  508. package/dist/esm/automations/event-bus-source.js.map +1 -0
  509. package/dist/esm/automations/handler-module-generator.d.ts +25 -0
  510. package/dist/esm/automations/handler-module-generator.d.ts.map +1 -0
  511. package/dist/esm/automations/handler-module-generator.js +71 -0
  512. package/dist/esm/automations/handler-module-generator.js.map +1 -0
  513. package/dist/esm/automations/hydrators-source.d.ts +33 -0
  514. package/dist/esm/automations/hydrators-source.d.ts.map +1 -0
  515. package/dist/esm/automations/hydrators-source.js +567 -0
  516. package/dist/esm/automations/hydrators-source.js.map +1 -0
  517. package/dist/esm/booking-calendar-feed-route-generator.d.ts.map +1 -1
  518. package/dist/esm/booking-calendar-feed-route-generator.js +8 -0
  519. package/dist/esm/booking-calendar-feed-route-generator.js.map +1 -1
  520. package/dist/esm/configured-nextauth-url.d.ts +17 -0
  521. package/dist/esm/configured-nextauth-url.d.ts.map +1 -0
  522. package/dist/esm/configured-nextauth-url.js +17 -0
  523. package/dist/esm/configured-nextauth-url.js.map +1 -0
  524. package/dist/esm/cron-request-verification.d.ts +22 -1
  525. package/dist/esm/cron-request-verification.d.ts.map +1 -1
  526. package/dist/esm/cron-request-verification.js +48 -5
  527. package/dist/esm/cron-request-verification.js.map +1 -1
  528. package/dist/esm/data-api-route-generator.d.ts +19 -0
  529. package/dist/esm/data-api-route-generator.d.ts.map +1 -1
  530. package/dist/esm/data-api-route-generator.js +710 -43
  531. package/dist/esm/data-api-route-generator.js.map +1 -1
  532. package/dist/esm/ecommerce/parameterized-stock-chain.d.ts +3 -1
  533. package/dist/esm/ecommerce/parameterized-stock-chain.d.ts.map +1 -1
  534. package/dist/esm/ecommerce/parameterized-stock-chain.js +43 -4
  535. package/dist/esm/ecommerce/parameterized-stock-chain.js.map +1 -1
  536. package/dist/esm/ecommerce/place-order-guards.d.ts +126 -0
  537. package/dist/esm/ecommerce/place-order-guards.d.ts.map +1 -0
  538. package/dist/esm/ecommerce/place-order-guards.js +655 -0
  539. package/dist/esm/ecommerce/place-order-guards.js.map +1 -0
  540. package/dist/esm/ecommerce-customhandler-rewriter.d.ts +2 -0
  541. package/dist/esm/ecommerce-customhandler-rewriter.d.ts.map +1 -1
  542. package/dist/esm/ecommerce-customhandler-rewriter.js +38 -2
  543. package/dist/esm/ecommerce-customhandler-rewriter.js.map +1 -1
  544. package/dist/esm/executor-generator.d.ts.map +1 -1
  545. package/dist/esm/executor-generator.js +368 -60
  546. package/dist/esm/executor-generator.js.map +1 -1
  547. package/dist/esm/graph-utils.d.ts +9 -0
  548. package/dist/esm/graph-utils.d.ts.map +1 -1
  549. package/dist/esm/graph-utils.js +30 -0
  550. package/dist/esm/graph-utils.js.map +1 -1
  551. package/dist/esm/index.d.ts +20 -1
  552. package/dist/esm/index.d.ts.map +1 -1
  553. package/dist/esm/index.js +27 -1
  554. package/dist/esm/index.js.map +1 -1
  555. package/dist/esm/invoice/api-routes-code.d.ts +9 -3
  556. package/dist/esm/invoice/api-routes-code.d.ts.map +1 -1
  557. package/dist/esm/invoice/api-routes-code.js +9 -7
  558. package/dist/esm/invoice/api-routes-code.js.map +1 -1
  559. package/dist/esm/invoice/index.d.ts.map +1 -1
  560. package/dist/esm/invoice/index.js +12 -7
  561. package/dist/esm/invoice/index.js.map +1 -1
  562. package/dist/esm/invoice/invoice-assembly-code.d.ts.map +1 -1
  563. package/dist/esm/invoice/invoice-assembly-code.js +8 -3
  564. package/dist/esm/invoice/invoice-assembly-code.js.map +1 -1
  565. package/dist/esm/invoice/pdf-generator-code.d.ts.map +1 -1
  566. package/dist/esm/invoice/pdf-generator-code.js +2 -1
  567. package/dist/esm/invoice/pdf-generator-code.js.map +1 -1
  568. package/dist/esm/invoice/pdf-service-client-code.d.ts.map +1 -1
  569. package/dist/esm/invoice/pdf-service-client-code.js +15 -7
  570. package/dist/esm/invoice/pdf-service-client-code.js.map +1 -1
  571. package/dist/esm/newsletter/admin-route-code.d.ts +60 -0
  572. package/dist/esm/newsletter/admin-route-code.d.ts.map +1 -0
  573. package/dist/esm/newsletter/admin-route-code.js +295 -0
  574. package/dist/esm/newsletter/admin-route-code.js.map +1 -0
  575. package/dist/esm/newsletter/helper-code.d.ts +109 -0
  576. package/dist/esm/newsletter/helper-code.d.ts.map +1 -0
  577. package/dist/esm/newsletter/helper-code.js +656 -0
  578. package/dist/esm/newsletter/helper-code.js.map +1 -0
  579. package/dist/esm/newsletter/newsletter-scope.d.ts +65 -0
  580. package/dist/esm/newsletter/newsletter-scope.d.ts.map +1 -0
  581. package/dist/esm/newsletter/newsletter-scope.js +97 -0
  582. package/dist/esm/newsletter/newsletter-scope.js.map +1 -0
  583. package/dist/esm/newsletter/project-plugin.d.ts +18 -0
  584. package/dist/esm/newsletter/project-plugin.d.ts.map +1 -0
  585. package/dist/esm/newsletter/project-plugin.js +93 -0
  586. package/dist/esm/newsletter/project-plugin.js.map +1 -0
  587. package/dist/esm/newsletter/routes-code.d.ts +6 -0
  588. package/dist/esm/newsletter/routes-code.d.ts.map +1 -0
  589. package/dist/esm/newsletter/routes-code.js +175 -0
  590. package/dist/esm/newsletter/routes-code.js.map +1 -0
  591. package/dist/esm/nodes/account/account-compare-passwords.d.ts.map +1 -1
  592. package/dist/esm/nodes/account/account-compare-passwords.js +16 -6
  593. package/dist/esm/nodes/account/account-compare-passwords.js.map +1 -1
  594. package/dist/esm/nodes/account/account-delete-current.js +1 -1
  595. package/dist/esm/nodes/account/account-get-current.js +1 -1
  596. package/dist/esm/nodes/account/account-hash-password.d.ts.map +1 -1
  597. package/dist/esm/nodes/account/account-hash-password.js +15 -3
  598. package/dist/esm/nodes/account/account-hash-password.js.map +1 -1
  599. package/dist/esm/nodes/account/account-login.d.ts.map +1 -1
  600. package/dist/esm/nodes/account/account-login.js +23 -6
  601. package/dist/esm/nodes/account/account-login.js.map +1 -1
  602. package/dist/esm/nodes/account/account-logout.js +1 -1
  603. package/dist/esm/nodes/account/account-refresh-session.js +1 -1
  604. package/dist/esm/nodes/account/account-request-password-reset.d.ts +3 -0
  605. package/dist/esm/nodes/account/account-request-password-reset.d.ts.map +1 -0
  606. package/dist/esm/nodes/account/account-request-password-reset.js +43 -0
  607. package/dist/esm/nodes/account/account-request-password-reset.js.map +1 -0
  608. package/dist/esm/nodes/account/account-reset-password.d.ts +3 -0
  609. package/dist/esm/nodes/account/account-reset-password.d.ts.map +1 -0
  610. package/dist/esm/nodes/account/account-reset-password.js +41 -0
  611. package/dist/esm/nodes/account/account-reset-password.js.map +1 -0
  612. package/dist/esm/nodes/account/account-signup.d.ts.map +1 -1
  613. package/dist/esm/nodes/account/account-signup.js +82 -19
  614. package/dist/esm/nodes/account/account-signup.js.map +1 -1
  615. package/dist/esm/nodes/account/account-social-login.js +1 -1
  616. package/dist/esm/nodes/ai/ai-custom-prompt.d.ts.map +1 -1
  617. package/dist/esm/nodes/ai/ai-custom-prompt.js +20 -5
  618. package/dist/esm/nodes/ai/ai-custom-prompt.js.map +1 -1
  619. package/dist/esm/nodes/ai/ai-detect-language.d.ts.map +1 -1
  620. package/dist/esm/nodes/ai/ai-detect-language.js +20 -5
  621. package/dist/esm/nodes/ai/ai-detect-language.js.map +1 -1
  622. package/dist/esm/nodes/ai/ai-generate-text-embedding.d.ts.map +1 -1
  623. package/dist/esm/nodes/ai/ai-generate-text-embedding.js +10 -2
  624. package/dist/esm/nodes/ai/ai-generate-text-embedding.js.map +1 -1
  625. package/dist/esm/nodes/ai/ai-provider-utils-sources.generated.js +2 -2
  626. package/dist/esm/nodes/ai/ai-provider-utils-sources.generated.js.map +1 -1
  627. package/dist/esm/nodes/ai/ai-provider-utils.d.ts +31 -2
  628. package/dist/esm/nodes/ai/ai-provider-utils.d.ts.map +1 -1
  629. package/dist/esm/nodes/ai/ai-provider-utils.js +124 -10
  630. package/dist/esm/nodes/ai/ai-provider-utils.js.map +1 -1
  631. package/dist/esm/nodes/ai/ai-select-database-data.d.ts.map +1 -1
  632. package/dist/esm/nodes/ai/ai-select-database-data.js +6 -2
  633. package/dist/esm/nodes/ai/ai-select-database-data.js.map +1 -1
  634. package/dist/esm/nodes/ai/ai-sentiment-analysis.d.ts.map +1 -1
  635. package/dist/esm/nodes/ai/ai-sentiment-analysis.js +20 -5
  636. package/dist/esm/nodes/ai/ai-sentiment-analysis.js.map +1 -1
  637. package/dist/esm/nodes/ai/ai-summarization.d.ts.map +1 -1
  638. package/dist/esm/nodes/ai/ai-summarization.js +20 -5
  639. package/dist/esm/nodes/ai/ai-summarization.js.map +1 -1
  640. package/dist/esm/nodes/ai/ai-text-classifier.d.ts.map +1 -1
  641. package/dist/esm/nodes/ai/ai-text-classifier.js +20 -5
  642. package/dist/esm/nodes/ai/ai-text-classifier.js.map +1 -1
  643. package/dist/esm/nodes/ai/ai-text-transform.d.ts.map +1 -1
  644. package/dist/esm/nodes/ai/ai-text-transform.js +20 -5
  645. package/dist/esm/nodes/ai/ai-text-transform.js.map +1 -1
  646. package/dist/esm/nodes/analytics/analytics-track-outcome.d.ts +3 -0
  647. package/dist/esm/nodes/analytics/analytics-track-outcome.d.ts.map +1 -0
  648. package/dist/esm/nodes/analytics/analytics-track-outcome.js +107 -0
  649. package/dist/esm/nodes/analytics/analytics-track-outcome.js.map +1 -0
  650. package/dist/esm/nodes/cart/cart-price-order.d.ts.map +1 -1
  651. package/dist/esm/nodes/cart/cart-price-order.js +161 -2
  652. package/dist/esm/nodes/cart/cart-price-order.js.map +1 -1
  653. package/dist/esm/nodes/cost-bearing-node-types.d.ts +4 -0
  654. package/dist/esm/nodes/cost-bearing-node-types.d.ts.map +1 -0
  655. package/dist/esm/nodes/cost-bearing-node-types.js +39 -0
  656. package/dist/esm/nodes/cost-bearing-node-types.js.map +1 -0
  657. package/dist/esm/nodes/data/data-select.d.ts.map +1 -1
  658. package/dist/esm/nodes/data/data-select.js +12 -2
  659. package/dist/esm/nodes/data/data-select.js.map +1 -1
  660. package/dist/esm/nodes/email/email-mailersend.d.ts.map +1 -1
  661. package/dist/esm/nodes/email/email-mailersend.js +15 -11
  662. package/dist/esm/nodes/email/email-mailersend.js.map +1 -1
  663. package/dist/esm/nodes/email/email-mailgun.d.ts.map +1 -1
  664. package/dist/esm/nodes/email/email-mailgun.js +15 -15
  665. package/dist/esm/nodes/email/email-mailgun.js.map +1 -1
  666. package/dist/esm/nodes/email/email-postmark.d.ts.map +1 -1
  667. package/dist/esm/nodes/email/email-postmark.js +15 -15
  668. package/dist/esm/nodes/email/email-postmark.js.map +1 -1
  669. package/dist/esm/nodes/email/email-resend.d.ts.map +1 -1
  670. package/dist/esm/nodes/email/email-resend.js +15 -15
  671. package/dist/esm/nodes/email/email-resend.js.map +1 -1
  672. package/dist/esm/nodes/email/email-sendgrid.d.ts.map +1 -1
  673. package/dist/esm/nodes/email/email-sendgrid.js +15 -15
  674. package/dist/esm/nodes/email/email-sendgrid.js.map +1 -1
  675. package/dist/esm/nodes/email/html-escape-code.d.ts +3 -0
  676. package/dist/esm/nodes/email/html-escape-code.d.ts.map +1 -0
  677. package/dist/esm/nodes/email/html-escape-code.js +18 -0
  678. package/dist/esm/nodes/email/html-escape-code.js.map +1 -0
  679. package/dist/esm/nodes/email/message-trust.d.ts +40 -0
  680. package/dist/esm/nodes/email/message-trust.d.ts.map +1 -0
  681. package/dist/esm/nodes/email/message-trust.js +161 -0
  682. package/dist/esm/nodes/email/message-trust.js.map +1 -0
  683. package/dist/esm/nodes/email/outbound-message-guard.d.ts +113 -0
  684. package/dist/esm/nodes/email/outbound-message-guard.d.ts.map +1 -0
  685. package/dist/esm/nodes/email/outbound-message-guard.js +452 -0
  686. package/dist/esm/nodes/email/outbound-message-guard.js.map +1 -0
  687. package/dist/esm/nodes/email/trusted-html-code.d.ts +22 -0
  688. package/dist/esm/nodes/email/trusted-html-code.d.ts.map +1 -0
  689. package/dist/esm/nodes/email/trusted-html-code.js +49 -0
  690. package/dist/esm/nodes/email/trusted-html-code.js.map +1 -0
  691. package/dist/esm/nodes/general/general-custom-js.d.ts.map +1 -1
  692. package/dist/esm/nodes/general/general-custom-js.js +44 -7
  693. package/dist/esm/nodes/general/general-custom-js.js.map +1 -1
  694. package/dist/esm/nodes/general/general-http-request.d.ts.map +1 -1
  695. package/dist/esm/nodes/general/general-http-request.js +431 -45
  696. package/dist/esm/nodes/general/general-http-request.js.map +1 -1
  697. package/dist/esm/nodes/general/general-rate-limiter.d.ts.map +1 -1
  698. package/dist/esm/nodes/general/general-rate-limiter.js +46 -78
  699. package/dist/esm/nodes/general/general-rate-limiter.js.map +1 -1
  700. package/dist/esm/nodes/general/general-wait.d.ts +3 -0
  701. package/dist/esm/nodes/general/general-wait.d.ts.map +1 -0
  702. package/dist/esm/nodes/general/general-wait.js +78 -0
  703. package/dist/esm/nodes/general/general-wait.js.map +1 -0
  704. package/dist/esm/nodes/general/visitor-request.d.ts +44 -0
  705. package/dist/esm/nodes/general/visitor-request.d.ts.map +1 -0
  706. package/dist/esm/nodes/general/visitor-request.js +65 -0
  707. package/dist/esm/nodes/general/visitor-request.js.map +1 -0
  708. package/dist/esm/nodes/index.d.ts.map +1 -1
  709. package/dist/esm/nodes/index.js +7 -1
  710. package/dist/esm/nodes/index.js.map +1 -1
  711. package/dist/esm/nodes/integrations/integration-slack.d.ts.map +1 -1
  712. package/dist/esm/nodes/integrations/integration-slack.js +17 -6
  713. package/dist/esm/nodes/integrations/integration-slack.js.map +1 -1
  714. package/dist/esm/nodes/newsletter/newsletter-confirm.d.ts +3 -0
  715. package/dist/esm/nodes/newsletter/newsletter-confirm.d.ts.map +1 -0
  716. package/dist/esm/nodes/newsletter/newsletter-confirm.js +38 -0
  717. package/dist/esm/nodes/newsletter/newsletter-confirm.js.map +1 -0
  718. package/dist/esm/nodes/newsletter/newsletter-subscribe.d.ts +7 -0
  719. package/dist/esm/nodes/newsletter/newsletter-subscribe.d.ts.map +1 -0
  720. package/dist/esm/nodes/newsletter/newsletter-subscribe.js +66 -0
  721. package/dist/esm/nodes/newsletter/newsletter-subscribe.js.map +1 -0
  722. package/dist/esm/nodes/newsletter/newsletter-unsubscribe.d.ts +3 -0
  723. package/dist/esm/nodes/newsletter/newsletter-unsubscribe.d.ts.map +1 -0
  724. package/dist/esm/nodes/newsletter/newsletter-unsubscribe.js +39 -0
  725. package/dist/esm/nodes/newsletter/newsletter-unsubscribe.js.map +1 -0
  726. package/dist/esm/nodes/realtime/realtime-join-channel.d.ts.map +1 -1
  727. package/dist/esm/nodes/realtime/realtime-join-channel.js +5 -4
  728. package/dist/esm/nodes/realtime/realtime-join-channel.js.map +1 -1
  729. package/dist/esm/nodes/realtime/realtime-send-channel-event.d.ts.map +1 -1
  730. package/dist/esm/nodes/realtime/realtime-send-channel-event.js +11 -2
  731. package/dist/esm/nodes/realtime/realtime-send-channel-event.js.map +1 -1
  732. package/dist/esm/nodes/realtime/realtime-send-channel-message.d.ts.map +1 -1
  733. package/dist/esm/nodes/realtime/realtime-send-channel-message.js +11 -2
  734. package/dist/esm/nodes/realtime/realtime-send-channel-message.js.map +1 -1
  735. package/dist/esm/nodes/sms/sms-infobip.d.ts.map +1 -1
  736. package/dist/esm/nodes/sms/sms-infobip.js +11 -8
  737. package/dist/esm/nodes/sms/sms-infobip.js.map +1 -1
  738. package/dist/esm/nodes/sms/sms-smsapi.d.ts.map +1 -1
  739. package/dist/esm/nodes/sms/sms-smsapi.js +11 -8
  740. package/dist/esm/nodes/sms/sms-smsapi.js.map +1 -1
  741. package/dist/esm/nodes/sms/sms-textmagic.d.ts.map +1 -1
  742. package/dist/esm/nodes/sms/sms-textmagic.js +11 -8
  743. package/dist/esm/nodes/sms/sms-textmagic.js.map +1 -1
  744. package/dist/esm/nodes/sms/sms-twilio.d.ts.map +1 -1
  745. package/dist/esm/nodes/sms/sms-twilio.js +12 -10
  746. package/dist/esm/nodes/sms/sms-twilio.js.map +1 -1
  747. package/dist/esm/nodes/types.d.ts +8 -1
  748. package/dist/esm/nodes/types.d.ts.map +1 -1
  749. package/dist/esm/nodes/utility/utility-similarity-scoring.d.ts.map +1 -1
  750. package/dist/esm/nodes/utility/utility-similarity-scoring.js +29 -10
  751. package/dist/esm/nodes/utility/utility-similarity-scoring.js.map +1 -1
  752. package/dist/esm/page-access-guard-generator.d.ts +23 -0
  753. package/dist/esm/page-access-guard-generator.d.ts.map +1 -0
  754. package/dist/esm/page-access-guard-generator.js +131 -0
  755. package/dist/esm/page-access-guard-generator.js.map +1 -0
  756. package/dist/esm/password-reset-route-generator.d.ts +119 -0
  757. package/dist/esm/password-reset-route-generator.d.ts.map +1 -0
  758. package/dist/esm/password-reset-route-generator.js +448 -0
  759. package/dist/esm/password-reset-route-generator.js.map +1 -0
  760. package/dist/esm/payments/payment-core-code.d.ts.map +1 -1
  761. package/dist/esm/payments/payment-core-code.js +12 -7
  762. package/dist/esm/payments/payment-core-code.js.map +1 -1
  763. package/dist/esm/project-code-scanner.d.ts +11 -0
  764. package/dist/esm/project-code-scanner.d.ts.map +1 -0
  765. package/dist/esm/project-code-scanner.js +75 -0
  766. package/dist/esm/project-code-scanner.js.map +1 -0
  767. package/dist/esm/public-step-guards.d.ts +122 -0
  768. package/dist/esm/public-step-guards.d.ts.map +1 -0
  769. package/dist/esm/public-step-guards.js +280 -0
  770. package/dist/esm/public-step-guards.js.map +1 -0
  771. package/dist/esm/publish-refusals.d.ts +66 -0
  772. package/dist/esm/publish-refusals.d.ts.map +1 -0
  773. package/dist/esm/publish-refusals.js +271 -0
  774. package/dist/esm/publish-refusals.js.map +1 -0
  775. package/dist/esm/realtime-generator.d.ts +63 -1
  776. package/dist/esm/realtime-generator.d.ts.map +1 -1
  777. package/dist/esm/realtime-generator.js +401 -229
  778. package/dist/esm/realtime-generator.js.map +1 -1
  779. package/dist/esm/runtime-storage-generator.d.ts +32 -1
  780. package/dist/esm/runtime-storage-generator.d.ts.map +1 -1
  781. package/dist/esm/runtime-storage-generator.js +264 -11
  782. package/dist/esm/runtime-storage-generator.js.map +1 -1
  783. package/dist/esm/security-runtime/index.d.ts +14 -0
  784. package/dist/esm/security-runtime/index.d.ts.map +1 -0
  785. package/dist/esm/security-runtime/index.js +37 -0
  786. package/dist/esm/security-runtime/index.js.map +1 -0
  787. package/dist/esm/security-runtime/security-runtime-code.d.ts +53 -0
  788. package/dist/esm/security-runtime/security-runtime-code.d.ts.map +1 -0
  789. package/dist/esm/security-runtime/security-runtime-code.js +575 -0
  790. package/dist/esm/security-runtime/security-runtime-code.js.map +1 -0
  791. package/dist/esm/security-scanner.d.ts +72 -3
  792. package/dist/esm/security-scanner.d.ts.map +1 -1
  793. package/dist/esm/security-scanner.js +217 -8
  794. package/dist/esm/security-scanner.js.map +1 -1
  795. package/dist/esm/segment-splitter.d.ts.map +1 -1
  796. package/dist/esm/segment-splitter.js +10 -2
  797. package/dist/esm/segment-splitter.js.map +1 -1
  798. package/dist/esm/segment-trust.d.ts +36 -0
  799. package/dist/esm/segment-trust.d.ts.map +1 -1
  800. package/dist/esm/segment-trust.js +146 -2
  801. package/dist/esm/segment-trust.js.map +1 -1
  802. package/dist/esm/self-call-headers.d.ts +31 -0
  803. package/dist/esm/self-call-headers.d.ts.map +1 -0
  804. package/dist/esm/self-call-headers.js +43 -0
  805. package/dist/esm/self-call-headers.js.map +1 -0
  806. package/dist/esm/sent-email-log/index.d.ts +7 -0
  807. package/dist/esm/sent-email-log/index.d.ts.map +1 -1
  808. package/dist/esm/sent-email-log/index.js +15 -0
  809. package/dist/esm/sent-email-log/index.js.map +1 -1
  810. package/dist/esm/sent-email-log/sent-email-log-code.d.ts +7 -0
  811. package/dist/esm/sent-email-log/sent-email-log-code.d.ts.map +1 -1
  812. package/dist/esm/sent-email-log/sent-email-log-code.js +17 -3
  813. package/dist/esm/sent-email-log/sent-email-log-code.js.map +1 -1
  814. package/dist/esm/server-custom-node-call.d.ts +79 -0
  815. package/dist/esm/server-custom-node-call.d.ts.map +1 -0
  816. package/dist/esm/server-custom-node-call.js +278 -0
  817. package/dist/esm/server-custom-node-call.js.map +1 -0
  818. package/dist/esm/server-runtime-code.d.ts +39 -12
  819. package/dist/esm/server-runtime-code.d.ts.map +1 -1
  820. package/dist/esm/server-runtime-code.js +483 -40
  821. package/dist/esm/server-runtime-code.js.map +1 -1
  822. package/dist/esm/session-cookie-resolver.d.ts +3 -1
  823. package/dist/esm/session-cookie-resolver.d.ts.map +1 -1
  824. package/dist/esm/session-revocation-generator.d.ts +39 -0
  825. package/dist/esm/session-revocation-generator.d.ts.map +1 -0
  826. package/dist/esm/session-revocation-generator.js +172 -0
  827. package/dist/esm/session-revocation-generator.js.map +1 -0
  828. package/dist/esm/slack-message-values.d.ts +6 -0
  829. package/dist/esm/slack-message-values.d.ts.map +1 -0
  830. package/dist/esm/slack-message-values.js +68 -0
  831. package/dist/esm/slack-message-values.js.map +1 -0
  832. package/dist/esm/transactional-email-code.d.ts +11 -0
  833. package/dist/esm/transactional-email-code.d.ts.map +1 -1
  834. package/dist/esm/transactional-email-code.js +28 -4
  835. package/dist/esm/transactional-email-code.js.map +1 -1
  836. package/dist/esm/trigger-generator.d.ts +2 -0
  837. package/dist/esm/trigger-generator.d.ts.map +1 -1
  838. package/dist/esm/trigger-generator.js +15 -3
  839. package/dist/esm/trigger-generator.js.map +1 -1
  840. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  841. package/dist/esm/visitor-step-limits.d.ts +66 -0
  842. package/dist/esm/visitor-step-limits.d.ts.map +1 -0
  843. package/dist/esm/visitor-step-limits.js +181 -0
  844. package/dist/esm/visitor-step-limits.js.map +1 -0
  845. package/dist/esm/webhook-generator.d.ts.map +1 -1
  846. package/dist/esm/webhook-generator.js +93 -15
  847. package/dist/esm/webhook-generator.js.map +1 -1
  848. package/dist/esm/webhook-signature-verification.d.ts.map +1 -1
  849. package/dist/esm/webhook-signature-verification.js +13 -3
  850. package/dist/esm/webhook-signature-verification.js.map +1 -1
  851. package/dist/esm/workflow-auth-generator.d.ts +4 -1
  852. package/dist/esm/workflow-auth-generator.d.ts.map +1 -1
  853. package/dist/esm/workflow-auth-generator.js +8 -3
  854. package/dist/esm/workflow-auth-generator.js.map +1 -1
  855. package/dist/esm/workflow-component-plugin.js +12 -4
  856. package/dist/esm/workflow-component-plugin.js.map +1 -1
  857. package/dist/esm/workflow-project-plugin.d.ts.map +1 -1
  858. package/dist/esm/workflow-project-plugin.js +306 -60
  859. package/dist/esm/workflow-project-plugin.js.map +1 -1
  860. package/dist/esm/workflow-scope.d.ts.map +1 -1
  861. package/dist/esm/workflow-scope.js +5 -0
  862. package/dist/esm/workflow-scope.js.map +1 -1
  863. package/package.json +4 -4
  864. package/src/account-delete-route-generator.ts +28 -4
  865. package/src/api-route-generator.ts +712 -134
  866. package/src/auth-generator.ts +1471 -142
  867. package/src/automations/activity-kicks.ts +139 -0
  868. package/src/automations/app-events-source.ts +117 -0
  869. package/src/automations/automations-project-plugin.ts +202 -0
  870. package/src/automations/automations-scope.ts +196 -0
  871. package/src/automations/dispatcher-source.ts +1072 -0
  872. package/src/automations/event-bus-source.ts +428 -0
  873. package/src/automations/handler-module-generator.ts +107 -0
  874. package/src/automations/hydrators-source.ts +647 -0
  875. package/src/booking-calendar-feed-route-generator.ts +8 -0
  876. package/src/configured-nextauth-url.ts +17 -0
  877. package/src/cron-request-verification.ts +55 -5
  878. package/src/data-api-route-generator.ts +780 -43
  879. package/src/ecommerce/parameterized-stock-chain.ts +52 -5
  880. package/src/ecommerce/place-order-guards.ts +785 -0
  881. package/src/ecommerce-customhandler-rewriter.ts +55 -2
  882. package/src/executor-generator.ts +372 -60
  883. package/src/graph-utils.ts +33 -0
  884. package/src/index.ts +70 -0
  885. package/src/invoice/api-routes-code.ts +20 -7
  886. package/src/invoice/index.ts +11 -6
  887. package/src/invoice/invoice-assembly-code.ts +8 -3
  888. package/src/invoice/pdf-generator-code.ts +2 -1
  889. package/src/invoice/pdf-service-client-code.ts +15 -7
  890. package/src/newsletter/admin-route-code.ts +319 -0
  891. package/src/newsletter/helper-code.ts +748 -0
  892. package/src/newsletter/newsletter-scope.ts +116 -0
  893. package/src/newsletter/project-plugin.ts +119 -0
  894. package/src/newsletter/routes-code.ts +186 -0
  895. package/src/nodes/account/account-compare-passwords.ts +17 -6
  896. package/src/nodes/account/account-delete-current.ts +1 -1
  897. package/src/nodes/account/account-get-current.ts +1 -1
  898. package/src/nodes/account/account-hash-password.ts +19 -3
  899. package/src/nodes/account/account-login.ts +24 -7
  900. package/src/nodes/account/account-logout.ts +1 -1
  901. package/src/nodes/account/account-refresh-session.ts +1 -1
  902. package/src/nodes/account/account-request-password-reset.ts +47 -0
  903. package/src/nodes/account/account-reset-password.ts +45 -0
  904. package/src/nodes/account/account-signup.ts +86 -20
  905. package/src/nodes/account/account-social-login.ts +1 -1
  906. package/src/nodes/ai/ai-custom-prompt.ts +25 -6
  907. package/src/nodes/ai/ai-detect-language.ts +25 -6
  908. package/src/nodes/ai/ai-generate-text-embedding.ts +16 -3
  909. package/src/nodes/ai/ai-provider-utils-sources.generated.ts +2 -2
  910. package/src/nodes/ai/ai-provider-utils.ts +135 -10
  911. package/src/nodes/ai/ai-select-database-data.ts +8 -3
  912. package/src/nodes/ai/ai-sentiment-analysis.ts +25 -6
  913. package/src/nodes/ai/ai-summarization.ts +25 -6
  914. package/src/nodes/ai/ai-text-classifier.ts +25 -6
  915. package/src/nodes/ai/ai-text-transform.ts +25 -6
  916. package/src/nodes/analytics/analytics-track-outcome.ts +111 -0
  917. package/src/nodes/cart/cart-price-order.ts +200 -2
  918. package/src/nodes/cost-bearing-node-types.ts +45 -0
  919. package/src/nodes/data/data-select.ts +11 -2
  920. package/src/nodes/email/email-mailersend.ts +16 -8
  921. package/src/nodes/email/email-mailgun.ts +17 -12
  922. package/src/nodes/email/email-postmark.ts +17 -12
  923. package/src/nodes/email/email-resend.ts +17 -12
  924. package/src/nodes/email/email-sendgrid.ts +17 -12
  925. package/src/nodes/email/html-escape-code.ts +21 -0
  926. package/src/nodes/email/message-trust.ts +198 -0
  927. package/src/nodes/email/outbound-message-guard.ts +572 -0
  928. package/src/nodes/email/trusted-html-code.ts +49 -0
  929. package/src/nodes/general/general-custom-js.ts +46 -7
  930. package/src/nodes/general/general-http-request.ts +449 -46
  931. package/src/nodes/general/general-rate-limiter.ts +54 -81
  932. package/src/nodes/general/general-wait.ts +80 -0
  933. package/src/nodes/general/visitor-request.ts +79 -0
  934. package/src/nodes/index.ts +12 -0
  935. package/src/nodes/integrations/integration-slack.ts +21 -6
  936. package/src/nodes/newsletter/newsletter-confirm.ts +44 -0
  937. package/src/nodes/newsletter/newsletter-subscribe.ts +78 -0
  938. package/src/nodes/newsletter/newsletter-unsubscribe.ts +43 -0
  939. package/src/nodes/realtime/realtime-join-channel.ts +5 -4
  940. package/src/nodes/realtime/realtime-send-channel-event.ts +13 -2
  941. package/src/nodes/realtime/realtime-send-channel-message.ts +13 -2
  942. package/src/nodes/sms/sms-infobip.ts +14 -4
  943. package/src/nodes/sms/sms-smsapi.ts +14 -4
  944. package/src/nodes/sms/sms-textmagic.ts +14 -4
  945. package/src/nodes/sms/sms-twilio.ts +14 -4
  946. package/src/nodes/types.ts +9 -1
  947. package/src/nodes/utility/utility-similarity-scoring.ts +33 -12
  948. package/src/page-access-guard-generator.ts +154 -0
  949. package/src/password-reset-route-generator.ts +531 -0
  950. package/src/payments/payment-core-code.ts +12 -7
  951. package/src/project-code-scanner.ts +98 -0
  952. package/src/public-step-guards.ts +448 -0
  953. package/src/publish-refusals.ts +459 -0
  954. package/src/realtime-generator.ts +457 -234
  955. package/src/runtime-storage-generator.ts +270 -11
  956. package/src/security-runtime/index.ts +53 -0
  957. package/src/security-runtime/security-runtime-code.ts +579 -0
  958. package/src/security-scanner.ts +253 -10
  959. package/src/segment-splitter.ts +10 -2
  960. package/src/segment-trust.ts +205 -2
  961. package/src/self-call-headers.ts +46 -0
  962. package/src/sent-email-log/index.ts +16 -0
  963. package/src/sent-email-log/sent-email-log-code.ts +30 -4
  964. package/src/server-custom-node-call.ts +331 -0
  965. package/src/server-runtime-code.ts +488 -40
  966. package/src/session-revocation-generator.ts +177 -0
  967. package/src/slack-message-values.ts +84 -0
  968. package/src/transactional-email-code.ts +30 -4
  969. package/src/trigger-generator.ts +19 -3
  970. package/src/visitor-step-limits.ts +228 -0
  971. package/src/webhook-generator.ts +94 -14
  972. package/src/webhook-signature-verification.ts +13 -3
  973. package/src/workflow-auth-generator.ts +9 -4
  974. package/src/workflow-component-plugin.ts +14 -4
  975. package/src/workflow-project-plugin.ts +374 -61
  976. package/src/workflow-scope.ts +6 -0
@@ -0,0 +1,1324 @@
1
+ /* tslint:disable:function-constructor no-any */
2
+ import * as crypto from 'crypto'
3
+ import { TableAccess } from '@teleporthq/teleport-shared'
4
+ import { generateDataAPIRoute } from '../src/data-api-route-generator'
5
+ import {
6
+ generateCronAPIRoute,
7
+ generateHandlerFunction,
8
+ generateServerSegmentAPIRoute,
9
+ generateStreamingServerSegmentAPIRoute,
10
+ generateWebhookWorkflowAPIRoute,
11
+ } from '../src/api-route-generator'
12
+ import { dataSelect } from '../src/nodes/data/data-select'
13
+ import { loadServerRuntime } from './_helpers/load-server-runtime'
14
+ import { withEnv, withFetch } from './_helpers/fake-fetch'
15
+
16
+ /**
17
+ * The data API is what a server segment reads with the app secret, for a
18
+ * visitor whose session reaches it only as the forwarded cookie and whose
19
+ * filter values arrive as the context the browser sent (A1-01, A1-02, A1-07,
20
+ * A6-04). The verdict is the SQL that reached a fake database and the rows
21
+ * served.
22
+ */
23
+
24
+ const SECRET = 'server-secret-abc'
25
+
26
+ interface Session {
27
+ id?: string
28
+ email?: string
29
+ role?: string
30
+ }
31
+
32
+ interface Db {
33
+ queries: string[]
34
+ params: unknown[][]
35
+ rows: any[]
36
+ /** Column types the schema lookup answers with. */
37
+ columnTypes?: Record<string, string>
38
+ /** Column types per table, where tables differ (wins over `columnTypes`). */
39
+ tableColumns?: Record<string, Record<string, string>>
40
+ /** The ids of registered accounts (users rows with an email). */
41
+ registered?: string[]
42
+ /**
43
+ * The `users` rows themselves: when given, the "is it a registered account"
44
+ * check is answered by the predicate the statement writes, over these rows.
45
+ */
46
+ users?: Array<{ id: string; email: string | null }>
47
+ }
48
+
49
+ const quiet = {
50
+ log: (): void => undefined,
51
+ warn: (): void => undefined,
52
+ error: (): void => undefined,
53
+ }
54
+
55
+ function bootDataApi(db: Db, extra: Record<string, unknown> = {}) {
56
+ // The project's staff: the admin panel's `manager` role and the explicit admin;
57
+ // its TeleportHQ data source: ds1.
58
+ const code = generateDataAPIRoute({
59
+ authUsersTableName: 'users',
60
+ staffRoles: ['admin', 'manager'],
61
+ managedDataSourceIds: ['ds1'],
62
+ ...extra,
63
+ })
64
+ let session: Session | null = null
65
+ class FakeClient {
66
+ public async connect(): Promise<void> {
67
+ return
68
+ }
69
+ public async end(): Promise<void> {
70
+ return
71
+ }
72
+ public async query(
73
+ sql: string,
74
+ values?: unknown[]
75
+ ): Promise<{ rows: any[]; rowCount: number }> {
76
+ db.queries.push(sql)
77
+ db.params.push(values || [])
78
+ if (/information_schema/i.test(sql)) {
79
+ const table = String((values || [])[1])
80
+ const types = (db.tableColumns && db.tableColumns[table]) || db.columnTypes || {}
81
+ const rows = Object.keys(types).map((name) => ({
82
+ column_name: name,
83
+ data_type: types[name],
84
+ }))
85
+ return { rows, rowCount: rows.length }
86
+ }
87
+ if (/^SELECT 1 FROM users WHERE id::text = \$1/.test(sql) && db.users) {
88
+ const row = db.users.find((user) => user.id === String((values || [])[0]))
89
+ const email = row ? String(row.email == null ? '' : row.email) : ''
90
+ let registered: boolean
91
+ if (sql.indexOf("COALESCE(LOWER(email), '') NOT LIKE '%@anonymous.local'") !== -1) {
92
+ registered = !!row && !email.toLowerCase().endsWith('@anonymous.local')
93
+ } else if (sql.indexOf("COALESCE(email, '') <> ''") !== -1) {
94
+ registered = !!row && email !== ''
95
+ } else {
96
+ throw new Error('unexpected registered-account check: ' + sql)
97
+ }
98
+ return { rows: registered ? [{ '?column?': 1 }] : [], rowCount: registered ? 1 : 0 }
99
+ }
100
+ if (/^SELECT 1 FROM users WHERE id::text = \$1/.test(sql)) {
101
+ const known = (db.registered || []).indexOf(String((values || [])[0])) !== -1
102
+ return { rows: known ? [{ '?column?': 1 }] : [], rowCount: known ? 1 : 0 }
103
+ }
104
+ if (/^SELECT COUNT/i.test(sql)) {
105
+ return { rows: [{ count: String(db.rows.length) }], rowCount: 1 }
106
+ }
107
+ return { rows: db.rows.map((row) => ({ ...row })), rowCount: db.rows.length }
108
+ }
109
+ }
110
+ const moduleObj: { exports: any } = { exports: {} }
111
+ const fakeRequire = (name: string): any => {
112
+ if (name === 'pg') {
113
+ return { Client: FakeClient }
114
+ }
115
+ if (name === 'next-auth/jwt') {
116
+ return { getToken: async () => (session ? { sub: session.id, ...session } : null) }
117
+ }
118
+ if (name === 'crypto') {
119
+ return require('crypto')
120
+ }
121
+ if (/\/utils\/security-runtime$/.test(name)) {
122
+ // The shared security runtime's constant-time compare, which the guard
123
+ // requires for the app secret.
124
+ return {
125
+ safeEqual: (given: unknown, expected: unknown) =>
126
+ typeof given === 'string' &&
127
+ typeof expected === 'string' &&
128
+ given !== '' &&
129
+ given === expected,
130
+ }
131
+ }
132
+ throw new Error('unexpected require: ' + name)
133
+ }
134
+ new Function('require', 'module', 'exports', 'process', 'console', code)(
135
+ fakeRequire,
136
+ moduleObj,
137
+ moduleObj.exports,
138
+ { env: { NEXTAUTH_SECRET: SECRET } },
139
+ quiet
140
+ )
141
+ return async (
142
+ operation: string,
143
+ body: any,
144
+ options: {
145
+ internal?: boolean
146
+ session?: Session | null
147
+ secret?: string
148
+ authLayer?: boolean
149
+ dataSourceId?: string
150
+ /** A server job (cron, webhook, automation): no visitor's request behind the call. */
151
+ job?: boolean
152
+ } = {}
153
+ ) => {
154
+ session = options.session || null
155
+ const reply: any = { status: 0, body: null }
156
+ const headers: Record<string, string> = { cookie: 'next-auth.session-token=x' }
157
+ if (options.internal) {
158
+ headers['x-internal-data-secret'] = options.secret || SECRET
159
+ }
160
+ if (options.job) {
161
+ // A cron, a webhook or an automation run flags its calls (the runners put
162
+ // the flag in the run's internal headers).
163
+ headers['x-tq-server-job'] = '1'
164
+ }
165
+ const req: any = {
166
+ method: 'POST',
167
+ query: { params: [options.dataSourceId || 'ds1', operation] },
168
+ headers,
169
+ body,
170
+ }
171
+ if (options.authLayer) {
172
+ // The auth layer's own in-process call.
173
+ req.__tqServerCall = true
174
+ req.__tqAuthLayerCall = true
175
+ }
176
+ await moduleObj.exports(req, {
177
+ status(c: number) {
178
+ reply.status = c
179
+ return this
180
+ },
181
+ json(p: any) {
182
+ reply.body = p
183
+ return this
184
+ },
185
+ })
186
+ return reply
187
+ }
188
+ }
189
+
190
+ const freshDb = (rows: any[] = []): Db => ({ queries: [], params: [], rows })
191
+ const selects = (db: Db): string[] =>
192
+ db.queries.filter((sql) => /^SELECT (?!COUNT)/i.test(sql) && !/information_schema/i.test(sql))
193
+
194
+ describe('owner-scoped reads of customer tables (A1-01)', () => {
195
+ it('an "all" or empty owner never widens a guest read to every customer', async () => {
196
+ for (const forged of ['all', '__all__', '']) {
197
+ const db = freshDb([{ id: 'o1', user_id: 'victim' }])
198
+ const api = bootDataApi(db)
199
+ const reply = await api(
200
+ 'select',
201
+ {
202
+ tableName: 'teleport_orders',
203
+ filters: [{ field: 'user_id', operator: '=', value: forged }],
204
+ },
205
+ { internal: true }
206
+ )
207
+ expect(reply.status).toBe(200)
208
+ expect(selects(db)[0]).toBe('SELECT * FROM teleport_orders WHERE FALSE')
209
+ }
210
+ })
211
+
212
+ it('the data-select node keeps an empty owner filter, so the read stays scoped end to end', async () => {
213
+ const db = freshDb([{ id: 'o1', user_id: 'victim' }])
214
+ const api = bootDataApi(db)
215
+ const source = dataSelect.generateHandler()
216
+ const fetchShim = async (url: string, init: any) => {
217
+ const reply = await api(url.split('/').pop() as string, JSON.parse(init.body), {
218
+ internal: true,
219
+ })
220
+ return { ok: reply.status < 400, status: reply.status, json: async () => reply.body }
221
+ }
222
+ const handler = new Function('fetch', `return (${source})`)(fetchShim)
223
+ await handler(
224
+ {
225
+ dataSourceId: 'ds1',
226
+ tableName: 'teleport_orders',
227
+ filters: [{ field: 'user_id', operator: '=', value: 'all' }],
228
+ },
229
+ { __baseUrl: 'http://localhost', __internalHeaders: {}, __sessionUserId: null }
230
+ )
231
+ expect(selects(db)[0]).toBe('SELECT * FROM teleport_orders WHERE FALSE')
232
+
233
+ // On any other table the node's old rule stands: the empty filter is left out.
234
+ const other = freshDb([{ id: 'n1' }])
235
+ const otherApi = bootDataApi(other)
236
+ const otherHandler = new Function('fetch', `return (${source})`)(
237
+ async (url: string, init: any) => {
238
+ const reply = await otherApi(url.split('/').pop() as string, JSON.parse(init.body), {
239
+ internal: true,
240
+ })
241
+ return { ok: reply.status < 400, status: reply.status, json: async () => reply.body }
242
+ }
243
+ )
244
+ await otherHandler(
245
+ {
246
+ dataSourceId: 'ds1',
247
+ tableName: 'notes',
248
+ filters: [{ field: 'user_id', operator: '=', value: '' }],
249
+ },
250
+ { __baseUrl: 'http://localhost', __internalHeaders: {}, __sessionUserId: null }
251
+ )
252
+ expect(selects(other)[0]).toBe('SELECT * FROM notes')
253
+ })
254
+
255
+ it("a signed-in customer reads only the session's own rows, whatever id or email the context names", async () => {
256
+ const db = freshDb([{ id: 'u2', email: 'victim@x.com' }])
257
+ const api = bootDataApi(db)
258
+ const me = { id: 'u1', email: 'me@x.com', role: 'user' }
259
+
260
+ await api(
261
+ 'select',
262
+ { tableName: 'users', filters: [{ field: 'email', operator: '=', value: 'victim@x.com' }] },
263
+ { internal: true, session: me }
264
+ )
265
+ expect(selects(db)[0]).toBe('SELECT * FROM users WHERE FALSE')
266
+
267
+ db.queries.length = 0
268
+ db.params.length = 0
269
+ await api(
270
+ 'select',
271
+ { tableName: 'users', filters: [{ field: 'email', operator: '=', value: 'ME@x.com' }] },
272
+ { internal: true, session: me }
273
+ )
274
+ expect(selects(db)[0]).toBe('SELECT * FROM users WHERE email = $1')
275
+
276
+ db.queries.length = 0
277
+ await api(
278
+ 'select',
279
+ {
280
+ tableName: 'teleport_orders',
281
+ filters: [{ field: 'user_id', operator: '=', value: ['u1', 'u2'] }],
282
+ },
283
+ { internal: true, session: me }
284
+ )
285
+ expect(selects(db)[0]).toBe('SELECT * FROM teleport_orders WHERE FALSE')
286
+
287
+ db.queries.length = 0
288
+ await api(
289
+ 'count',
290
+ {
291
+ tableName: 'teleport_orders',
292
+ filters: [{ field: 'user_id', operator: '!=', value: 'u1' }],
293
+ },
294
+ { internal: true, session: me }
295
+ )
296
+ expect(db.queries[0]).toBe('SELECT COUNT(*) FROM teleport_orders WHERE FALSE')
297
+ })
298
+
299
+ it("a guest's own rows are the ones no account owns, by the guest key the read names", async () => {
300
+ const db = freshDb([])
301
+ const api = bootDataApi(db)
302
+ await api(
303
+ 'select',
304
+ {
305
+ tableName: 'teleport_favourites',
306
+ filters: [
307
+ { field: 'user_id', operator: '=', value: '', __skippable: true },
308
+ { field: 'session_id', operator: '=', value: 'guest-session' },
309
+ ],
310
+ },
311
+ { internal: true }
312
+ )
313
+ expect(selects(db)[0]).toBe(
314
+ 'SELECT * FROM teleport_favourites WHERE user_id IS NULL AND session_id = $1'
315
+ )
316
+ })
317
+
318
+ it('a staff role reads every customer record as before', async () => {
319
+ for (const role of ['admin', 'manager']) {
320
+ const db = freshDb([])
321
+ const api = bootDataApi(db)
322
+ await api(
323
+ 'select',
324
+ {
325
+ tableName: 'teleport_orders',
326
+ filters: [{ field: 'customer_email', operator: '=', value: 'someone@x.com' }],
327
+ },
328
+ { internal: true, session: { id: 'a1', role } }
329
+ )
330
+ expect(selects(db)[0]).toBe('SELECT * FROM teleport_orders WHERE customer_email = $1')
331
+ }
332
+ })
333
+
334
+ it("a customer role a sign-up or a subscription gives (member) reads only the member's own rows", async () => {
335
+ const db = freshDb([])
336
+ const api = bootDataApi(db)
337
+ const member = { id: 'm1', email: 'm@x.com', role: 'member' }
338
+ await api(
339
+ 'select',
340
+ {
341
+ tableName: 'teleport_orders',
342
+ filters: [{ field: 'customer_email', operator: '=', value: 'someone@x.com' }],
343
+ },
344
+ { internal: true, session: member }
345
+ )
346
+ expect(selects(db)[0]).toBe('SELECT * FROM teleport_orders WHERE FALSE')
347
+ db.queries.length = 0
348
+ await api(
349
+ 'select',
350
+ { tableName: 'teleport_orders', filters: [{ field: 'user_id', operator: '=', value: 'm1' }] },
351
+ { internal: true, session: member }
352
+ )
353
+ expect(selects(db)[0]).toBe('SELECT * FROM teleport_orders WHERE user_id = $1')
354
+ // Nor may a member grant itself a staff role.
355
+ const write = await api(
356
+ 'update',
357
+ {
358
+ tableName: 'users',
359
+ filters: [{ field: 'id', operator: '=', value: 'm1' }],
360
+ columnMappings: [{ column: 'role', value: 'manager' }],
361
+ },
362
+ { internal: true, session: member }
363
+ )
364
+ expect(write.status).toBe(403)
365
+ })
366
+
367
+ it('without the staff roles, only the explicit admin role is staff', () => {
368
+ const code = generateDataAPIRoute({})
369
+ expect(code).toContain('var STAFF_ROLES = ["admin"];')
370
+ })
371
+ })
372
+
373
+ describe('credential columns never leave in a row (A1-02)', () => {
374
+ const USER = {
375
+ id: 'u1',
376
+ email: 'v@x.com',
377
+ password: '$2b$10$hash',
378
+ access_token: 'oauth',
379
+ role: 'admin',
380
+ }
381
+
382
+ it('a server-side SELECT * on users serves no hash and no OAuth token', async () => {
383
+ const db = freshDb([USER])
384
+ const api = bootDataApi(db)
385
+ const reply = await api(
386
+ 'select',
387
+ { tableName: 'users', filters: [], limit: 1 },
388
+ { internal: true }
389
+ )
390
+ expect(reply.body.rows).toEqual([{ id: 'u1', email: 'v@x.com', role: 'admin' }])
391
+ })
392
+
393
+ it('a server segment that names the hash in its projection still never gets it (I1)', async () => {
394
+ const db = freshDb([{ id: 'u1', email: 'v@x.com', password: '$2b$10$hash' }])
395
+ const api = bootDataApi(db)
396
+ const reply = await api(
397
+ 'select',
398
+ {
399
+ tableName: 'users',
400
+ selectedColumns: ['email', 'password'],
401
+ filters: [{ field: 'email', operator: '=', value: 'v@x.com' }],
402
+ },
403
+ { internal: true }
404
+ )
405
+ expect(reply.body.rows[0]).not.toHaveProperty('password')
406
+ })
407
+
408
+ it("only the auth layer's own in-process call gets a credential it names", async () => {
409
+ const db = freshDb([{ id: 'u1', password: '$2b$10$hash' }])
410
+ const api = bootDataApi(db)
411
+ const reply = await api(
412
+ 'select',
413
+ { tableName: 'users', selectedColumns: ['id', 'password'] },
414
+ { authLayer: true }
415
+ )
416
+ expect(reply.body.rows[0].password).toBe('$2b$10$hash')
417
+ })
418
+
419
+ it('a write never hands back the row with its credentials (I1)', async () => {
420
+ const db = freshDb([
421
+ { id: 'u1', email: 'me@x.com', name: 'New', password: '$2b$hash', refresh_token: 'rt' },
422
+ ])
423
+ const api = bootDataApi(db)
424
+ const me = { id: 'u1', email: 'me@x.com', role: 'user' }
425
+ const updated = await api(
426
+ 'update',
427
+ {
428
+ tableName: 'users',
429
+ filters: [{ field: 'email', operator: '=', value: 'me@x.com' }],
430
+ columnMappings: [{ column: 'name', value: 'New' }],
431
+ },
432
+ { internal: true, session: me }
433
+ )
434
+ expect(updated.status).toBe(200)
435
+ expect(updated.body.item).toEqual({ id: 'u1', email: 'me@x.com', name: 'New' })
436
+ const created = await api(
437
+ 'create',
438
+ { tableName: 'users', columnMappings: [{ column: 'name', value: 'New' }] },
439
+ { internal: true }
440
+ )
441
+ expect(created.body.item).not.toHaveProperty('password')
442
+ expect(created.body.item).not.toHaveProperty('refresh_token')
443
+ })
444
+
445
+ it("a server job's raw statement brings back only the credential columns it names", async () => {
446
+ const db = freshDb([{ id: 'u1', password: 'h', reset_token: 't', name: 'Ada' }])
447
+ const api = bootDataApi(db)
448
+ const all = await api(
449
+ 'raw-query',
450
+ { query: 'SELECT * FROM users u JOIN profiles p ON p.user_id = u.id' },
451
+ { internal: true, job: true }
452
+ )
453
+ expect(all.body.rows).toEqual([{ id: 'u1', name: 'Ada' }])
454
+ const named = await api(
455
+ 'raw-query',
456
+ { query: 'SELECT id, password FROM users WHERE email = $1', params: ['a'] },
457
+ { internal: true, job: true }
458
+ )
459
+ expect(named.body.rows[0]).toHaveProperty('password', 'h')
460
+ expect(named.body.rows[0]).not.toHaveProperty('reset_token')
461
+ })
462
+ })
463
+
464
+ describe('browser reads are bounded (A1-07) and the secret is compared in constant time (A6-04)', () => {
465
+ it('a browser read without a count gets the default, a huge one the cap, a malformed one a 400', async () => {
466
+ const db = freshDb([])
467
+ const api = bootDataApi(db)
468
+ await api('select', { tableName: 'teleport_products' })
469
+ expect(selects(db)[0]).toMatch(/ LIMIT 100$/)
470
+ db.queries.length = 0
471
+ await api('select', { tableName: 'teleport_products', limit: 1000000000 })
472
+ expect(selects(db)[0]).toMatch(/ LIMIT 1000$/)
473
+ db.queries.length = 0
474
+ const bad = await api('select', { tableName: 'teleport_products', limit: '1;--' })
475
+ expect(bad.status).toBe(400)
476
+ expect(db.queries).toEqual([])
477
+ })
478
+
479
+ it('a server-side read is not capped', async () => {
480
+ const db = freshDb([])
481
+ const api = bootDataApi(db)
482
+ await api('select', { tableName: 'teleport_products' }, { internal: true })
483
+ expect(selects(db)[0]).toBe('SELECT * FROM teleport_products')
484
+ })
485
+
486
+ it('only the exact secret makes a request internal', async () => {
487
+ const db = freshDb([])
488
+ const api = bootDataApi(db)
489
+ const wrong = await api(
490
+ 'select',
491
+ { tableName: 'users' },
492
+ { internal: true, secret: SECRET.slice(0, -1) + 'x' }
493
+ )
494
+ expect(wrong.status).toBe(403)
495
+ const short = await api(
496
+ 'select',
497
+ { tableName: 'users' },
498
+ { internal: true, secret: SECRET.slice(0, 4) }
499
+ )
500
+ expect(short.status).toBe(403)
501
+ // Constant-time: Node's own compare, or the shared security runtime's
502
+ // (Task 3a moved the guard onto it).
503
+ expect(TableAccess.generateTableAccessHelperCode({ trustedReaderRoles: [] })).toMatch(
504
+ /timingSafeEqual|security\.safeEqual\(/
505
+ )
506
+ })
507
+ })
508
+
509
+ describe('the data-select node hands every filter to the data API', () => {
510
+ it('keeps a filter it would leave out, marked, so the data API decides', async () => {
511
+ const sent: any[] = []
512
+ const handler = new Function('fetch', `return (${dataSelect.generateHandler()})`)(
513
+ async (_url: string, init: any) => {
514
+ sent.push(JSON.parse(init.body))
515
+ return { ok: true, status: 200, json: async () => ({ rows: [] as any[], count: 0 }) }
516
+ }
517
+ )
518
+ await handler(
519
+ {
520
+ dataSourceId: 'ds1',
521
+ tableName: 'teleport_orders',
522
+ filters: [
523
+ { field: 'id', operator: '=', value: 'all' },
524
+ { field: 'status', operator: '=', value: 'paid' },
525
+ ],
526
+ },
527
+ { __baseUrl: 'http://localhost', __internalHeaders: {}, __sessionUserId: null }
528
+ )
529
+ expect(sent[0].filters).toEqual([
530
+ { field: 'id', operator: '=', value: 'all', __skippable: true },
531
+ { field: 'status', operator: '=', value: 'paid' },
532
+ ])
533
+ })
534
+ })
535
+
536
+ describe('a server segment never writes a privilege onto an ordinary account (A1-06)', () => {
537
+ const update = (columns: Record<string, unknown>) => ({
538
+ tableName: 'users',
539
+ filters: [{ field: 'id', operator: '=', value: 'u1' }],
540
+ columnMappings: Object.keys(columns).map((column) => ({ column, value: columns[column] })),
541
+ })
542
+
543
+ it('refuses a role or an admin flag for a signed-in customer, by any spelling', async () => {
544
+ const db = freshDb([])
545
+ const api = bootDataApi(db)
546
+ const me = { id: 'u1', email: 'me@x.com', role: 'user' }
547
+ for (const columns of [
548
+ { role: 'admin' },
549
+ { is_admin: true },
550
+ { name: 'Ada', roles: ['admin'] },
551
+ ]) {
552
+ const reply = await api('update', update(columns), { internal: true, session: me })
553
+ expect(reply.status).toBe(403)
554
+ }
555
+ const raw = await api(
556
+ 'raw-query',
557
+ { query: 'UPDATE users SET is_staff = TRUE WHERE id = $1', params: ['u1'] },
558
+ { internal: true, session: me }
559
+ )
560
+ expect(raw.status).toBe(403)
561
+ expect(db.queries.filter((sql) => /^UPDATE/.test(sql))).toEqual([])
562
+ })
563
+
564
+ it('lets a customer update their profile, the admin grant a role, and a server job write without a visitor', async () => {
565
+ const db = freshDb([{ id: 'u1' }])
566
+ const api = bootDataApi(db)
567
+ expect(
568
+ (
569
+ await api('update', update({ name: 'Ada' }), {
570
+ internal: true,
571
+ session: { id: 'u1', role: 'user' },
572
+ })
573
+ ).status
574
+ ).toBe(200)
575
+ expect(
576
+ (
577
+ await api('update', update({ role: 'staff' }), {
578
+ internal: true,
579
+ session: { id: 'a1', role: 'admin' },
580
+ })
581
+ ).status
582
+ ).toBe(200)
583
+ expect((await api('update', update({ is_admin: false }), { internal: true })).status).toBe(200)
584
+ })
585
+ })
586
+
587
+ describe('no data API query waits on the database for long (A5-L5)', () => {
588
+ it('creates every client with a 10 s query timeout', () => {
589
+ const code = generateDataAPIRoute({})
590
+ expect(code.match(/query_timeout: 10000/g)).toHaveLength(2)
591
+ })
592
+ })
593
+
594
+ describe('fix round 1: customer tables never widen, guests never name an owner', () => {
595
+ it('an "all", empty or wildcard value on ANY key of a customer table matches nothing (I4)', async () => {
596
+ for (const forged of ['all', '', '__all__', '*']) {
597
+ const forgedDb = freshDb([{ id: 'o1' }, { id: 'o2' }])
598
+ const forgedApi = bootDataApi(forgedDb)
599
+ await forgedApi(
600
+ 'select',
601
+ { tableName: 'teleport_orders', filters: [{ field: 'id', operator: '=', value: forged }] },
602
+ { internal: true }
603
+ )
604
+ expect(selects(forgedDb)[0]).toBe('SELECT * FROM teleport_orders WHERE FALSE')
605
+ }
606
+ // Any other table keeps the optional filter's old meaning.
607
+ const db = freshDb([])
608
+ const api = bootDataApi(db)
609
+ await api(
610
+ 'select',
611
+ { tableName: 'notes', filters: [{ field: 'id', operator: '=', value: 'all' }] },
612
+ { internal: true }
613
+ )
614
+ expect(selects(db)[0]).toBe('SELECT * FROM notes')
615
+ })
616
+
617
+ it("a guest naming an account's email or id reads nothing, unless the read is bound to the guest's own key (I5)", async () => {
618
+ const db = freshDb([{ id: 'o1', customer_email: 'victim@x.com' }])
619
+ const api = bootDataApi(db)
620
+ await api(
621
+ 'select',
622
+ {
623
+ tableName: 'teleport_orders',
624
+ filters: [{ field: 'customer_email', operator: '=', value: 'victim@x.com' }],
625
+ },
626
+ { internal: true }
627
+ )
628
+ expect(selects(db)[0]).toBe('SELECT * FROM teleport_orders WHERE FALSE')
629
+
630
+ db.queries.length = 0
631
+ db.params.length = 0
632
+ await api(
633
+ 'select',
634
+ {
635
+ tableName: 'teleport_favourites',
636
+ filters: [
637
+ { field: 'user_id', operator: '=', value: '5a1f0b9e-1111-4c4c-9a9a-000000000001' },
638
+ { field: 'session_id', operator: '=', value: 'guest-session' },
639
+ ],
640
+ },
641
+ { internal: true }
642
+ )
643
+ expect(selects(db)[0]).toBe(
644
+ 'SELECT * FROM teleport_favourites WHERE user_id = $1 AND session_id = $2'
645
+ )
646
+ })
647
+
648
+ it("files a guest's row under an anonymous id only, never a registered account's id (Task 2a)", async () => {
649
+ const REGISTERED = '5a1f0b9e-1111-4c4c-9a9a-00000000aaaa'
650
+ const ANONYMOUS = '5a1f0b9e-1111-4c4c-9a9a-00000000bbbb'
651
+ const insertParams = async (fallback: string): Promise<unknown[]> => {
652
+ const db = freshDb([])
653
+ db.columnTypes = { user_id: 'uuid', session_id: 'text' }
654
+ db.registered = [REGISTERED]
655
+ const api = bootDataApi(db)
656
+ await api(
657
+ 'create',
658
+ {
659
+ tableName: 'teleport_favourites',
660
+ columnMappings: [{ column: 'user_id', value: 'anonymous' }],
661
+ __anonymousUserId: fallback,
662
+ },
663
+ { internal: true }
664
+ )
665
+ return db.params[db.queries.findIndex((sql) => /^INSERT/.test(sql))]
666
+ }
667
+ // A registered account's id is never taken: the row is filed under no one.
668
+ expect(await insertParams(REGISTERED)).toEqual([null])
669
+ // An anonymous id is.
670
+ expect(await insertParams(ANONYMOUS)).toEqual([ANONYMOUS])
671
+ })
672
+
673
+ it('keeps the guest checkout confirmation and the guest booking page working through their server segments', async () => {
674
+ // The order-details lookup the editor builds: the order's number, the
675
+ // session's id ('' for a guest) and the guest's anonymous id, all bound.
676
+ const ORDER_LOOKUP =
677
+ 'SELECT o.id, o.order_number, o.total_amount FROM teleport_orders o ' +
678
+ "WHERE o.order_number = $1 AND ((o.user_id::text = $2 AND $2 <> '') OR o.user_id::text = $3)"
679
+ const db = freshDb([{ id: 'o1', order_number: 'ORD-7', total_amount: 12 }])
680
+ const api = bootDataApi(db)
681
+ const order = await api(
682
+ 'raw-query',
683
+ { query: ORDER_LOOKUP, params: ['ORD-7', '', '5a1f0b9e-1111-4c4c-9a9a-00000000bbbb'] },
684
+ { internal: true }
685
+ )
686
+ expect(order.status).toBe(200)
687
+ expect(order.body.rows).toEqual([{ id: 'o1', order_number: 'ORD-7', total_amount: 12 }])
688
+
689
+ // The booking page a guest opens from the link in their email: the
690
+ // booking's reference and its manage key.
691
+ const BOOKING_LOOKUP =
692
+ 'SELECT b.id, b.status, b.starts_at FROM teleport_bookings b WHERE b.reference = $1 AND b.manage_key = $2'
693
+ const bookingDb = freshDb([
694
+ { id: 'b1', status: 'confirmed', starts_at: '2026-11-01T10:00:00Z' },
695
+ ])
696
+ const bookingApi = bootDataApi(bookingDb)
697
+ const booking = await bookingApi(
698
+ 'raw-query',
699
+ { query: BOOKING_LOOKUP, params: ['BK-1', 'key-123'] },
700
+ { internal: true }
701
+ )
702
+ expect(booking.status).toBe(200)
703
+ expect(booking.body.rows).toHaveLength(1)
704
+ })
705
+
706
+ it('an owner filter written as a one-value "in" list still reads the session\'s own rows (M3)', async () => {
707
+ const db = freshDb([])
708
+ const api = bootDataApi(db)
709
+ await api(
710
+ 'select',
711
+ {
712
+ tableName: 'teleport_orders',
713
+ filters: [{ field: 'user_id', operator: 'in', value: ['u1'] }],
714
+ },
715
+ { internal: true, session: { id: 'u1', role: 'user' } }
716
+ )
717
+ expect(selects(db)[0]).toBe('SELECT * FROM teleport_orders WHERE user_id IN ($1)')
718
+ })
719
+ })
720
+
721
+ describe('fix round 1: browser reads through the data API', () => {
722
+ const EXPOSURE = {
723
+ tables: {
724
+ 'ds1:team_members': {
725
+ public: true,
726
+ anySession: false,
727
+ roles: [] as string[],
728
+ defaultLimit: 100,
729
+ maxLimit: 500,
730
+ },
731
+ 'ds1:member_notes': {
732
+ public: false,
733
+ anySession: true,
734
+ roles: [] as string[],
735
+ defaultLimit: 100,
736
+ maxLimit: 500,
737
+ },
738
+ },
739
+ dataSources: {},
740
+ }
741
+
742
+ it('admits a table the way its per-table route does (I6)', async () => {
743
+ const db = freshDb([])
744
+ const api = bootDataApi(db, { dataExposure: EXPOSURE })
745
+ expect((await api('select', { tableName: 'team_members' })).status).toBe(200)
746
+ expect((await api('select', { tableName: 'member_notes' })).status).toBe(403)
747
+ expect(
748
+ (await api('select', { tableName: 'member_notes' }, { session: { id: 'u1', role: 'user' } }))
749
+ .status
750
+ ).toBe(200)
751
+ // Another data source's table of the same name is not this one.
752
+ expect(
753
+ (await api('select', { tableName: 'team_members' }, { dataSourceId: 'ds2' })).status
754
+ ).toBe(403)
755
+ // A table no page binds stays the server's.
756
+ expect((await api('select', { tableName: 'contacts' })).status).toBe(403)
757
+ })
758
+
759
+ it('never lets a browser filter, sort or select by a credential column (I2)', async () => {
760
+ const db = freshDb([])
761
+ const api = bootDataApi(db, { dataExposure: EXPOSURE })
762
+ for (const body of [
763
+ { tableName: 'team_members', filters: [{ field: 'password', operator: '>', value: '$2b' }] },
764
+ { tableName: 'team_members', sorts: [{ field: 'api_key', order: 'asc' }] },
765
+ { tableName: 'team_members', selectedColumns: ['name', 'reset_token'] },
766
+ ]) {
767
+ const reply = await api('select', body)
768
+ expect(reply.status).toBe(400)
769
+ }
770
+ expect(db.queries.filter((sql) => /team_members/.test(sql))).toEqual([])
771
+ })
772
+
773
+ it('a browser read naming only an offset still gets the default count (M1)', async () => {
774
+ const db = freshDb([])
775
+ const api = bootDataApi(db)
776
+ await api('select', { tableName: 'teleport_products', skip: 40 })
777
+ expect(selects(db)[0]).toMatch(/ LIMIT 100 OFFSET 40$/)
778
+ })
779
+ })
780
+
781
+ describe("fix round 2: a visitor's own list, and the server's own jobs", () => {
782
+ const ME = { id: 'u1', email: 'me@x.com', role: 'user' }
783
+
784
+ it('"all statuses" on My Orders lists the customer\'s own orders', async () => {
785
+ const db = freshDb([])
786
+ const api = bootDataApi(db)
787
+ await api(
788
+ 'select',
789
+ {
790
+ tableName: 'teleport_orders',
791
+ filters: [
792
+ { field: 'user_id', operator: '=', value: 'u1' },
793
+ { field: 'status', operator: '=', value: 'all' },
794
+ ],
795
+ },
796
+ { internal: true, session: ME }
797
+ )
798
+ expect(selects(db)[0]).toBe('SELECT * FROM teleport_orders WHERE user_id = $1')
799
+ expect(db.params[0]).toEqual(['u1'])
800
+ })
801
+
802
+ it('an "all" never reaches another customer\'s rows (I4 still holds)', async () => {
803
+ for (const filters of [
804
+ [{ field: 'id', operator: '=', value: 'all' }],
805
+ [
806
+ { field: 'user_id', operator: '=', value: 'victim' },
807
+ { field: 'status', operator: '=', value: 'all' },
808
+ ],
809
+ ]) {
810
+ const db = freshDb([])
811
+ const api = bootDataApi(db)
812
+ await api(
813
+ 'select',
814
+ { tableName: 'teleport_orders', filters },
815
+ { internal: true, session: ME }
816
+ )
817
+ expect(selects(db)[0]).toMatch(/WHERE FALSE/)
818
+ expect(selects(db)[0]).not.toMatch(/user_id = \$1/)
819
+ }
820
+ })
821
+
822
+ it('a cron, a webhook or an automation reads customer records by owner exactly as before', async () => {
823
+ const db = freshDb([])
824
+ const api = bootDataApi(db)
825
+ await api(
826
+ 'select',
827
+ {
828
+ tableName: 'teleport_orders',
829
+ filters: [
830
+ { field: 'customer_email', operator: '=', value: 'buyer@x.com' },
831
+ { field: 'status', operator: '=', value: 'all' },
832
+ ],
833
+ },
834
+ { internal: true, job: true }
835
+ )
836
+ expect(selects(db)[0]).toBe('SELECT * FROM teleport_orders WHERE customer_email = $1')
837
+ expect(db.params[0]).toEqual(['buyer@x.com'])
838
+ })
839
+ })
840
+
841
+ describe('fix round 3: scoped by default, the guest key, raw results, the source id (N4, N5, N6, N9)', () => {
842
+ const VICTIM = 'victim@x.com'
843
+
844
+ it("an internal call that flags no server job is a visitor's: its customer reads are scoped (N9)", async () => {
845
+ const db = freshDb([{ id: 'o1' }])
846
+ const api = bootDataApi(db)
847
+ // No data node marker of any kind: the default is the visitor's.
848
+ await api(
849
+ 'select',
850
+ {
851
+ tableName: 'teleport_orders',
852
+ filters: [{ field: 'customer_email', operator: '=', value: VICTIM }],
853
+ },
854
+ { internal: true }
855
+ )
856
+ expect(selects(db)[0]).toBe('SELECT * FROM teleport_orders WHERE FALSE')
857
+ db.queries.length = 0
858
+ await api(
859
+ 'count',
860
+ {
861
+ tableName: 'teleport_orders',
862
+ filters: [{ field: 'user_id', operator: '=', value: 'all' }],
863
+ },
864
+ { internal: true }
865
+ )
866
+ expect(db.queries.filter((sql) => /^SELECT COUNT/.test(sql))[0]).toBe(
867
+ 'SELECT COUNT(*) FROM teleport_orders WHERE FALSE'
868
+ )
869
+ })
870
+
871
+ it('the server-job flag counts only with the app secret (N9)', async () => {
872
+ for (const options of [{ job: true }, { job: true, internal: true, secret: 'wrong-secret' }]) {
873
+ const db = freshDb([{ id: 'o1' }])
874
+ const api = bootDataApi(db)
875
+ const reply = await api(
876
+ 'select',
877
+ {
878
+ tableName: 'teleport_orders',
879
+ filters: [{ field: 'customer_email', operator: '=', value: VICTIM }],
880
+ },
881
+ options
882
+ )
883
+ expect(reply.status).toBe(403)
884
+ expect(selects(db)).toEqual([])
885
+ }
886
+ })
887
+
888
+ it('the data nodes send no marker of their own: the run flags its jobs in its internal headers (N9)', async () => {
889
+ const sent: any[] = []
890
+ const handler = new Function('fetch', `return (${dataSelect.generateHandler()})`)(
891
+ async (_url: string, init: any) => {
892
+ sent.push(init.headers)
893
+ return { ok: true, status: 200, json: async () => ({ rows: [] as any[], count: 0 }) }
894
+ }
895
+ )
896
+ const config = { dataSourceId: 'ds1', tableName: 'teleport_orders', filters: [] as any[] }
897
+ await handler(config, { __baseUrl: 'http://x', __internalHeaders: {}, __sessionUserId: null })
898
+ await handler(config, { __baseUrl: 'http://x', __internalHeaders: {} })
899
+ await handler(config, { __baseUrl: 'http://x', __internalHeaders: { 'x-tq-server-job': '1' } })
900
+ expect(sent.map((headers) => headers['x-tq-server-job'])).toEqual([undefined, undefined, '1'])
901
+ expect(sent.some((headers) => 'x-tq-visitor-request' in headers)).toBe(false)
902
+ })
903
+
904
+ it('a cron run flags its data calls as a server job; a segment route a visitor calls never does (N9)', async () => {
905
+ const workflow: any = {
906
+ id: 'wf-cron',
907
+ name: 'Nightly',
908
+ trigger: {
909
+ type: 'event-cron-triggered',
910
+ nodeId: 't',
911
+ scope: 'global',
912
+ config: { schedule: '0 * * * *', urlPath: 'cron_nightly' },
913
+ },
914
+ nodes: [
915
+ {
916
+ id: 'count',
917
+ type: 'data-count',
918
+ config: { dataSourceId: 'ds-1', tableName: 'teleport_orders', filters: [] },
919
+ stepNumber: 1,
920
+ label: 'Count orders',
921
+ },
922
+ ],
923
+ edges: [{ id: 'e1', source: 't', target: 'count' }],
924
+ }
925
+ const runtime = { exports: loadServerRuntime() }
926
+ const route = { exports: null as any }
927
+ new Function('module', 'exports', 'require', generateCronAPIRoute(workflow))(
928
+ route,
929
+ {},
930
+ (id: string) =>
931
+ id.endsWith('/utils/workflows/server-runtime') ? runtime.exports : require(id)
932
+ )
933
+ const key = 'k'.repeat(64)
934
+ const timestamp = String(Math.floor(Date.now() / 1000))
935
+ const path = '/api/workflows/cron_nightly'
936
+ const headers = {
937
+ host: 'shop.test',
938
+ 'x-forwarded-proto': 'https',
939
+ 'x-teleport-cron-id': 'cron-1',
940
+ 'x-teleport-project-id': 'project-1',
941
+ 'x-teleport-cron-execution-id': 'exec-1',
942
+ 'x-teleport-cron-timestamp': timestamp,
943
+ 'x-teleport-cron-signature':
944
+ 'v1=' +
945
+ crypto
946
+ .createHmac('sha256', key)
947
+ .update(`v1:${timestamp}:project-1:cron-1:exec-1:${path}`)
948
+ .digest('hex'),
949
+ }
950
+ const res = { status: () => ({ json: (): void => undefined }) }
951
+ const calls = await withEnv({ TELEPORT_CRON_SECRET: key, NEXTAUTH_SECRET: SECRET }, () =>
952
+ withFetch(
953
+ () => ({ status: 200, body: { count: 3 } }),
954
+ async (recorded) => {
955
+ await route.exports({ method: 'POST', url: path, headers, body: {} }, res)
956
+ return recorded
957
+ }
958
+ )
959
+ )
960
+ const dataCall = calls.find((call) => /\/api\/data\//.test(call.url))
961
+ expect(dataCall).toBeDefined()
962
+ expect(dataCall!.headers['x-tq-server-job']).toBe('1')
963
+ expect(dataCall!.headers['x-internal-data-secret']).toBe(SECRET)
964
+
965
+ // The webhook route and the automation run flag theirs the same way.
966
+ const flag = "context.__internalHeaders['x-tq-server-job'] = '1'"
967
+ const webhook = generateWebhookWorkflowAPIRoute({
968
+ ...workflow,
969
+ trigger: { type: 'event-webhook-triggered', nodeId: 't', scope: 'global', config: {} },
970
+ webhookConfig: { urlPath: 'hooks/x', httpMethod: 'POST', signatureSecret: '' },
971
+ })
972
+ expect(webhook).toContain(flag)
973
+ expect(
974
+ generateHandlerFunction({
975
+ ...workflow,
976
+ trigger: { ...workflow.trigger, type: 'event-business-event' },
977
+ })
978
+ ).toContain(flag)
979
+ // A segment route sets the flag only when this deployment's own server code
980
+ // called it with the flag (the internal-call token); a browser never can.
981
+ // server-job-hops-real-data-api.test.ts runs both sides end to end.
982
+ const segment: any = {
983
+ id: 'seg-1',
984
+ workflowId: 'wf-1',
985
+ executionEnv: 'server',
986
+ nodes: [
987
+ {
988
+ id: 'n1',
989
+ type: 'data-select',
990
+ config: { dataSourceId: 'ds1', tableName: 'teleport_orders' },
991
+ stepNumber: 1,
992
+ label: 'Read',
993
+ },
994
+ ],
995
+ edges: [],
996
+ }
997
+ for (const segmentRoute of [
998
+ generateServerSegmentAPIRoute(segment),
999
+ generateStreamingServerSegmentAPIRoute(segment),
1000
+ ]) {
1001
+ expect(segmentRoute).toContain(
1002
+ "if (utils.isInternalCall(req) && req.headers && req.headers['x-tq-server-job'] === '1') {"
1003
+ )
1004
+ expect(segmentRoute.split("context.__internalHeaders['x-tq-server-job'] = '1'")).toHaveLength(
1005
+ 2
1006
+ )
1007
+ }
1008
+ })
1009
+
1010
+ it('only "=" with one concrete value on a guest key binds a guest\'s read (N4)', async () => {
1011
+ for (const [operator, value] of [
1012
+ ['LIKE', '%'],
1013
+ ['!=', 'g-own'],
1014
+ ['contains', 'a'],
1015
+ ['=', '*'],
1016
+ ['=', 'all'],
1017
+ ['in', ['g-1', 'g-2']],
1018
+ ] as Array<[string, unknown]>) {
1019
+ const probeDb = freshDb([{ id: 'o1', customer_email: VICTIM }])
1020
+ const probeApi = bootDataApi(probeDb)
1021
+ await probeApi(
1022
+ 'select',
1023
+ {
1024
+ tableName: 'teleport_orders',
1025
+ filters: [
1026
+ { field: 'customer_email', operator: '=', value: VICTIM },
1027
+ { field: 'session_id', operator, value },
1028
+ ],
1029
+ },
1030
+ { internal: true }
1031
+ )
1032
+ expect({ operator, value, sql: selects(probeDb)[0] }).toEqual({
1033
+ operator,
1034
+ value,
1035
+ sql: expect.stringMatching(/^SELECT \* FROM teleport_orders WHERE FALSE\b/),
1036
+ })
1037
+ }
1038
+ // The guest's own key, with "=", still binds (the guest checkout lookup).
1039
+ const db = freshDb([{ id: 'o1' }])
1040
+ const api = bootDataApi(db)
1041
+ await api(
1042
+ 'select',
1043
+ {
1044
+ tableName: 'teleport_orders',
1045
+ filters: [
1046
+ { field: 'customer_email', operator: '=', value: VICTIM },
1047
+ { field: 'session_id', operator: '=', value: 'g-own' },
1048
+ ],
1049
+ },
1050
+ { internal: true }
1051
+ )
1052
+ expect(selects(db)[0]).toBe(
1053
+ 'SELECT * FROM teleport_orders WHERE customer_email = $1 AND session_id = $2'
1054
+ )
1055
+ })
1056
+
1057
+ it("a visitor segment's raw statement never brings back a credential, even one it names (N5)", async () => {
1058
+ const rows = [{ email: 'a@x.com', password: '$2b$hash', reset_token: 't' }]
1059
+ const statement = {
1060
+ query: 'SELECT email, password, reset_token FROM users WHERE id = $1',
1061
+ params: ['u1'],
1062
+ }
1063
+ const visitor = await bootDataApi(freshDb(rows))('raw-query', statement, {
1064
+ internal: true,
1065
+ session: { id: 'u1', role: 'user' },
1066
+ })
1067
+ expect(visitor.status).toBe(200)
1068
+ expect(visitor.body.rows).toEqual([{ email: 'a@x.com' }])
1069
+ // A staff session is still a visitor's segment: its results go to a browser.
1070
+ const staff = await bootDataApi(freshDb(rows))('raw-query', statement, {
1071
+ internal: true,
1072
+ session: { id: 'a1', role: 'admin' },
1073
+ })
1074
+ expect(staff.body.rows).toEqual([{ email: 'a@x.com' }])
1075
+ // A server job (a cron's calendar sync) and the auth layer keep what they name.
1076
+ const job = await bootDataApi(freshDb(rows))('raw-query', statement, {
1077
+ internal: true,
1078
+ job: true,
1079
+ })
1080
+ expect(job.body.rows[0]).toHaveProperty('password', '$2b$hash')
1081
+ const auth = await bootDataApi(freshDb(rows))('raw-query', statement, { authLayer: true })
1082
+ expect(auth.body.rows[0]).toHaveProperty('reset_token', 't')
1083
+ })
1084
+
1085
+ it("a browser read names the managed database's own source, never another source's same-named table (N6)", async () => {
1086
+ const dataExposure = {
1087
+ tables: {
1088
+ 'ds-mysql:customers': {
1089
+ public: true,
1090
+ anySession: false,
1091
+ roles: [] as string[],
1092
+ defaultLimit: 100,
1093
+ maxLimit: 500,
1094
+ },
1095
+ '*:team_members': {
1096
+ public: true,
1097
+ anySession: false,
1098
+ roles: [] as string[],
1099
+ defaultLimit: 100,
1100
+ maxLimit: 500,
1101
+ },
1102
+ },
1103
+ dataSources: {},
1104
+ }
1105
+ const db = freshDb([{ id: 'c1', name: 'managed-db-row' }])
1106
+ const api = bootDataApi(db, { dataExposure })
1107
+ expect(
1108
+ (await api('select', { tableName: 'customers' }, { dataSourceId: 'ds-mysql' })).status
1109
+ ).toBe(403)
1110
+ expect((await api('select', { tableName: 'customers' }, { dataSourceId: 'ds1' })).status).toBe(
1111
+ 403
1112
+ )
1113
+ expect(db.queries.filter((sql) => /FROM customers/.test(sql))).toEqual([])
1114
+ // A binding naming no source admits the managed source's table, under its id only.
1115
+ expect(
1116
+ (await api('select', { tableName: 'team_members' }, { dataSourceId: 'ds1' })).status
1117
+ ).toBe(200)
1118
+ expect(
1119
+ (await api('select', { tableName: 'team_members' }, { dataSourceId: 'ds-other' })).status
1120
+ ).toBe(403)
1121
+ // The route never even carries another source's entries.
1122
+ expect(generateDataAPIRoute({ dataExposure, managedDataSourceIds: ['ds1'] })).not.toContain(
1123
+ 'ds-mysql'
1124
+ )
1125
+ })
1126
+ })
1127
+
1128
+ describe("final wave: a private record is always the visitor's own (M2)", () => {
1129
+ const ME = { id: 'u1', email: 'Me@X.com', role: 'user' }
1130
+ const ORDERS = { id: 'uuid', user_id: 'uuid', customer_email: 'text', status: 'text' }
1131
+ const withOrders = (db: Db): Db => {
1132
+ db.tableColumns = {
1133
+ teleport_orders: ORDERS,
1134
+ teleport_order_items: { id: 'uuid', order_id: 'uuid', product_name: 'text' },
1135
+ teleport_bookings: { id: 'uuid', reference: 'text', starts_at: 'timestamp' },
1136
+ }
1137
+ return db
1138
+ }
1139
+ const countsOf = (db: Db): string[] => db.queries.filter((sql) => /^SELECT COUNT/i.test(sql))
1140
+
1141
+ it("a page's list of orders with no owner filter shows a signed-in visitor only their own", async () => {
1142
+ const db = withOrders(freshDb([{ id: 'o1' }]))
1143
+ const api = bootDataApi(db)
1144
+ await api('select', { tableName: 'teleport_orders' }, { internal: true, session: ME })
1145
+ const read = selects(db)[0]
1146
+ expect(read).toBe(
1147
+ 'SELECT * FROM teleport_orders WHERE (user_id::text = $1 OR LOWER(customer_email::text) = $2)'
1148
+ )
1149
+ expect(db.params[db.queries.indexOf(read)]).toEqual(['u1', 'me@x.com'])
1150
+ // Its count, and a filter on another key, are narrowed the same way.
1151
+ expect(countsOf(db)[0]).toBe(
1152
+ 'SELECT COUNT(*) FROM teleport_orders WHERE (user_id::text = $1 OR LOWER(customer_email::text) = $2)'
1153
+ )
1154
+ const filtered = withOrders(freshDb([]))
1155
+ await bootDataApi(filtered)(
1156
+ 'count',
1157
+ {
1158
+ tableName: 'teleport_orders',
1159
+ filters: [{ field: 'status', operator: '=', value: 'paid' }],
1160
+ },
1161
+ { internal: true, session: ME }
1162
+ )
1163
+ expect(countsOf(filtered)[0]).toBe(
1164
+ 'SELECT COUNT(*) FROM teleport_orders WHERE status = $1 AND (user_id::text = $2 OR LOWER(customer_email::text) = $3)'
1165
+ )
1166
+ expect(filtered.params[filtered.queries.indexOf(countsOf(filtered)[0])]).toEqual([
1167
+ 'paid',
1168
+ 'u1',
1169
+ 'me@x.com',
1170
+ ])
1171
+ })
1172
+
1173
+ it('a guest gets none of them without its own guest key', async () => {
1174
+ const db = withOrders(freshDb([{ id: 'o1' }]))
1175
+ await bootDataApi(db)(
1176
+ 'select',
1177
+ {
1178
+ tableName: 'teleport_orders',
1179
+ filters: [{ field: 'status', operator: '=', value: 'paid' }],
1180
+ },
1181
+ { internal: true }
1182
+ )
1183
+ expect(selects(db)[0]).toBe('SELECT * FROM teleport_orders WHERE status = $1 AND FALSE')
1184
+ // A guest's own cart, by its guest key, reads as before.
1185
+ const cart = freshDb([])
1186
+ await bootDataApi(cart)(
1187
+ 'select',
1188
+ {
1189
+ tableName: 'teleport_cart',
1190
+ filters: [{ field: 'session_id', operator: '=', value: 'g-own' }],
1191
+ },
1192
+ { internal: true }
1193
+ )
1194
+ expect(selects(cart)[0]).toBe('SELECT * FROM teleport_cart WHERE session_id = $1')
1195
+ })
1196
+
1197
+ it("an order's lines are the order's buyer's: narrowed through the order", async () => {
1198
+ const db = withOrders(freshDb([]))
1199
+ await bootDataApi(db)(
1200
+ 'select',
1201
+ {
1202
+ tableName: 'teleport_order_items',
1203
+ filters: [{ field: 'order_id', operator: '=', value: 'o-9' }],
1204
+ },
1205
+ { internal: true, session: ME }
1206
+ )
1207
+ const read = selects(db)[0]
1208
+ expect(read).toBe(
1209
+ 'SELECT * FROM teleport_order_items WHERE order_id = $1 AND order_id IN (SELECT id FROM teleport_orders WHERE (user_id::text = $2 OR LOWER(customer_email::text) = $3))'
1210
+ )
1211
+ expect(db.params[db.queries.indexOf(read)]).toEqual(['o-9', 'u1', 'me@x.com'])
1212
+ // A private table with no owner column and no parent to own it through finds nothing.
1213
+ const bookings = withOrders(freshDb([]))
1214
+ await bootDataApi(bookings)(
1215
+ 'select',
1216
+ { tableName: 'teleport_bookings' },
1217
+ { internal: true, session: ME }
1218
+ )
1219
+ expect(selects(bookings)[0]).toBe('SELECT * FROM teleport_bookings WHERE FALSE')
1220
+ })
1221
+
1222
+ it("My Orders reads as before, and the visitor's own owner filter needs no extra condition", async () => {
1223
+ const db = withOrders(freshDb([{ id: 'o1' }]))
1224
+ await bootDataApi(db)(
1225
+ 'select',
1226
+ {
1227
+ tableName: 'teleport_orders',
1228
+ filters: [
1229
+ { field: 'user_id', operator: '=', value: 'u1' },
1230
+ { field: 'status', operator: '=', value: 'all', __skippable: true },
1231
+ ],
1232
+ },
1233
+ { internal: true, session: ME }
1234
+ )
1235
+ expect(selects(db)[0]).toBe('SELECT * FROM teleport_orders WHERE user_id = $1')
1236
+ expect(db.queries.some((sql) => /information_schema/i.test(sql))).toBe(false)
1237
+ })
1238
+
1239
+ it('product reviews still list for everyone; a staff session and a server job read orders whole', async () => {
1240
+ const reviews = freshDb([{ id: 'r1', rating: 5 }])
1241
+ const listed = await bootDataApi(reviews)(
1242
+ 'select',
1243
+ {
1244
+ tableName: 'teleport_product_reviews',
1245
+ filters: [{ field: 'product_id', operator: '=', value: 'p1' }],
1246
+ },
1247
+ { internal: true }
1248
+ )
1249
+ expect(listed.body.rows).toHaveLength(1)
1250
+ expect(selects(reviews)[0]).toBe('SELECT * FROM teleport_product_reviews WHERE product_id = $1')
1251
+
1252
+ for (const options of [
1253
+ { internal: true, session: { id: 'a1', role: 'admin' } },
1254
+ { internal: true, job: true },
1255
+ ]) {
1256
+ const db = withOrders(freshDb([]))
1257
+ await bootDataApi(db)('select', { tableName: 'teleport_orders' }, options)
1258
+ expect(selects(db)[0]).toBe('SELECT * FROM teleport_orders')
1259
+ }
1260
+ })
1261
+ })
1262
+
1263
+ describe("C1 re-review: a guest's own anonymous account row is no registered account (B1)", () => {
1264
+ const GUEST = '5a1f0b9e-1111-4c4c-9a9a-00000000cccc'
1265
+ const MEMBER = '5a1f0b9e-1111-4c4c-9a9a-00000000dddd'
1266
+ const NO_EMAIL = '5a1f0b9e-1111-4c4c-9a9a-00000000eeee'
1267
+ // "Resolve Current User" writes the guest's own row before the checkout's
1268
+ // INSERT: <uuid>@anonymous.local. A real account has a real address — or,
1269
+ // signed in some other way, none at all.
1270
+ const USERS = [
1271
+ { id: GUEST, email: `${GUEST}@anonymous.local` },
1272
+ { id: MEMBER, email: 'member@x.com' },
1273
+ { id: NO_EMAIL, email: null as string | null },
1274
+ ]
1275
+ const stored = async (operation: 'create' | 'update', fallback: string): Promise<unknown> => {
1276
+ const db = freshDb([])
1277
+ db.columnTypes = { id: 'uuid', user_id: 'uuid', status: 'text' }
1278
+ db.users = USERS
1279
+ const api = bootDataApi(db)
1280
+ // The checkout's server segment: the owner bound to '' for a signed-out
1281
+ // visitor, the guest's id as the hint.
1282
+ const body =
1283
+ operation === 'create'
1284
+ ? {
1285
+ tableName: 'teleport_orders',
1286
+ columnMappings: [
1287
+ { column: 'user_id', value: '' },
1288
+ { column: 'status', value: 'pending' },
1289
+ ],
1290
+ __anonymousUserId: fallback,
1291
+ }
1292
+ : {
1293
+ tableName: 'teleport_orders',
1294
+ filters: [
1295
+ { field: 'id', operator: '=', value: '5a1f0b9e-1111-4c4c-9a9a-0000000000ff' },
1296
+ ],
1297
+ columnMappings: [{ column: 'user_id', value: '' }],
1298
+ __anonymousUserId: fallback,
1299
+ }
1300
+ const reply = await api(operation, body, { internal: true })
1301
+ expect(reply.status).toBe(200)
1302
+ const write = db.queries.findIndex((sql) =>
1303
+ (operation === 'create' ? /^INSERT/ : /^UPDATE/).test(sql)
1304
+ )
1305
+ expect(write).toBeGreaterThan(-1)
1306
+ // user_id is the first column either statement writes.
1307
+ return db.params[write][0]
1308
+ }
1309
+
1310
+ it.each(['create', 'update'] as const)(
1311
+ "%s files the order under the guest's id when its users row is the guest's anonymous one",
1312
+ async (operation) => {
1313
+ expect(await stored(operation, GUEST)).toBe(GUEST)
1314
+ }
1315
+ )
1316
+
1317
+ it.each(['create', 'update'] as const)(
1318
+ '%s never files it under a registered account, with or without an address',
1319
+ async (operation) => {
1320
+ expect(await stored(operation, MEMBER)).toBeNull()
1321
+ expect(await stored(operation, NO_EMAIL)).toBeNull()
1322
+ }
1323
+ )
1324
+ })