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

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 (787) hide show
  1. package/__tests__/_helpers/bind-workflow-utils.ts +16 -1
  2. package/__tests__/_helpers/fake-fetch.ts +96 -0
  3. package/__tests__/_helpers/fake-stripe.ts +52 -0
  4. package/__tests__/_helpers/load-handler.ts +22 -3
  5. package/__tests__/_helpers/load-invoice-route.ts +75 -0
  6. package/__tests__/_helpers/load-payment-drivers.ts +69 -0
  7. package/__tests__/_helpers/load-server-runtime.ts +33 -0
  8. package/__tests__/_helpers/run-generated-middleware.ts +50 -9
  9. package/__tests__/admin-form-hydration-target.test.ts +39 -0
  10. package/__tests__/admin-form-row-hydration.test.ts +58 -0
  11. package/__tests__/ai-select-database-data-handler.test.ts +14 -3
  12. package/__tests__/api-route-file-name-segments.test.ts +33 -0
  13. package/__tests__/app-secret-env.test.ts +55 -0
  14. package/__tests__/auth-env-secret-preservation.test.ts +22 -3
  15. package/__tests__/auth-nextauth-url.test.ts +134 -50
  16. package/__tests__/cart-add-item-kinds.test.ts +259 -0
  17. package/__tests__/cart-add-item-line-fields.test.ts +328 -0
  18. package/__tests__/cart-availability-add-to-cart.test.ts +108 -0
  19. package/__tests__/cart-get-total-discounts.test.ts +499 -0
  20. package/__tests__/cart-get-total-product-options.test.ts +195 -0
  21. package/__tests__/cart-get-total-subscriptions.test.ts +221 -0
  22. package/__tests__/cart-price-order.test.ts +283 -0
  23. package/__tests__/cart-update-item-quantity-recurring.test.ts +75 -0
  24. package/__tests__/client-loop-current-item.test.ts +164 -0
  25. package/__tests__/cron-route-loop-custom-node.test.ts +123 -0
  26. package/__tests__/cron-route-loop-templateparams.test.ts +7 -0
  27. package/__tests__/cron-route-verification.test.ts +252 -0
  28. package/__tests__/custom-js-runtime-base-url.test.ts +64 -0
  29. package/__tests__/custom-nodes-admin-module.test.ts +310 -0
  30. package/__tests__/data-api-browser-reads.test.ts +341 -0
  31. package/__tests__/data-api-low-stock-autofire.test.ts +67 -17
  32. package/__tests__/data-api-optional-feature-columns.test.ts +240 -0
  33. package/__tests__/data-api-protected-tables.test.ts +948 -0
  34. package/__tests__/data-node-not-awaited.test.ts +7 -3
  35. package/__tests__/data-write-missing-filter.test.ts +119 -0
  36. package/__tests__/ecommerce-rewriter-product-options.test.ts +143 -0
  37. package/__tests__/email-locale-senders.test.ts +1 -1
  38. package/__tests__/file-storage-upload-picked-files.test.ts +20 -0
  39. package/__tests__/input-debounce-per-field.test.ts +141 -0
  40. package/__tests__/internal-request-headers.test.ts +7 -3
  41. package/__tests__/invoice-data-access-replace.test.ts +340 -0
  42. package/__tests__/invoice-delivery-fee.test.ts +3 -2
  43. package/__tests__/invoice-generate-hydration.test.ts +20 -12
  44. package/__tests__/invoice-order-items-settle.test.ts +51 -46
  45. package/__tests__/invoice-product-options.test.ts +177 -0
  46. package/__tests__/invoice-regenerate-route.test.ts +488 -0
  47. package/__tests__/invoice-regional-tax.test.ts +3 -2
  48. package/__tests__/invoice-reservation.test.ts +195 -0
  49. package/__tests__/invoice-route-access.test.ts +275 -0
  50. package/__tests__/invoice-self-call-origin.test.ts +117 -0
  51. package/__tests__/invoice-tender.test.ts +550 -0
  52. package/__tests__/legacy-webhook-self-calls.test.ts +187 -0
  53. package/__tests__/locale-aware-redirects.test.ts +55 -26
  54. package/__tests__/loop-collection-unwrap.test.ts +6 -1
  55. package/__tests__/middleware-subscriber-access.test.ts +269 -0
  56. package/__tests__/payment-charge-user-earlier-attempt.test.ts +267 -0
  57. package/__tests__/payment-charge-user-handler-serialization.test.ts +47 -82
  58. package/__tests__/payment-charge-user-line-descriptions.test.ts +124 -0
  59. package/__tests__/payment-charge-user-report-refusal.test.ts +105 -0
  60. package/__tests__/payment-close-checkout-node.test.ts +127 -0
  61. package/__tests__/payment-driver-close-checkout.test.ts +1163 -0
  62. package/__tests__/payment-driver-coingate.test.ts +470 -0
  63. package/__tests__/payment-driver-inspect-checkout.test.ts +648 -0
  64. package/__tests__/payment-driver-mollie.test.ts +864 -0
  65. package/__tests__/payment-driver-paddle.test.ts +870 -0
  66. package/__tests__/payment-driver-paypal-capture.test.ts +158 -0
  67. package/__tests__/payment-driver-paypal-webhook.test.ts +367 -0
  68. package/__tests__/payment-driver-razorpay.test.ts +895 -0
  69. package/__tests__/payment-driver-square.test.ts +977 -0
  70. package/__tests__/payment-driver-stripe.test.ts +267 -0
  71. package/__tests__/payment-drivers-module.test.ts +429 -0
  72. package/__tests__/payment-legacy-webhook-routes.test.ts +588 -0
  73. package/__tests__/payment-redirect-and-order-notification.test.ts +98 -39
  74. package/__tests__/payment-refund.test.ts +523 -22
  75. package/__tests__/payment-subscription-nodes.test.ts +1360 -0
  76. package/__tests__/payment-webhook-route.test.ts +523 -0
  77. package/__tests__/paypal-webhook-signature-verification.test.ts +205 -0
  78. package/__tests__/prune-context-oversized-leaf.test.ts +1 -0
  79. package/__tests__/prune-context-state-keys.test.ts +89 -0
  80. package/__tests__/push-node-handlers.test.ts +291 -0
  81. package/__tests__/route-changed-trigger.test.ts +40 -0
  82. package/__tests__/runtime-storage-upload-access.test.ts +255 -0
  83. package/__tests__/security-runtime-shadow.test.ts +103 -1
  84. package/__tests__/segment-reply-changed-keys.test.ts +146 -0
  85. package/__tests__/segment-state-keys-emission.test.ts +185 -0
  86. package/__tests__/segment-state-needs.test.ts +102 -0
  87. package/__tests__/server-segment-context-integrity.test.ts +210 -0
  88. package/__tests__/server-step-signing.test.ts +371 -0
  89. package/__tests__/session-cookie-resolver.test.ts +59 -0
  90. package/__tests__/stock-decrement-audit.test.ts +17 -0
  91. package/__tests__/subscriber-access-route.test.ts +406 -0
  92. package/__tests__/webhook-delivery-lease.test.ts +316 -0
  93. package/__tests__/workflow-auth-guard.test.ts +253 -2
  94. package/dist/cjs/admin-form-hydration.d.ts +10 -0
  95. package/dist/cjs/admin-form-hydration.d.ts.map +1 -0
  96. package/dist/cjs/admin-form-hydration.js +25 -0
  97. package/dist/cjs/admin-form-hydration.js.map +1 -0
  98. package/dist/cjs/api-route-generator.d.ts +19 -3
  99. package/dist/cjs/api-route-generator.d.ts.map +1 -1
  100. package/dist/cjs/api-route-generator.js +190 -70
  101. package/dist/cjs/api-route-generator.js.map +1 -1
  102. package/dist/cjs/auth-generator.d.ts +4 -1
  103. package/dist/cjs/auth-generator.d.ts.map +1 -1
  104. package/dist/cjs/auth-generator.js +241 -62
  105. package/dist/cjs/auth-generator.js.map +1 -1
  106. package/dist/cjs/auth-return/signed-in-destination-code.d.ts +17 -0
  107. package/dist/cjs/auth-return/signed-in-destination-code.d.ts.map +1 -0
  108. package/dist/cjs/auth-return/signed-in-destination-code.js +37 -0
  109. package/dist/cjs/auth-return/signed-in-destination-code.js.map +1 -0
  110. package/dist/cjs/cart-pricing-preamble.d.ts +12 -0
  111. package/dist/cjs/cart-pricing-preamble.d.ts.map +1 -0
  112. package/dist/cjs/cart-pricing-preamble.js +23 -0
  113. package/dist/cjs/cart-pricing-preamble.js.map +1 -0
  114. package/dist/cjs/cron-request-verification.d.ts +24 -0
  115. package/dist/cjs/cron-request-verification.d.ts.map +1 -0
  116. package/dist/cjs/cron-request-verification.js +84 -0
  117. package/dist/cjs/cron-request-verification.js.map +1 -0
  118. package/dist/cjs/custom-node-modules.d.ts +30 -0
  119. package/dist/cjs/custom-node-modules.d.ts.map +1 -0
  120. package/dist/cjs/custom-node-modules.js +90 -0
  121. package/dist/cjs/custom-node-modules.js.map +1 -0
  122. package/dist/cjs/data-api-route-generator.d.ts +27 -0
  123. package/dist/cjs/data-api-route-generator.d.ts.map +1 -1
  124. package/dist/cjs/data-api-route-generator.js +366 -29
  125. package/dist/cjs/data-api-route-generator.js.map +1 -1
  126. package/dist/cjs/ecommerce/cart-availability.d.ts.map +1 -1
  127. package/dist/cjs/ecommerce/cart-availability.js +22 -13
  128. package/dist/cjs/ecommerce/cart-availability.js.map +1 -1
  129. package/dist/cjs/ecommerce/stock-decrement.d.ts +2 -1
  130. package/dist/cjs/ecommerce/stock-decrement.d.ts.map +1 -1
  131. package/dist/cjs/ecommerce/stock-decrement.js +6 -0
  132. package/dist/cjs/ecommerce/stock-decrement.js.map +1 -1
  133. package/dist/cjs/executor-generator.d.ts +0 -1
  134. package/dist/cjs/executor-generator.d.ts.map +1 -1
  135. package/dist/cjs/executor-generator.js +213 -20
  136. package/dist/cjs/executor-generator.js.map +1 -1
  137. package/dist/cjs/index.d.ts +12 -4
  138. package/dist/cjs/index.d.ts.map +1 -1
  139. package/dist/cjs/index.js +25 -2
  140. package/dist/cjs/index.js.map +1 -1
  141. package/dist/cjs/invoice/api-routes-code.d.ts +26 -0
  142. package/dist/cjs/invoice/api-routes-code.d.ts.map +1 -1
  143. package/dist/cjs/invoice/api-routes-code.js +423 -391
  144. package/dist/cjs/invoice/api-routes-code.js.map +1 -1
  145. package/dist/cjs/invoice/data-access-code.d.ts.map +1 -1
  146. package/dist/cjs/invoice/data-access-code.js +420 -107
  147. package/dist/cjs/invoice/data-access-code.js.map +1 -1
  148. package/dist/cjs/invoice/index.d.ts.map +1 -1
  149. package/dist/cjs/invoice/index.js +24 -0
  150. package/dist/cjs/invoice/index.js.map +1 -1
  151. package/dist/cjs/invoice/invoice-assembly-code.d.ts +12 -0
  152. package/dist/cjs/invoice/invoice-assembly-code.d.ts.map +1 -0
  153. package/dist/cjs/invoice/invoice-assembly-code.js +517 -0
  154. package/dist/cjs/invoice/invoice-assembly-code.js.map +1 -0
  155. package/dist/cjs/invoice/invoice-html-code.d.ts.map +1 -1
  156. package/dist/cjs/invoice/invoice-html-code.js +111 -9
  157. package/dist/cjs/invoice/invoice-html-code.js.map +1 -1
  158. package/dist/cjs/invoice/pdf-service-client-code.d.ts.map +1 -1
  159. package/dist/cjs/invoice/pdf-service-client-code.js +3 -4
  160. package/dist/cjs/invoice/pdf-service-client-code.js.map +1 -1
  161. package/dist/cjs/nodes/account/account-login.d.ts.map +1 -1
  162. package/dist/cjs/nodes/account/account-login.js +4 -3
  163. package/dist/cjs/nodes/account/account-login.js.map +1 -1
  164. package/dist/cjs/nodes/account/account-signup.d.ts.map +1 -1
  165. package/dist/cjs/nodes/account/account-signup.js +7 -4
  166. package/dist/cjs/nodes/account/account-signup.js.map +1 -1
  167. package/dist/cjs/nodes/ai/ai-select-database-data.d.ts.map +1 -1
  168. package/dist/cjs/nodes/ai/ai-select-database-data.js +6 -1
  169. package/dist/cjs/nodes/ai/ai-select-database-data.js.map +1 -1
  170. package/dist/cjs/nodes/browser/browser-get-push-subscription.d.ts +9 -0
  171. package/dist/cjs/nodes/browser/browser-get-push-subscription.d.ts.map +1 -0
  172. package/dist/cjs/nodes/browser/browser-get-push-subscription.js +25 -0
  173. package/dist/cjs/nodes/browser/browser-get-push-subscription.js.map +1 -0
  174. package/dist/cjs/nodes/browser/browser-show-notification.d.ts +10 -0
  175. package/dist/cjs/nodes/browser/browser-show-notification.d.ts.map +1 -1
  176. package/dist/cjs/nodes/browser/browser-show-notification.js +65 -40
  177. package/dist/cjs/nodes/browser/browser-show-notification.js.map +1 -1
  178. package/dist/cjs/nodes/browser/browser-subscribe-to-push.d.ts +11 -0
  179. package/dist/cjs/nodes/browser/browser-subscribe-to-push.d.ts.map +1 -1
  180. package/dist/cjs/nodes/browser/browser-subscribe-to-push.js +21 -31
  181. package/dist/cjs/nodes/browser/browser-subscribe-to-push.js.map +1 -1
  182. package/dist/cjs/nodes/browser/browser-unsubscribe-from-push.d.ts +8 -0
  183. package/dist/cjs/nodes/browser/browser-unsubscribe-from-push.d.ts.map +1 -0
  184. package/dist/cjs/nodes/browser/browser-unsubscribe-from-push.js +24 -0
  185. package/dist/cjs/nodes/browser/browser-unsubscribe-from-push.js.map +1 -0
  186. package/dist/cjs/nodes/browser/push-api-access.d.ts +12 -0
  187. package/dist/cjs/nodes/browser/push-api-access.d.ts.map +1 -0
  188. package/dist/cjs/nodes/browser/push-api-access.js +19 -0
  189. package/dist/cjs/nodes/browser/push-api-access.js.map +1 -0
  190. package/dist/cjs/nodes/cart/cart-add-item.d.ts.map +1 -1
  191. package/dist/cjs/nodes/cart/cart-add-item.js +174 -10
  192. package/dist/cjs/nodes/cart/cart-add-item.js.map +1 -1
  193. package/dist/cjs/nodes/cart/cart-clear.d.ts.map +1 -1
  194. package/dist/cjs/nodes/cart/cart-clear.js +11 -0
  195. package/dist/cjs/nodes/cart/cart-clear.js.map +1 -1
  196. package/dist/cjs/nodes/cart/cart-get-total.d.ts.map +1 -1
  197. package/dist/cjs/nodes/cart/cart-get-total.js +260 -3
  198. package/dist/cjs/nodes/cart/cart-get-total.js.map +1 -1
  199. package/dist/cjs/nodes/cart/cart-price-order.d.ts +3 -0
  200. package/dist/cjs/nodes/cart/cart-price-order.d.ts.map +1 -0
  201. package/dist/cjs/nodes/cart/cart-price-order.js +281 -0
  202. package/dist/cjs/nodes/cart/cart-price-order.js.map +1 -0
  203. package/dist/cjs/nodes/cart/cart-update-item-quantity.d.ts.map +1 -1
  204. package/dist/cjs/nodes/cart/cart-update-item-quantity.js +7 -0
  205. package/dist/cjs/nodes/cart/cart-update-item-quantity.js.map +1 -1
  206. package/dist/cjs/nodes/data/data-count.d.ts.map +1 -1
  207. package/dist/cjs/nodes/data/data-count.js +6 -1
  208. package/dist/cjs/nodes/data/data-count.js.map +1 -1
  209. package/dist/cjs/nodes/data/data-create-item.d.ts.map +1 -1
  210. package/dist/cjs/nodes/data/data-create-item.js +11 -1
  211. package/dist/cjs/nodes/data/data-create-item.js.map +1 -1
  212. package/dist/cjs/nodes/data/data-delete-item.d.ts.map +1 -1
  213. package/dist/cjs/nodes/data/data-delete-item.js +29 -0
  214. package/dist/cjs/nodes/data/data-delete-item.js.map +1 -1
  215. package/dist/cjs/nodes/data/data-raw-query.d.ts.map +1 -1
  216. package/dist/cjs/nodes/data/data-raw-query.js +6 -1
  217. package/dist/cjs/nodes/data/data-raw-query.js.map +1 -1
  218. package/dist/cjs/nodes/data/data-select.d.ts.map +1 -1
  219. package/dist/cjs/nodes/data/data-select.js +6 -1
  220. package/dist/cjs/nodes/data/data-select.js.map +1 -1
  221. package/dist/cjs/nodes/data/data-update-item.d.ts.map +1 -1
  222. package/dist/cjs/nodes/data/data-update-item.js +29 -0
  223. package/dist/cjs/nodes/data/data-update-item.js.map +1 -1
  224. package/dist/cjs/nodes/ecommerce/ecommerce-generate-invoice.d.ts.map +1 -1
  225. package/dist/cjs/nodes/ecommerce/ecommerce-generate-invoice.js +7 -1
  226. package/dist/cjs/nodes/ecommerce/ecommerce-generate-invoice.js.map +1 -1
  227. package/dist/cjs/nodes/file-storage/file-storage-upload.d.ts.map +1 -1
  228. package/dist/cjs/nodes/file-storage/file-storage-upload.js +7 -0
  229. package/dist/cjs/nodes/file-storage/file-storage-upload.js.map +1 -1
  230. package/dist/cjs/nodes/general/general-custom-js.d.ts.map +1 -1
  231. package/dist/cjs/nodes/general/general-custom-js.js +21 -5
  232. package/dist/cjs/nodes/general/general-custom-js.js.map +1 -1
  233. package/dist/cjs/nodes/index.d.ts.map +1 -1
  234. package/dist/cjs/nodes/index.js +9 -4
  235. package/dist/cjs/nodes/index.js.map +1 -1
  236. package/dist/cjs/nodes/payment/payment-billing-portal.d.ts +3 -0
  237. package/dist/cjs/nodes/payment/payment-billing-portal.d.ts.map +1 -0
  238. package/dist/cjs/nodes/payment/payment-billing-portal.js +52 -0
  239. package/dist/cjs/nodes/payment/payment-billing-portal.js.map +1 -0
  240. package/dist/cjs/nodes/payment/payment-charge-user.d.ts.map +1 -1
  241. package/dist/cjs/nodes/payment/payment-charge-user.js +227 -360
  242. package/dist/cjs/nodes/payment/payment-charge-user.js.map +1 -1
  243. package/dist/cjs/nodes/payment/payment-close-checkout.d.ts +3 -0
  244. package/dist/cjs/nodes/payment/payment-close-checkout.d.ts.map +1 -0
  245. package/dist/cjs/nodes/payment/payment-close-checkout.js +141 -0
  246. package/dist/cjs/nodes/payment/payment-close-checkout.js.map +1 -0
  247. package/dist/cjs/nodes/payment/payment-ensure-subscription-plan.d.ts +3 -0
  248. package/dist/cjs/nodes/payment/payment-ensure-subscription-plan.d.ts.map +1 -0
  249. package/dist/cjs/nodes/payment/payment-ensure-subscription-plan.js +67 -0
  250. package/dist/cjs/nodes/payment/payment-ensure-subscription-plan.js.map +1 -0
  251. package/dist/cjs/nodes/payment/payment-manage-subscription.d.ts +3 -0
  252. package/dist/cjs/nodes/payment/payment-manage-subscription.d.ts.map +1 -0
  253. package/dist/cjs/nodes/payment/payment-manage-subscription.js +89 -0
  254. package/dist/cjs/nodes/payment/payment-manage-subscription.js.map +1 -0
  255. package/dist/cjs/nodes/payment/payment-refund.d.ts.map +1 -1
  256. package/dist/cjs/nodes/payment/payment-refund.js +50 -404
  257. package/dist/cjs/nodes/payment/payment-refund.js.map +1 -1
  258. package/dist/cjs/nodes/push/push-send-notification.d.ts +14 -0
  259. package/dist/cjs/nodes/push/push-send-notification.d.ts.map +1 -0
  260. package/dist/cjs/nodes/push/push-send-notification.js +83 -0
  261. package/dist/cjs/nodes/push/push-send-notification.js.map +1 -0
  262. package/dist/cjs/payments/drivers/coingate-driver-code.d.ts +16 -0
  263. package/dist/cjs/payments/drivers/coingate-driver-code.d.ts.map +1 -0
  264. package/dist/cjs/payments/drivers/coingate-driver-code.js +471 -0
  265. package/dist/cjs/payments/drivers/coingate-driver-code.js.map +1 -0
  266. package/dist/cjs/payments/drivers/mollie-driver-code.d.ts +16 -0
  267. package/dist/cjs/payments/drivers/mollie-driver-code.d.ts.map +1 -0
  268. package/dist/cjs/payments/drivers/mollie-driver-code.js +623 -0
  269. package/dist/cjs/payments/drivers/mollie-driver-code.js.map +1 -0
  270. package/dist/cjs/payments/drivers/paddle-driver-code.d.ts +12 -0
  271. package/dist/cjs/payments/drivers/paddle-driver-code.d.ts.map +1 -0
  272. package/dist/cjs/payments/drivers/paddle-driver-code.js +683 -0
  273. package/dist/cjs/payments/drivers/paddle-driver-code.js.map +1 -0
  274. package/dist/cjs/payments/drivers/paypal-driver-code.d.ts +12 -0
  275. package/dist/cjs/payments/drivers/paypal-driver-code.d.ts.map +1 -0
  276. package/dist/cjs/payments/drivers/paypal-driver-code.js +1261 -0
  277. package/dist/cjs/payments/drivers/paypal-driver-code.js.map +1 -0
  278. package/dist/cjs/payments/drivers/razorpay-driver-code.d.ts +12 -0
  279. package/dist/cjs/payments/drivers/razorpay-driver-code.d.ts.map +1 -0
  280. package/dist/cjs/payments/drivers/razorpay-driver-code.js +732 -0
  281. package/dist/cjs/payments/drivers/razorpay-driver-code.js.map +1 -0
  282. package/dist/cjs/payments/drivers/square-driver-code.d.ts +14 -0
  283. package/dist/cjs/payments/drivers/square-driver-code.d.ts.map +1 -0
  284. package/dist/cjs/payments/drivers/square-driver-code.js +931 -0
  285. package/dist/cjs/payments/drivers/square-driver-code.js.map +1 -0
  286. package/dist/cjs/payments/drivers/stripe-driver-code.d.ts +12 -0
  287. package/dist/cjs/payments/drivers/stripe-driver-code.d.ts.map +1 -0
  288. package/dist/cjs/payments/drivers/stripe-driver-code.js +778 -0
  289. package/dist/cjs/payments/drivers/stripe-driver-code.js.map +1 -0
  290. package/dist/cjs/payments/index.d.ts +66 -0
  291. package/dist/cjs/payments/index.d.ts.map +1 -0
  292. package/dist/cjs/payments/index.js +175 -0
  293. package/dist/cjs/payments/index.js.map +1 -0
  294. package/dist/cjs/payments/payment-core-code.d.ts +19 -0
  295. package/dist/cjs/payments/payment-core-code.d.ts.map +1 -0
  296. package/dist/cjs/payments/payment-core-code.js +422 -0
  297. package/dist/cjs/payments/payment-core-code.js.map +1 -0
  298. package/dist/cjs/payments/payment-driver-code-map.d.ts +4 -0
  299. package/dist/cjs/payments/payment-driver-code-map.d.ts.map +1 -0
  300. package/dist/cjs/payments/payment-driver-code-map.js +21 -0
  301. package/dist/cjs/payments/payment-driver-code-map.js.map +1 -0
  302. package/dist/cjs/payments/payment-drivers-scope.d.ts +35 -0
  303. package/dist/cjs/payments/payment-drivers-scope.d.ts.map +1 -0
  304. package/dist/cjs/payments/payment-drivers-scope.js +56 -0
  305. package/dist/cjs/payments/payment-drivers-scope.js.map +1 -0
  306. package/dist/cjs/payments/payment-registry-code.d.ts +8 -0
  307. package/dist/cjs/payments/payment-registry-code.d.ts.map +1 -0
  308. package/dist/cjs/payments/payment-registry-code.js +41 -0
  309. package/dist/cjs/payments/payment-registry-code.js.map +1 -0
  310. package/dist/cjs/pg-client-code.d.ts +10 -0
  311. package/dist/cjs/pg-client-code.d.ts.map +1 -1
  312. package/dist/cjs/pg-client-code.js +27 -1
  313. package/dist/cjs/pg-client-code.js.map +1 -1
  314. package/dist/cjs/runtime-storage-generator.d.ts +28 -0
  315. package/dist/cjs/runtime-storage-generator.d.ts.map +1 -1
  316. package/dist/cjs/runtime-storage-generator.js +240 -5
  317. package/dist/cjs/runtime-storage-generator.js.map +1 -1
  318. package/dist/cjs/secret-collector.d.ts.map +1 -1
  319. package/dist/cjs/secret-collector.js +8 -3
  320. package/dist/cjs/secret-collector.js.map +1 -1
  321. package/dist/cjs/security-scanner.d.ts +10 -1
  322. package/dist/cjs/security-scanner.d.ts.map +1 -1
  323. package/dist/cjs/security-scanner.js +19 -1
  324. package/dist/cjs/security-scanner.js.map +1 -1
  325. package/dist/cjs/segment-context-needs.d.ts +38 -0
  326. package/dist/cjs/segment-context-needs.d.ts.map +1 -0
  327. package/dist/cjs/segment-context-needs.js +129 -0
  328. package/dist/cjs/segment-context-needs.js.map +1 -0
  329. package/dist/cjs/segment-splitter.d.ts.map +1 -1
  330. package/dist/cjs/segment-splitter.js +6 -1
  331. package/dist/cjs/segment-splitter.js.map +1 -1
  332. package/dist/cjs/segment-trust.d.ts +50 -0
  333. package/dist/cjs/segment-trust.d.ts.map +1 -0
  334. package/dist/cjs/segment-trust.js +115 -0
  335. package/dist/cjs/segment-trust.js.map +1 -0
  336. package/dist/cjs/sent-email-log/sent-email-log-code.d.ts +19 -0
  337. package/dist/cjs/sent-email-log/sent-email-log-code.d.ts.map +1 -1
  338. package/dist/cjs/sent-email-log/sent-email-log-code.js +1 -24
  339. package/dist/cjs/sent-email-log/sent-email-log-code.js.map +1 -1
  340. package/dist/cjs/server-runtime-code.d.ts +34 -0
  341. package/dist/cjs/server-runtime-code.d.ts.map +1 -0
  342. package/dist/cjs/server-runtime-code.js +303 -0
  343. package/dist/cjs/server-runtime-code.js.map +1 -0
  344. package/dist/cjs/session-cookie-resolver.d.ts +3 -78
  345. package/dist/cjs/session-cookie-resolver.d.ts.map +1 -1
  346. package/dist/cjs/session-cookie-resolver.js +7 -276
  347. package/dist/cjs/session-cookie-resolver.js.map +1 -1
  348. package/dist/cjs/subscriber-access-route-generator.d.ts +71 -0
  349. package/dist/cjs/subscriber-access-route-generator.d.ts.map +1 -0
  350. package/dist/cjs/subscriber-access-route-generator.js +301 -0
  351. package/dist/cjs/subscriber-access-route-generator.js.map +1 -0
  352. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  353. package/dist/cjs/types.d.ts +6 -0
  354. package/dist/cjs/types.d.ts.map +1 -1
  355. package/dist/cjs/webhook-delivery-lease/index.d.ts +8 -0
  356. package/dist/cjs/webhook-delivery-lease/index.d.ts.map +1 -0
  357. package/dist/cjs/webhook-delivery-lease/index.js +41 -0
  358. package/dist/cjs/webhook-delivery-lease/index.js.map +1 -0
  359. package/dist/cjs/webhook-delivery-lease/webhook-delivery-lease-code.d.ts +26 -0
  360. package/dist/cjs/webhook-delivery-lease/webhook-delivery-lease-code.d.ts.map +1 -0
  361. package/dist/cjs/webhook-delivery-lease/webhook-delivery-lease-code.js +151 -0
  362. package/dist/cjs/webhook-delivery-lease/webhook-delivery-lease-code.js.map +1 -0
  363. package/dist/cjs/webhook-delivery-lease/webhook-delivery-lease-scope.d.ts +16 -0
  364. package/dist/cjs/webhook-delivery-lease/webhook-delivery-lease-scope.d.ts.map +1 -0
  365. package/dist/cjs/webhook-delivery-lease/webhook-delivery-lease-scope.js +19 -0
  366. package/dist/cjs/webhook-delivery-lease/webhook-delivery-lease-scope.js.map +1 -0
  367. package/dist/cjs/webhook-generator.d.ts +1 -1
  368. package/dist/cjs/webhook-generator.d.ts.map +1 -1
  369. package/dist/cjs/webhook-generator.js +342 -254
  370. package/dist/cjs/webhook-generator.js.map +1 -1
  371. package/dist/cjs/webhook-signature-verification.d.ts +17 -1
  372. package/dist/cjs/webhook-signature-verification.d.ts.map +1 -1
  373. package/dist/cjs/webhook-signature-verification.js +182 -27
  374. package/dist/cjs/webhook-signature-verification.js.map +1 -1
  375. package/dist/cjs/workflow-auth-generator.d.ts +9 -6
  376. package/dist/cjs/workflow-auth-generator.d.ts.map +1 -1
  377. package/dist/cjs/workflow-auth-generator.js +133 -29
  378. package/dist/cjs/workflow-auth-generator.js.map +1 -1
  379. package/dist/cjs/workflow-component-plugin.d.ts.map +1 -1
  380. package/dist/cjs/workflow-component-plugin.js +65 -28
  381. package/dist/cjs/workflow-component-plugin.js.map +1 -1
  382. package/dist/cjs/workflow-project-plugin.d.ts +13 -0
  383. package/dist/cjs/workflow-project-plugin.d.ts.map +1 -1
  384. package/dist/cjs/workflow-project-plugin.js +215 -65
  385. package/dist/cjs/workflow-project-plugin.js.map +1 -1
  386. package/dist/esm/admin-form-hydration.d.ts +10 -0
  387. package/dist/esm/admin-form-hydration.d.ts.map +1 -0
  388. package/dist/esm/admin-form-hydration.js +21 -0
  389. package/dist/esm/admin-form-hydration.js.map +1 -0
  390. package/dist/esm/api-route-generator.d.ts +19 -3
  391. package/dist/esm/api-route-generator.d.ts.map +1 -1
  392. package/dist/esm/api-route-generator.js +189 -70
  393. package/dist/esm/api-route-generator.js.map +1 -1
  394. package/dist/esm/auth-generator.d.ts +4 -1
  395. package/dist/esm/auth-generator.d.ts.map +1 -1
  396. package/dist/esm/auth-generator.js +241 -62
  397. package/dist/esm/auth-generator.js.map +1 -1
  398. package/dist/esm/auth-return/signed-in-destination-code.d.ts +17 -0
  399. package/dist/esm/auth-return/signed-in-destination-code.d.ts.map +1 -0
  400. package/dist/esm/auth-return/signed-in-destination-code.js +33 -0
  401. package/dist/esm/auth-return/signed-in-destination-code.js.map +1 -0
  402. package/dist/esm/cart-pricing-preamble.d.ts +12 -0
  403. package/dist/esm/cart-pricing-preamble.d.ts.map +1 -0
  404. package/dist/esm/cart-pricing-preamble.js +19 -0
  405. package/dist/esm/cart-pricing-preamble.js.map +1 -0
  406. package/dist/esm/cron-request-verification.d.ts +24 -0
  407. package/dist/esm/cron-request-verification.d.ts.map +1 -0
  408. package/dist/esm/cron-request-verification.js +80 -0
  409. package/dist/esm/cron-request-verification.js.map +1 -0
  410. package/dist/esm/custom-node-modules.d.ts +30 -0
  411. package/dist/esm/custom-node-modules.d.ts.map +1 -0
  412. package/dist/esm/custom-node-modules.js +84 -0
  413. package/dist/esm/custom-node-modules.js.map +1 -0
  414. package/dist/esm/data-api-route-generator.d.ts +27 -0
  415. package/dist/esm/data-api-route-generator.d.ts.map +1 -1
  416. package/dist/esm/data-api-route-generator.js +365 -28
  417. package/dist/esm/data-api-route-generator.js.map +1 -1
  418. package/dist/esm/ecommerce/cart-availability.d.ts.map +1 -1
  419. package/dist/esm/ecommerce/cart-availability.js +22 -13
  420. package/dist/esm/ecommerce/cart-availability.js.map +1 -1
  421. package/dist/esm/ecommerce/stock-decrement.d.ts +2 -1
  422. package/dist/esm/ecommerce/stock-decrement.d.ts.map +1 -1
  423. package/dist/esm/ecommerce/stock-decrement.js +6 -0
  424. package/dist/esm/ecommerce/stock-decrement.js.map +1 -1
  425. package/dist/esm/executor-generator.d.ts +0 -1
  426. package/dist/esm/executor-generator.d.ts.map +1 -1
  427. package/dist/esm/executor-generator.js +212 -18
  428. package/dist/esm/executor-generator.js.map +1 -1
  429. package/dist/esm/index.d.ts +12 -4
  430. package/dist/esm/index.d.ts.map +1 -1
  431. package/dist/esm/index.js +10 -4
  432. package/dist/esm/index.js.map +1 -1
  433. package/dist/esm/invoice/api-routes-code.d.ts +26 -0
  434. package/dist/esm/invoice/api-routes-code.d.ts.map +1 -1
  435. package/dist/esm/invoice/api-routes-code.js +421 -390
  436. package/dist/esm/invoice/api-routes-code.js.map +1 -1
  437. package/dist/esm/invoice/data-access-code.d.ts.map +1 -1
  438. package/dist/esm/invoice/data-access-code.js +420 -107
  439. package/dist/esm/invoice/data-access-code.js.map +1 -1
  440. package/dist/esm/invoice/index.d.ts.map +1 -1
  441. package/dist/esm/invoice/index.js +25 -1
  442. package/dist/esm/invoice/index.js.map +1 -1
  443. package/dist/esm/invoice/invoice-assembly-code.d.ts +12 -0
  444. package/dist/esm/invoice/invoice-assembly-code.d.ts.map +1 -0
  445. package/dist/esm/invoice/invoice-assembly-code.js +513 -0
  446. package/dist/esm/invoice/invoice-assembly-code.js.map +1 -0
  447. package/dist/esm/invoice/invoice-html-code.d.ts.map +1 -1
  448. package/dist/esm/invoice/invoice-html-code.js +111 -9
  449. package/dist/esm/invoice/invoice-html-code.js.map +1 -1
  450. package/dist/esm/invoice/pdf-service-client-code.d.ts.map +1 -1
  451. package/dist/esm/invoice/pdf-service-client-code.js +3 -4
  452. package/dist/esm/invoice/pdf-service-client-code.js.map +1 -1
  453. package/dist/esm/nodes/account/account-login.d.ts.map +1 -1
  454. package/dist/esm/nodes/account/account-login.js +4 -3
  455. package/dist/esm/nodes/account/account-login.js.map +1 -1
  456. package/dist/esm/nodes/account/account-signup.d.ts.map +1 -1
  457. package/dist/esm/nodes/account/account-signup.js +7 -4
  458. package/dist/esm/nodes/account/account-signup.js.map +1 -1
  459. package/dist/esm/nodes/ai/ai-select-database-data.d.ts.map +1 -1
  460. package/dist/esm/nodes/ai/ai-select-database-data.js +6 -1
  461. package/dist/esm/nodes/ai/ai-select-database-data.js.map +1 -1
  462. package/dist/esm/nodes/browser/browser-get-push-subscription.d.ts +9 -0
  463. package/dist/esm/nodes/browser/browser-get-push-subscription.d.ts.map +1 -0
  464. package/dist/esm/nodes/browser/browser-get-push-subscription.js +22 -0
  465. package/dist/esm/nodes/browser/browser-get-push-subscription.js.map +1 -0
  466. package/dist/esm/nodes/browser/browser-show-notification.d.ts +10 -0
  467. package/dist/esm/nodes/browser/browser-show-notification.d.ts.map +1 -1
  468. package/dist/esm/nodes/browser/browser-show-notification.js +65 -40
  469. package/dist/esm/nodes/browser/browser-show-notification.js.map +1 -1
  470. package/dist/esm/nodes/browser/browser-subscribe-to-push.d.ts +11 -0
  471. package/dist/esm/nodes/browser/browser-subscribe-to-push.d.ts.map +1 -1
  472. package/dist/esm/nodes/browser/browser-subscribe-to-push.js +21 -31
  473. package/dist/esm/nodes/browser/browser-subscribe-to-push.js.map +1 -1
  474. package/dist/esm/nodes/browser/browser-unsubscribe-from-push.d.ts +8 -0
  475. package/dist/esm/nodes/browser/browser-unsubscribe-from-push.d.ts.map +1 -0
  476. package/dist/esm/nodes/browser/browser-unsubscribe-from-push.js +21 -0
  477. package/dist/esm/nodes/browser/browser-unsubscribe-from-push.js.map +1 -0
  478. package/dist/esm/nodes/browser/push-api-access.d.ts +12 -0
  479. package/dist/esm/nodes/browser/push-api-access.d.ts.map +1 -0
  480. package/dist/esm/nodes/browser/push-api-access.js +13 -0
  481. package/dist/esm/nodes/browser/push-api-access.js.map +1 -0
  482. package/dist/esm/nodes/cart/cart-add-item.d.ts.map +1 -1
  483. package/dist/esm/nodes/cart/cart-add-item.js +174 -10
  484. package/dist/esm/nodes/cart/cart-add-item.js.map +1 -1
  485. package/dist/esm/nodes/cart/cart-clear.d.ts.map +1 -1
  486. package/dist/esm/nodes/cart/cart-clear.js +11 -0
  487. package/dist/esm/nodes/cart/cart-clear.js.map +1 -1
  488. package/dist/esm/nodes/cart/cart-get-total.d.ts.map +1 -1
  489. package/dist/esm/nodes/cart/cart-get-total.js +261 -4
  490. package/dist/esm/nodes/cart/cart-get-total.js.map +1 -1
  491. package/dist/esm/nodes/cart/cart-price-order.d.ts +3 -0
  492. package/dist/esm/nodes/cart/cart-price-order.d.ts.map +1 -0
  493. package/dist/esm/nodes/cart/cart-price-order.js +278 -0
  494. package/dist/esm/nodes/cart/cart-price-order.js.map +1 -0
  495. package/dist/esm/nodes/cart/cart-update-item-quantity.d.ts.map +1 -1
  496. package/dist/esm/nodes/cart/cart-update-item-quantity.js +7 -0
  497. package/dist/esm/nodes/cart/cart-update-item-quantity.js.map +1 -1
  498. package/dist/esm/nodes/data/data-count.d.ts.map +1 -1
  499. package/dist/esm/nodes/data/data-count.js +6 -1
  500. package/dist/esm/nodes/data/data-count.js.map +1 -1
  501. package/dist/esm/nodes/data/data-create-item.d.ts.map +1 -1
  502. package/dist/esm/nodes/data/data-create-item.js +11 -1
  503. package/dist/esm/nodes/data/data-create-item.js.map +1 -1
  504. package/dist/esm/nodes/data/data-delete-item.d.ts.map +1 -1
  505. package/dist/esm/nodes/data/data-delete-item.js +29 -0
  506. package/dist/esm/nodes/data/data-delete-item.js.map +1 -1
  507. package/dist/esm/nodes/data/data-raw-query.d.ts.map +1 -1
  508. package/dist/esm/nodes/data/data-raw-query.js +6 -1
  509. package/dist/esm/nodes/data/data-raw-query.js.map +1 -1
  510. package/dist/esm/nodes/data/data-select.d.ts.map +1 -1
  511. package/dist/esm/nodes/data/data-select.js +6 -1
  512. package/dist/esm/nodes/data/data-select.js.map +1 -1
  513. package/dist/esm/nodes/data/data-update-item.d.ts.map +1 -1
  514. package/dist/esm/nodes/data/data-update-item.js +29 -0
  515. package/dist/esm/nodes/data/data-update-item.js.map +1 -1
  516. package/dist/esm/nodes/ecommerce/ecommerce-generate-invoice.d.ts.map +1 -1
  517. package/dist/esm/nodes/ecommerce/ecommerce-generate-invoice.js +7 -1
  518. package/dist/esm/nodes/ecommerce/ecommerce-generate-invoice.js.map +1 -1
  519. package/dist/esm/nodes/file-storage/file-storage-upload.d.ts.map +1 -1
  520. package/dist/esm/nodes/file-storage/file-storage-upload.js +7 -0
  521. package/dist/esm/nodes/file-storage/file-storage-upload.js.map +1 -1
  522. package/dist/esm/nodes/general/general-custom-js.d.ts.map +1 -1
  523. package/dist/esm/nodes/general/general-custom-js.js +21 -5
  524. package/dist/esm/nodes/general/general-custom-js.js.map +1 -1
  525. package/dist/esm/nodes/index.d.ts.map +1 -1
  526. package/dist/esm/nodes/index.js +9 -4
  527. package/dist/esm/nodes/index.js.map +1 -1
  528. package/dist/esm/nodes/payment/payment-billing-portal.d.ts +3 -0
  529. package/dist/esm/nodes/payment/payment-billing-portal.d.ts.map +1 -0
  530. package/dist/esm/nodes/payment/payment-billing-portal.js +49 -0
  531. package/dist/esm/nodes/payment/payment-billing-portal.js.map +1 -0
  532. package/dist/esm/nodes/payment/payment-charge-user.d.ts.map +1 -1
  533. package/dist/esm/nodes/payment/payment-charge-user.js +227 -360
  534. package/dist/esm/nodes/payment/payment-charge-user.js.map +1 -1
  535. package/dist/esm/nodes/payment/payment-close-checkout.d.ts +3 -0
  536. package/dist/esm/nodes/payment/payment-close-checkout.d.ts.map +1 -0
  537. package/dist/esm/nodes/payment/payment-close-checkout.js +138 -0
  538. package/dist/esm/nodes/payment/payment-close-checkout.js.map +1 -0
  539. package/dist/esm/nodes/payment/payment-ensure-subscription-plan.d.ts +3 -0
  540. package/dist/esm/nodes/payment/payment-ensure-subscription-plan.d.ts.map +1 -0
  541. package/dist/esm/nodes/payment/payment-ensure-subscription-plan.js +64 -0
  542. package/dist/esm/nodes/payment/payment-ensure-subscription-plan.js.map +1 -0
  543. package/dist/esm/nodes/payment/payment-manage-subscription.d.ts +3 -0
  544. package/dist/esm/nodes/payment/payment-manage-subscription.d.ts.map +1 -0
  545. package/dist/esm/nodes/payment/payment-manage-subscription.js +86 -0
  546. package/dist/esm/nodes/payment/payment-manage-subscription.js.map +1 -0
  547. package/dist/esm/nodes/payment/payment-refund.d.ts.map +1 -1
  548. package/dist/esm/nodes/payment/payment-refund.js +50 -404
  549. package/dist/esm/nodes/payment/payment-refund.js.map +1 -1
  550. package/dist/esm/nodes/push/push-send-notification.d.ts +14 -0
  551. package/dist/esm/nodes/push/push-send-notification.d.ts.map +1 -0
  552. package/dist/esm/nodes/push/push-send-notification.js +80 -0
  553. package/dist/esm/nodes/push/push-send-notification.js.map +1 -0
  554. package/dist/esm/payments/drivers/coingate-driver-code.d.ts +16 -0
  555. package/dist/esm/payments/drivers/coingate-driver-code.d.ts.map +1 -0
  556. package/dist/esm/payments/drivers/coingate-driver-code.js +467 -0
  557. package/dist/esm/payments/drivers/coingate-driver-code.js.map +1 -0
  558. package/dist/esm/payments/drivers/mollie-driver-code.d.ts +16 -0
  559. package/dist/esm/payments/drivers/mollie-driver-code.d.ts.map +1 -0
  560. package/dist/esm/payments/drivers/mollie-driver-code.js +619 -0
  561. package/dist/esm/payments/drivers/mollie-driver-code.js.map +1 -0
  562. package/dist/esm/payments/drivers/paddle-driver-code.d.ts +12 -0
  563. package/dist/esm/payments/drivers/paddle-driver-code.d.ts.map +1 -0
  564. package/dist/esm/payments/drivers/paddle-driver-code.js +679 -0
  565. package/dist/esm/payments/drivers/paddle-driver-code.js.map +1 -0
  566. package/dist/esm/payments/drivers/paypal-driver-code.d.ts +12 -0
  567. package/dist/esm/payments/drivers/paypal-driver-code.d.ts.map +1 -0
  568. package/dist/esm/payments/drivers/paypal-driver-code.js +1257 -0
  569. package/dist/esm/payments/drivers/paypal-driver-code.js.map +1 -0
  570. package/dist/esm/payments/drivers/razorpay-driver-code.d.ts +12 -0
  571. package/dist/esm/payments/drivers/razorpay-driver-code.d.ts.map +1 -0
  572. package/dist/esm/payments/drivers/razorpay-driver-code.js +728 -0
  573. package/dist/esm/payments/drivers/razorpay-driver-code.js.map +1 -0
  574. package/dist/esm/payments/drivers/square-driver-code.d.ts +14 -0
  575. package/dist/esm/payments/drivers/square-driver-code.d.ts.map +1 -0
  576. package/dist/esm/payments/drivers/square-driver-code.js +927 -0
  577. package/dist/esm/payments/drivers/square-driver-code.js.map +1 -0
  578. package/dist/esm/payments/drivers/stripe-driver-code.d.ts +12 -0
  579. package/dist/esm/payments/drivers/stripe-driver-code.d.ts.map +1 -0
  580. package/dist/esm/payments/drivers/stripe-driver-code.js +774 -0
  581. package/dist/esm/payments/drivers/stripe-driver-code.js.map +1 -0
  582. package/dist/esm/payments/index.d.ts +66 -0
  583. package/dist/esm/payments/index.d.ts.map +1 -0
  584. package/dist/esm/payments/index.js +164 -0
  585. package/dist/esm/payments/index.js.map +1 -0
  586. package/dist/esm/payments/payment-core-code.d.ts +19 -0
  587. package/dist/esm/payments/payment-core-code.d.ts.map +1 -0
  588. package/dist/esm/payments/payment-core-code.js +418 -0
  589. package/dist/esm/payments/payment-core-code.js.map +1 -0
  590. package/dist/esm/payments/payment-driver-code-map.d.ts +4 -0
  591. package/dist/esm/payments/payment-driver-code-map.d.ts.map +1 -0
  592. package/dist/esm/payments/payment-driver-code-map.js +18 -0
  593. package/dist/esm/payments/payment-driver-code-map.js.map +1 -0
  594. package/dist/esm/payments/payment-drivers-scope.d.ts +35 -0
  595. package/dist/esm/payments/payment-drivers-scope.d.ts.map +1 -0
  596. package/dist/esm/payments/payment-drivers-scope.js +51 -0
  597. package/dist/esm/payments/payment-drivers-scope.js.map +1 -0
  598. package/dist/esm/payments/payment-registry-code.d.ts +8 -0
  599. package/dist/esm/payments/payment-registry-code.d.ts.map +1 -0
  600. package/dist/esm/payments/payment-registry-code.js +37 -0
  601. package/dist/esm/payments/payment-registry-code.js.map +1 -0
  602. package/dist/esm/pg-client-code.d.ts +10 -0
  603. package/dist/esm/pg-client-code.d.ts.map +1 -1
  604. package/dist/esm/pg-client-code.js +25 -0
  605. package/dist/esm/pg-client-code.js.map +1 -1
  606. package/dist/esm/runtime-storage-generator.d.ts +28 -0
  607. package/dist/esm/runtime-storage-generator.d.ts.map +1 -1
  608. package/dist/esm/runtime-storage-generator.js +239 -4
  609. package/dist/esm/runtime-storage-generator.js.map +1 -1
  610. package/dist/esm/secret-collector.d.ts.map +1 -1
  611. package/dist/esm/secret-collector.js +8 -3
  612. package/dist/esm/secret-collector.js.map +1 -1
  613. package/dist/esm/security-scanner.d.ts +10 -1
  614. package/dist/esm/security-scanner.d.ts.map +1 -1
  615. package/dist/esm/security-scanner.js +18 -0
  616. package/dist/esm/security-scanner.js.map +1 -1
  617. package/dist/esm/segment-context-needs.d.ts +38 -0
  618. package/dist/esm/segment-context-needs.d.ts.map +1 -0
  619. package/dist/esm/segment-context-needs.js +125 -0
  620. package/dist/esm/segment-context-needs.js.map +1 -0
  621. package/dist/esm/segment-splitter.d.ts.map +1 -1
  622. package/dist/esm/segment-splitter.js +6 -1
  623. package/dist/esm/segment-splitter.js.map +1 -1
  624. package/dist/esm/segment-trust.d.ts +50 -0
  625. package/dist/esm/segment-trust.d.ts.map +1 -0
  626. package/dist/esm/segment-trust.js +111 -0
  627. package/dist/esm/segment-trust.js.map +1 -0
  628. package/dist/esm/sent-email-log/sent-email-log-code.d.ts +19 -0
  629. package/dist/esm/sent-email-log/sent-email-log-code.d.ts.map +1 -1
  630. package/dist/esm/sent-email-log/sent-email-log-code.js +2 -25
  631. package/dist/esm/sent-email-log/sent-email-log-code.js.map +1 -1
  632. package/dist/esm/server-runtime-code.d.ts +34 -0
  633. package/dist/esm/server-runtime-code.d.ts.map +1 -0
  634. package/dist/esm/server-runtime-code.js +299 -0
  635. package/dist/esm/server-runtime-code.js.map +1 -0
  636. package/dist/esm/session-cookie-resolver.d.ts +3 -78
  637. package/dist/esm/session-cookie-resolver.d.ts.map +1 -1
  638. package/dist/esm/session-cookie-resolver.js +7 -274
  639. package/dist/esm/session-cookie-resolver.js.map +1 -1
  640. package/dist/esm/subscriber-access-route-generator.d.ts +71 -0
  641. package/dist/esm/subscriber-access-route-generator.d.ts.map +1 -0
  642. package/dist/esm/subscriber-access-route-generator.js +292 -0
  643. package/dist/esm/subscriber-access-route-generator.js.map +1 -0
  644. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  645. package/dist/esm/types.d.ts +6 -0
  646. package/dist/esm/types.d.ts.map +1 -1
  647. package/dist/esm/webhook-delivery-lease/index.d.ts +8 -0
  648. package/dist/esm/webhook-delivery-lease/index.d.ts.map +1 -0
  649. package/dist/esm/webhook-delivery-lease/index.js +37 -0
  650. package/dist/esm/webhook-delivery-lease/index.js.map +1 -0
  651. package/dist/esm/webhook-delivery-lease/webhook-delivery-lease-code.d.ts +26 -0
  652. package/dist/esm/webhook-delivery-lease/webhook-delivery-lease-code.d.ts.map +1 -0
  653. package/dist/esm/webhook-delivery-lease/webhook-delivery-lease-code.js +147 -0
  654. package/dist/esm/webhook-delivery-lease/webhook-delivery-lease-code.js.map +1 -0
  655. package/dist/esm/webhook-delivery-lease/webhook-delivery-lease-scope.d.ts +16 -0
  656. package/dist/esm/webhook-delivery-lease/webhook-delivery-lease-scope.d.ts.map +1 -0
  657. package/dist/esm/webhook-delivery-lease/webhook-delivery-lease-scope.js +16 -0
  658. package/dist/esm/webhook-delivery-lease/webhook-delivery-lease-scope.js.map +1 -0
  659. package/dist/esm/webhook-generator.d.ts +1 -1
  660. package/dist/esm/webhook-generator.d.ts.map +1 -1
  661. package/dist/esm/webhook-generator.js +342 -254
  662. package/dist/esm/webhook-generator.js.map +1 -1
  663. package/dist/esm/webhook-signature-verification.d.ts +17 -1
  664. package/dist/esm/webhook-signature-verification.d.ts.map +1 -1
  665. package/dist/esm/webhook-signature-verification.js +179 -25
  666. package/dist/esm/webhook-signature-verification.js.map +1 -1
  667. package/dist/esm/workflow-auth-generator.d.ts +9 -6
  668. package/dist/esm/workflow-auth-generator.d.ts.map +1 -1
  669. package/dist/esm/workflow-auth-generator.js +132 -28
  670. package/dist/esm/workflow-auth-generator.js.map +1 -1
  671. package/dist/esm/workflow-component-plugin.d.ts.map +1 -1
  672. package/dist/esm/workflow-component-plugin.js +65 -28
  673. package/dist/esm/workflow-component-plugin.js.map +1 -1
  674. package/dist/esm/workflow-project-plugin.d.ts +13 -0
  675. package/dist/esm/workflow-project-plugin.d.ts.map +1 -1
  676. package/dist/esm/workflow-project-plugin.js +212 -63
  677. package/dist/esm/workflow-project-plugin.js.map +1 -1
  678. package/package.json +4 -4
  679. package/src/admin-form-hydration.ts +28 -0
  680. package/src/api-route-generator.ts +251 -64
  681. package/src/auth-generator.ts +273 -53
  682. package/src/auth-return/signed-in-destination-code.ts +32 -0
  683. package/src/cart-pricing-preamble.ts +22 -0
  684. package/src/cron-request-verification.ts +79 -0
  685. package/src/custom-node-modules.ts +102 -0
  686. package/src/data-api-route-generator.ts +370 -28
  687. package/src/ecommerce/cart-availability.ts +22 -13
  688. package/src/ecommerce/stock-decrement.ts +13 -1
  689. package/src/executor-generator.ts +212 -19
  690. package/src/index.ts +28 -7
  691. package/src/invoice/api-routes-code.ts +424 -391
  692. package/src/invoice/data-access-code.ts +431 -110
  693. package/src/invoice/index.ts +31 -1
  694. package/src/invoice/invoice-assembly-code.ts +514 -0
  695. package/src/invoice/invoice-html-code.ts +111 -9
  696. package/src/invoice/pdf-service-client-code.ts +3 -4
  697. package/src/nodes/account/account-login.ts +4 -3
  698. package/src/nodes/account/account-signup.ts +7 -4
  699. package/src/nodes/ai/ai-select-database-data.ts +10 -1
  700. package/src/nodes/browser/browser-get-push-subscription.ts +23 -0
  701. package/src/nodes/browser/browser-show-notification.ts +61 -38
  702. package/src/nodes/browser/browser-subscribe-to-push.ts +26 -36
  703. package/src/nodes/browser/browser-unsubscribe-from-push.ts +22 -0
  704. package/src/nodes/browser/push-api-access.ts +20 -0
  705. package/src/nodes/cart/cart-add-item.ts +200 -9
  706. package/src/nodes/cart/cart-clear.ts +11 -0
  707. package/src/nodes/cart/cart-get-total.ts +279 -7
  708. package/src/nodes/cart/cart-price-order.ts +351 -0
  709. package/src/nodes/cart/cart-update-item-quantity.ts +7 -0
  710. package/src/nodes/data/data-count.ts +9 -1
  711. package/src/nodes/data/data-create-item.ts +15 -1
  712. package/src/nodes/data/data-delete-item.ts +32 -0
  713. package/src/nodes/data/data-raw-query.ts +9 -1
  714. package/src/nodes/data/data-select.ts +9 -1
  715. package/src/nodes/data/data-update-item.ts +32 -0
  716. package/src/nodes/ecommerce/ecommerce-generate-invoice.ts +11 -1
  717. package/src/nodes/file-storage/file-storage-upload.ts +8 -0
  718. package/src/nodes/general/general-custom-js.ts +21 -5
  719. package/src/nodes/index.ts +16 -6
  720. package/src/nodes/payment/payment-billing-portal.ts +51 -0
  721. package/src/nodes/payment/payment-charge-user.ts +236 -442
  722. package/src/nodes/payment/payment-close-checkout.ts +137 -0
  723. package/src/nodes/payment/payment-ensure-subscription-plan.ts +66 -0
  724. package/src/nodes/payment/payment-manage-subscription.ts +89 -0
  725. package/src/nodes/payment/payment-refund.ts +52 -467
  726. package/src/nodes/payment-drivers-global.d.ts +13 -0
  727. package/src/nodes/push/push-send-notification.ts +83 -0
  728. package/src/nodes/workflow-utils-global.d.ts +5 -0
  729. package/src/payments/drivers/coingate-driver-code.ts +466 -0
  730. package/src/payments/drivers/mollie-driver-code.ts +618 -0
  731. package/src/payments/drivers/paddle-driver-code.ts +678 -0
  732. package/src/payments/drivers/paypal-driver-code.ts +1256 -0
  733. package/src/payments/drivers/razorpay-driver-code.ts +727 -0
  734. package/src/payments/drivers/square-driver-code.ts +926 -0
  735. package/src/payments/drivers/stripe-driver-code.ts +773 -0
  736. package/src/payments/index.ts +204 -0
  737. package/src/payments/payment-core-code.ts +421 -0
  738. package/src/payments/payment-driver-code-map.ts +19 -0
  739. package/src/payments/payment-drivers-scope.ts +66 -0
  740. package/src/payments/payment-registry-code.ts +38 -0
  741. package/src/pg-client-code.ts +30 -0
  742. package/src/runtime-storage-generator.ts +241 -4
  743. package/src/secret-collector.ts +8 -3
  744. package/src/security-scanner.ts +22 -0
  745. package/src/segment-context-needs.ts +148 -0
  746. package/src/segment-splitter.ts +6 -1
  747. package/src/segment-trust.ts +170 -0
  748. package/src/sent-email-log/sent-email-log-code.ts +2 -32
  749. package/src/server-runtime-code.ts +298 -0
  750. package/src/session-cookie-resolver.ts +9 -277
  751. package/src/subscriber-access-route-generator.ts +351 -0
  752. package/src/types.ts +6 -0
  753. package/src/webhook-delivery-lease/index.ts +44 -0
  754. package/src/webhook-delivery-lease/webhook-delivery-lease-code.ts +151 -0
  755. package/src/webhook-delivery-lease/webhook-delivery-lease-scope.ts +18 -0
  756. package/src/webhook-generator.ts +359 -260
  757. package/src/webhook-signature-verification.ts +180 -25
  758. package/src/workflow-auth-generator.ts +137 -28
  759. package/src/workflow-component-plugin.ts +77 -20
  760. package/src/workflow-project-plugin.ts +247 -44
  761. package/dist/cjs/nodes/payment/payment-cancel-plan.d.ts +0 -3
  762. package/dist/cjs/nodes/payment/payment-cancel-plan.d.ts.map +0 -1
  763. package/dist/cjs/nodes/payment/payment-cancel-plan.js +0 -33
  764. package/dist/cjs/nodes/payment/payment-cancel-plan.js.map +0 -1
  765. package/dist/cjs/nodes/payment/payment-create-subscription.d.ts +0 -3
  766. package/dist/cjs/nodes/payment/payment-create-subscription.d.ts.map +0 -1
  767. package/dist/cjs/nodes/payment/payment-create-subscription.js +0 -41
  768. package/dist/cjs/nodes/payment/payment-create-subscription.js.map +0 -1
  769. package/dist/cjs/nodes/payment/payment-subscribe-to-plan.d.ts +0 -3
  770. package/dist/cjs/nodes/payment/payment-subscribe-to-plan.d.ts.map +0 -1
  771. package/dist/cjs/nodes/payment/payment-subscribe-to-plan.js +0 -45
  772. package/dist/cjs/nodes/payment/payment-subscribe-to-plan.js.map +0 -1
  773. package/dist/esm/nodes/payment/payment-cancel-plan.d.ts +0 -3
  774. package/dist/esm/nodes/payment/payment-cancel-plan.d.ts.map +0 -1
  775. package/dist/esm/nodes/payment/payment-cancel-plan.js +0 -30
  776. package/dist/esm/nodes/payment/payment-cancel-plan.js.map +0 -1
  777. package/dist/esm/nodes/payment/payment-create-subscription.d.ts +0 -3
  778. package/dist/esm/nodes/payment/payment-create-subscription.d.ts.map +0 -1
  779. package/dist/esm/nodes/payment/payment-create-subscription.js +0 -38
  780. package/dist/esm/nodes/payment/payment-create-subscription.js.map +0 -1
  781. package/dist/esm/nodes/payment/payment-subscribe-to-plan.d.ts +0 -3
  782. package/dist/esm/nodes/payment/payment-subscribe-to-plan.d.ts.map +0 -1
  783. package/dist/esm/nodes/payment/payment-subscribe-to-plan.js +0 -42
  784. package/dist/esm/nodes/payment/payment-subscribe-to-plan.js.map +0 -1
  785. package/src/nodes/payment/payment-cancel-plan.ts +0 -33
  786. package/src/nodes/payment/payment-create-subscription.ts +0 -42
  787. package/src/nodes/payment/payment-subscribe-to-plan.ts +0 -46
@@ -0,0 +1,948 @@
1
+ /* tslint:disable:function-constructor */
2
+ import { parse } from '@babel/parser'
3
+ import { generateDataAPIRoute } from '../src/data-api-route-generator'
4
+ import { dataSelect } from '../src/nodes/data/data-select'
5
+ import { dataCount } from '../src/nodes/data/data-count'
6
+ import { dataCreateItem } from '../src/nodes/data/data-create-item'
7
+ import { dataRawQuery } from '../src/nodes/data/data-raw-query'
8
+ import { dataUpdateItem } from '../src/nodes/data/data-update-item'
9
+ import { dataDeleteItem } from '../src/nodes/data/data-delete-item'
10
+ import { accountSignup } from '../src/nodes/account/account-signup'
11
+ import { generateSignupRouteFile } from '../src/auth-generator'
12
+ import { resolveAuthUsersTableName } from '../src/workflow-project-plugin'
13
+
14
+ /**
15
+ * The generated `/api/data/<ds>/<op>` route is reachable from any browser, so
16
+ * the tables that ARE money (gift cards and their ledger) are refused to it
17
+ * outright, and the tables that decide how much money is given away
18
+ * (vouchers, automatic discounts, the redemption ledger) are refused every
19
+ * write — unless the request carries the app's internal secret, which only a
20
+ * server-side workflow node can read. Executed against a fake pg client: the
21
+ * verdict is a status code, not a substring.
22
+ */
23
+
24
+ const SECRET = 'server-secret'
25
+
26
+ interface RouteResult {
27
+ status: number
28
+ body: any
29
+ queries: string[]
30
+ }
31
+
32
+ type RouteRunner = (
33
+ operation: string,
34
+ body: Record<string, unknown>,
35
+ headers?: Record<string, string>
36
+ ) => Promise<RouteResult>
37
+
38
+ function bootRoute(
39
+ secret: string | undefined,
40
+ options: { authUsersTableName?: string; rows?: any[] } = {}
41
+ ): RouteRunner {
42
+ const code = generateDataAPIRoute(options)
43
+ const queries: string[] = []
44
+ class FakeClient {
45
+ public async connect(): Promise<void> {
46
+ return
47
+ }
48
+ public async end(): Promise<void> {
49
+ return
50
+ }
51
+ public async query(sql: string): Promise<{ rows: any[]; rowCount: number }> {
52
+ queries.push(sql)
53
+ if (/information_schema/i.test(sql)) {
54
+ return { rows: [], rowCount: 0 }
55
+ }
56
+ if (/^SELECT COUNT/i.test(sql)) {
57
+ return { rows: [{ count: '0' }], rowCount: 1 }
58
+ }
59
+ const rows = options.rows || []
60
+ return { rows, rowCount: rows.length }
61
+ }
62
+ }
63
+ const moduleObj: { exports: any } = { exports: {} }
64
+ const fakeRequire = (name: string): any => {
65
+ if (name === 'pg') {
66
+ return { Client: FakeClient }
67
+ }
68
+ // The users-row guard resolves the caller's session; nobody is signed in
69
+ // in these tests.
70
+ if (name === 'next-auth/jwt') {
71
+ return { getToken: async () => null }
72
+ }
73
+ throw new Error('unexpected require: ' + name)
74
+ }
75
+ new Function('require', 'module', 'exports', 'process', 'console', code)(
76
+ fakeRequire,
77
+ moduleObj,
78
+ moduleObj.exports,
79
+ { env: { NEXTAUTH_SECRET: secret, TELEPORT_DB_CONNECTION_STRING: 'postgresql://x' } },
80
+ { error: () => undefined, warn: () => undefined, log: () => undefined }
81
+ )
82
+ const handler = moduleObj.exports
83
+ return async (operation, body, headers = {}) => {
84
+ queries.length = 0
85
+ let status = 0
86
+ let responseBody: any = null
87
+ const res = {
88
+ status(statusCode: number) {
89
+ status = statusCode
90
+ return this
91
+ },
92
+ json(payload: any) {
93
+ responseBody = payload
94
+ return this
95
+ },
96
+ }
97
+ await handler({ method: 'POST', query: { params: ['ds-1', operation] }, headers, body }, res)
98
+ return { status, body: responseBody, queries: queries.slice() }
99
+ }
100
+ }
101
+
102
+ const internal = { 'x-internal-data-secret': SECRET }
103
+ // The AI data-query node: server-side, so it may run raw SQL, but the SQL is a
104
+ // model's answer to a visitor — the statement scan still applies to it.
105
+ const restricted = { 'x-internal-data-secret': SECRET, 'x-tq-restricted-sql': '1' }
106
+
107
+ describe('data API — money tables are server-only', () => {
108
+ const run = bootRoute(SECRET)
109
+
110
+ it('still emits the whole route — a stray backtick would cut the file off', () => {
111
+ const code = generateDataAPIRoute()
112
+ expect(code).toContain('module.exports = async function handler(req, res)')
113
+ expect(() => parse(code, { sourceType: 'script' })).not.toThrow()
114
+ })
115
+
116
+ it('refuses a browser every operation on the gift-card, voucher and customer-record tables', async () => {
117
+ for (const tableName of [
118
+ 'teleport_gift_cards',
119
+ 'teleport_gift_card_transactions',
120
+ 'teleport_vouchers',
121
+ 'teleport_voucher_redemptions',
122
+ // A customer's own records reach a browser only through a server
123
+ // segment (their order page) or the admin's session — the list is
124
+ // every buyer's name, address and email.
125
+ 'users',
126
+ 'teleport_orders',
127
+ 'teleport_order_items',
128
+ 'teleport_invoices',
129
+ 'teleport_events',
130
+ 'teleport_shipments',
131
+ 'teleport_withdrawal_requests',
132
+ 'teleport_abandoned_carts',
133
+ 'teleport_cart',
134
+ 'teleport_favourites',
135
+ 'teleport_product_reviews',
136
+ ]) {
137
+ for (const [operation, body] of [
138
+ ['select', { tableName }],
139
+ ['count', { tableName }],
140
+ ['create', { tableName, columnMappings: { balance: 1 } }],
141
+ ['update', { tableName, columnMappings: { balance: 1 }, filters: [] }],
142
+ ['delete', { tableName, filters: [] }],
143
+ ] as Array<[string, Record<string, unknown>]>) {
144
+ const result = await run(operation, body)
145
+ expect(result.status).toBe(403)
146
+ if (operation === 'select' || operation === 'count') {
147
+ expect(result.body.error).toContain(tableName)
148
+ }
149
+ // Refused BEFORE the database is touched.
150
+ expect(result.queries).toEqual([])
151
+ }
152
+ }
153
+ })
154
+
155
+ it('refuses the same however the table is spelled', async () => {
156
+ for (const tableName of [
157
+ '"teleport_gift_cards"',
158
+ 'public.teleport_gift_cards',
159
+ 'TELEPORT_GIFT_CARDS',
160
+ ]) {
161
+ expect((await run('select', { tableName })).status).toBe(403)
162
+ }
163
+ })
164
+
165
+ it('lets a server-side node through with the internal secret', async () => {
166
+ const result = await run('select', { tableName: 'teleport_gift_cards' }, internal)
167
+ expect(result.status).toBe(200)
168
+ expect(result.queries[0]).toContain('FROM teleport_gift_cards')
169
+ expect(
170
+ (
171
+ await run(
172
+ 'update',
173
+ {
174
+ tableName: 'teleport_vouchers',
175
+ columnMappings: { usage_count: 1 },
176
+ filters: [{ field: 'id', value: 'v1' }],
177
+ },
178
+ internal
179
+ )
180
+ ).status
181
+ ).toBe(200)
182
+ })
183
+
184
+ it('does not take a wrong secret, nor an empty one when none is configured', async () => {
185
+ expect(
186
+ (
187
+ await run(
188
+ 'select',
189
+ { tableName: 'teleport_gift_cards' },
190
+ { 'x-internal-data-secret': 'nope' }
191
+ )
192
+ ).status
193
+ ).toBe(403)
194
+ const unconfigured = bootRoute(undefined)
195
+ expect(
196
+ (
197
+ await unconfigured(
198
+ 'select',
199
+ { tableName: 'teleport_gift_cards' },
200
+ { 'x-internal-data-secret': '' }
201
+ )
202
+ ).status
203
+ ).toBe(403)
204
+ })
205
+
206
+ it('refuses a browser every write on the automatic-discount table, but not a read', async () => {
207
+ const tableName = 'teleport_discounts'
208
+ expect((await run('create', { tableName, columnMappings: { name: 'X' } })).status).toBe(403)
209
+ expect(
210
+ (await run('update', { tableName, columnMappings: { name: 'X' }, filters: [] })).status
211
+ ).toBe(403)
212
+ expect((await run('delete', { tableName, filters: [] })).status).toBe(403)
213
+ // The storefront provider reads the active rules from the browser.
214
+ expect((await run('select', { tableName })).status).toBe(200)
215
+ expect((await run('count', { tableName })).status).toBe(200)
216
+ })
217
+
218
+ it('serves the discount table to a browser only as the live-rule feed', async () => {
219
+ const tableName = 'teleport_discounts'
220
+ const live =
221
+ "status = 'active' AND (starts_at IS NULL OR starts_at <= NOW()) AND (ends_at IS NULL OR ends_at > NOW())"
222
+
223
+ // What the storefront provider sends: the merchant's campaign plan is
224
+ // narrowed to the rules that price an order right now.
225
+ const feed = await run('select', {
226
+ tableName,
227
+ filters: [{ field: 'status', value: 'active', operator: '=' }],
228
+ limit: 500,
229
+ })
230
+ expect(feed.status).toBe(200)
231
+ const select = feed.queries.find((sql) => /^SELECT /.test(sql) && !/^SELECT COUNT/i.test(sql))
232
+ expect(select).toContain('SELECT id, name, status, priority, discount_type')
233
+ // The window is the database's judgement, and when a campaign ends is the
234
+ // merchant's business.
235
+ expect(select).not.toContain('starts_at,')
236
+ expect(select).not.toContain('ends_at,')
237
+ expect(select).toContain(' AND ' + live)
238
+ // Drafts, paused rules, how often a campaign ran: none of it is the
239
+ // shopper's business.
240
+ expect(select).not.toContain('*')
241
+ expect(select).not.toContain('description')
242
+ expect(select).not.toContain('usage_count')
243
+ // The count beside the rows counts the same rows.
244
+ expect(feed.queries.find((sql) => /^SELECT COUNT/i.test(sql))).toContain(' AND ' + live)
245
+
246
+ // No filters at all: the window is still the database's.
247
+ const unfiltered = await run('select', { tableName })
248
+ expect(unfiltered.queries[0]).toContain(' WHERE ' + live)
249
+ expect((await run('count', { tableName })).queries[0]).toContain(' WHERE ' + live)
250
+
251
+ // A caller cannot ask for the columns back, nor widen the window.
252
+ const asked = await run('select', {
253
+ tableName,
254
+ selectedColumns: ['id', 'description', 'usage_count'],
255
+ filters: [{ field: 'status', value: 'draft', operator: '=' }],
256
+ })
257
+ expect(asked.queries[0]).not.toContain('description')
258
+ expect(asked.queries[0]).toContain(' AND ' + live)
259
+
260
+ // A server segment prices the order from the whole table.
261
+ const server = await run('select', { tableName }, internal)
262
+ expect(server.queries[0]).toBe('SELECT * FROM teleport_discounts')
263
+ })
264
+
265
+ it('refuses a feed filter or sort on a column the feed does not serve — a filter is an oracle', async () => {
266
+ const tableName = 'teleport_discounts'
267
+ for (const [operation, body] of [
268
+ ['select', { tableName, filters: [{ field: 'usage_count', operator: '>', value: 100 }] }],
269
+ [
270
+ 'select',
271
+ {
272
+ tableName,
273
+ filters: [{ source: 'description', operand: 'contains', destination: 'launch' }],
274
+ },
275
+ ],
276
+ [
277
+ 'select',
278
+ { tableName, filters: [{ field: 'length(description)', operator: '>', value: 3 }] },
279
+ ],
280
+ ['select', { tableName, sorts: [{ field: 'usage_count', order: 'desc' }] }],
281
+ ['select', { tableName, sorts: [{ field: 'ends_at', order: 'asc' }] }],
282
+ ['count', { tableName, filters: [{ field: 'usage_count', operator: '>', value: 100 }] }],
283
+ ] as Array<[string, Record<string, unknown>]>) {
284
+ const result = await run(operation, body)
285
+ expect(result.status).toBe(403)
286
+ expect(result.queries).toEqual([])
287
+ }
288
+ // The storefront's own read, and any filter or sort over served columns.
289
+ expect(
290
+ (
291
+ await run('select', {
292
+ tableName,
293
+ filters: [{ field: '"status"', value: 'active', operator: '=' }],
294
+ sorts: [{ field: 'priority', order: 'asc' }],
295
+ })
296
+ ).status
297
+ ).toBe(200)
298
+ // A server segment filters however it likes.
299
+ expect(
300
+ (
301
+ await run(
302
+ 'select',
303
+ { tableName, filters: [{ field: 'usage_count', operator: '>', value: 1 }] },
304
+ internal
305
+ )
306
+ ).status
307
+ ).toBe(200)
308
+ })
309
+
310
+ it('serves a browser the storefront catalogue to READ, and nothing more', async () => {
311
+ // Generated browser code only reads here (the storefront feeds); every
312
+ // write and every raw statement comes from a server segment presenting
313
+ // the secret. So a browser that writes is not the store: it could mark
314
+ // its own order paid. And it reads only the catalogue tables the
315
+ // storefront itself reads — any other table is refused (see
316
+ // data-api-browser-reads.test.ts).
317
+ expect((await run('select', { tableName: 'teleport_products' })).status).toBe(200)
318
+ expect((await run('count', { tableName: 'teleport_products' })).status).toBe(200)
319
+ expect((await run('select', { tableName: 'teleport_gift_cards_archive' })).status).toBe(403)
320
+ for (const [operation, body] of [
321
+ ['create', { tableName: 'teleport_orders', columnMappings: { status: 'pending' } }],
322
+ [
323
+ 'update',
324
+ {
325
+ tableName: 'teleport_orders',
326
+ columnMappings: { payment_status: 'paid' },
327
+ filters: [{ field: 'id', value: 'o1' }],
328
+ },
329
+ ],
330
+ ['delete', { tableName: 'teleport_orders', filters: [{ field: 'id', value: 'o1' }] }],
331
+ ['raw-query', { query: 'SELECT 1 FROM teleport_products', params: [] }],
332
+ [
333
+ 'select',
334
+ { tableName: 'teleport_products', rawQueryUserPart: 'SELECT * FROM teleport_products' },
335
+ ],
336
+ ] as Array<[string, Record<string, unknown>]>) {
337
+ const result = await run(operation, body)
338
+ expect(result.status).toBe(403)
339
+ expect(result.queries).toEqual([])
340
+ }
341
+ expect(
342
+ (
343
+ await run(
344
+ 'create',
345
+ { tableName: 'teleport_orders', columnMappings: { status: 'pending' } },
346
+ internal
347
+ )
348
+ ).status
349
+ ).toBe(200)
350
+ })
351
+
352
+ it('keeps the old scan for an app with no secret to tell its own calls apart', async () => {
353
+ // No authentication, hence no store: nothing identifies a server call, so
354
+ // writes and raw statements stay open and only the money tables are held back.
355
+ const open = bootRoute(undefined)
356
+ expect(
357
+ (await open('create', { tableName: 'teleport_posts', columnMappings: { status: 'draft' } }))
358
+ .status
359
+ ).toBe(200)
360
+ expect(
361
+ (await open('raw-query', { query: 'SELECT 1 FROM teleport_products', params: [] })).status
362
+ ).toBe(200)
363
+ expect(
364
+ (await open('raw-query', { query: 'SELECT code FROM teleport_gift_cards', params: [] }))
365
+ .status
366
+ ).toBe(403)
367
+ expect((await open('select', { tableName: 'teleport_orders' })).status).toBe(403)
368
+ })
369
+
370
+ it('refuses a raw query that mentions the ledger, quoted or schema-qualified', async () => {
371
+ for (const query of [
372
+ 'SELECT balance FROM teleport_gift_cards WHERE code = $1',
373
+ 'SELECT * FROM "teleport_gift_card_transactions"',
374
+ 'SELECT 1 FROM public.teleport_gift_cards',
375
+ 'WITH c AS (SELECT id FROM Teleport_Gift_Cards) SELECT * FROM c',
376
+ "SELECT 1 /* teleport_products */ FROM teleport_gift_cards -- 'x'",
377
+ ]) {
378
+ const result = await run('raw-query', { query, params: [] }, restricted)
379
+ expect(result.status).toBe(403)
380
+ expect(result.queries).toEqual([])
381
+ }
382
+ // A table name inside a string literal is data, not a reference.
383
+ expect(
384
+ (
385
+ await run(
386
+ 'raw-query',
387
+ { query: "SELECT 1 FROM teleport_products WHERE name = 'teleport_gift_cards'" },
388
+ restricted
389
+ )
390
+ ).status
391
+ ).toBe(200)
392
+ })
393
+
394
+ it('refuses a raw write on the discount table, a raw read of the voucher tables, and lets a discount read through', async () => {
395
+ expect(
396
+ (
397
+ await run(
398
+ 'raw-query',
399
+ {
400
+ query: 'UPDATE teleport_vouchers SET usage_count = usage_count + 1 WHERE id = $1',
401
+ params: ['v1'],
402
+ },
403
+ restricted
404
+ )
405
+ ).status
406
+ ).toBe(403)
407
+ expect(
408
+ (
409
+ await run(
410
+ 'raw-query',
411
+ {
412
+ query:
413
+ 'WITH bump AS (SELECT 1) INSERT INTO teleport_voucher_redemptions (voucher_id) SELECT 1',
414
+ },
415
+ restricted
416
+ )
417
+ ).status
418
+ ).toBe(403)
419
+ expect(
420
+ (await run('raw-query', { query: 'DELETE FROM teleport_discounts' }, restricted)).status
421
+ ).toBe(403)
422
+ expect(
423
+ (await run('raw-query', { query: 'TRUNCATE teleport_discounts' }, restricted)).status
424
+ ).toBe(403)
425
+ // A generated batch is a list of single-use coupons: no browser lists it.
426
+ expect(
427
+ (
428
+ await run(
429
+ 'raw-query',
430
+ {
431
+ query: "SELECT * FROM teleport_vouchers WHERE code = $1 AND status = 'active'",
432
+ params: ['X'],
433
+ },
434
+ restricted
435
+ )
436
+ ).status
437
+ ).toBe(403)
438
+ // The feed is the ONE shape a browser reads the rule table in, and a
439
+ // statement the caller wrote is not it.
440
+ expect(
441
+ (
442
+ await run(
443
+ 'raw-query',
444
+ { query: "SELECT * FROM teleport_discounts WHERE status = 'active'", params: [] },
445
+ restricted
446
+ )
447
+ ).status
448
+ ).toBe(403)
449
+ expect(
450
+ (
451
+ await run(
452
+ 'select',
453
+ { tableName: 'teleport_products', rawQueryUserPart: 'SELECT * FROM teleport_discounts' },
454
+ restricted
455
+ )
456
+ ).status
457
+ ).toBe(403)
458
+ expect(
459
+ (
460
+ await run(
461
+ 'raw-query',
462
+ { query: "SELECT * FROM teleport_discounts WHERE status = 'active'", params: [] },
463
+ internal
464
+ )
465
+ ).status
466
+ ).toBe(200)
467
+ // Deliberately coarse: a statement that writes AND mentions a protected
468
+ // table is refused without working out which table the write lands on —
469
+ // parsing that is exactly the kind of guard that can be talked around.
470
+ expect(
471
+ (
472
+ await run(
473
+ 'raw-query',
474
+ {
475
+ query:
476
+ 'UPDATE teleport_orders SET discount_details = (SELECT name FROM teleport_discounts WHERE id = $1)',
477
+ params: ['d1'],
478
+ },
479
+ restricted
480
+ )
481
+ ).status
482
+ ).toBe(403)
483
+ expect(
484
+ (
485
+ await run(
486
+ 'raw-query',
487
+ { query: 'UPDATE teleport_vouchers SET usage_count = 1', params: [] },
488
+ internal
489
+ )
490
+ ).status
491
+ ).toBe(200)
492
+ })
493
+
494
+ it("checks a select's raw override like a raw query", async () => {
495
+ expect(
496
+ (
497
+ await run(
498
+ 'select',
499
+ {
500
+ tableName: 'teleport_products',
501
+ rawQueryUserPart: 'SELECT code FROM teleport_gift_cards',
502
+ },
503
+ restricted
504
+ )
505
+ ).status
506
+ ).toBe(403)
507
+ })
508
+
509
+ it('refuses a statement that can reach a protected table without spelling its name', async () => {
510
+ for (const query of [
511
+ // A Unicode-escaped identifier: \005f is the underscore.
512
+ 'SELECT * FROM U&"teleport\\005fgift_cards"',
513
+ 'select code from u&"teleport\\005fvouchers"',
514
+ 'SELECT * FROM U&"teleport\\005fdiscounts"',
515
+ // Quote and comment markers inside a quoted identifier, `$` and `E`
516
+ // inside an identifier: the scan lexes them as Postgres does.
517
+ 'SELECT code AS "x\'", balance FROM teleport_gift_cards -- \'',
518
+ 'SELECT 1 AS "--", code, balance FROM teleport_gift_cards',
519
+ 'SELECT code AS a$b$, balance FROM teleport_gift_cards AS g$b$',
520
+ "SELECT CASE WHEN true THEN 'a' ELSE'\\' END, code FROM teleport_vouchers -- '",
521
+ // The planner statistics hold sampled values of every column.
522
+ "SELECT histogram_bounds::text FROM pg_stats WHERE tablename = 'teleport_vouchers'",
523
+ // Functions that run SQL text, or dump whole tables and schemas.
524
+ "SELECT query_to_xml('select code from teleport_gift_cards', true, false, '')",
525
+ "SELECT table_to_xml('teleport_' || 'gift_cards', true, false, '')",
526
+ "SELECT pg_catalog.schema_to_xml('public', true, false, '')",
527
+ "SELECT database_to_xml(true, false, '')",
528
+ "SELECT * FROM ts_stat('select to_tsvector(code) from teleport_gift_cards')",
529
+ ]) {
530
+ const raw = await run('raw-query', { query, params: [] }, restricted)
531
+ expect(raw.status).toBe(403)
532
+ expect(raw.queries).toEqual([])
533
+ const override = await run(
534
+ 'select',
535
+ { tableName: 'teleport_products', rawQueryUserPart: query },
536
+ restricted
537
+ )
538
+ expect(override.status).toBe(403)
539
+ expect(override.queries).toEqual([])
540
+ }
541
+ // The server keeps every spelling it writes.
542
+ expect(
543
+ (
544
+ await run(
545
+ 'raw-query',
546
+ { query: 'SELECT * FROM U&"teleport\\005fgift_cards"', params: [] },
547
+ internal
548
+ )
549
+ ).status
550
+ ).toBe(200)
551
+ })
552
+
553
+ it('keeps password reset tokens server-only — reading one is taking the account', async () => {
554
+ expect((await run('select', { tableName: 'password_reset_tokens' })).status).toBe(403)
555
+ for (const headers of [{}, restricted]) {
556
+ expect(
557
+ (
558
+ await run(
559
+ 'raw-query',
560
+ {
561
+ query: 'SELECT token FROM password_reset_tokens WHERE email = $1',
562
+ params: ['a@b.c'],
563
+ },
564
+ headers
565
+ )
566
+ ).status
567
+ ).toBe(403)
568
+ }
569
+ expect((await run('select', { tableName: 'password_reset_tokens' }, internal)).status).toBe(200)
570
+ })
571
+
572
+ it('keeps push subscriptions server-only — an endpoint and its keys can notify that device', async () => {
573
+ expect((await run('select', { tableName: 'teleport_push_subscriptions' })).status).toBe(403)
574
+ for (const headers of [{}, restricted]) {
575
+ expect(
576
+ (
577
+ await run(
578
+ 'raw-query',
579
+ { query: 'SELECT endpoint, p256dh, auth FROM teleport_push_subscriptions', params: [] },
580
+ headers
581
+ )
582
+ ).status
583
+ ).toBe(403)
584
+ }
585
+ expect(
586
+ (await run('select', { tableName: 'teleport_push_subscriptions' }, internal)).status
587
+ ).toBe(200)
588
+ })
589
+ })
590
+
591
+ describe('data API — a browser cannot grant itself a role', () => {
592
+ // The money-table guard admits a browser whose session token says `admin`,
593
+ // and that role is a column of the user's OWN row. The same route exposes an
594
+ // update of that row, so without a column check the trust boundary is
595
+ // self-service.
596
+ const run = bootRoute(SECRET, { authUsersTableName: 'users' })
597
+
598
+ it('refuses an update that writes a role column, before the database is touched', async () => {
599
+ for (const columnMappings of [
600
+ { role: 'admin' },
601
+ { Role: 'admin' },
602
+ { role_name: 'admin' },
603
+ { roles: ['admin'] },
604
+ { name: 'Mallory', role: 'admin' },
605
+ ] as Array<Record<string, unknown>>) {
606
+ const result = await run('update', {
607
+ tableName: 'users',
608
+ columnMappings,
609
+ filters: [{ field: 'id', value: 'u1' }],
610
+ })
611
+ expect(result.status).toBe(403)
612
+ expect(result.queries).toEqual([])
613
+ }
614
+ // The column-mapping list shape the update node also sends.
615
+ const mapped = await run('update', {
616
+ tableName: 'users',
617
+ columnMappings: [{ source: 'role', destination: 'admin' }],
618
+ filters: [{ field: 'id', value: 'u1' }],
619
+ })
620
+ expect(mapped.status).toBe(403)
621
+ })
622
+
623
+ it('refuses it however the table is spelled, and leaves profile columns alone', async () => {
624
+ for (const tableName of ['public.users', '"users"', 'USERS']) {
625
+ expect(
626
+ (
627
+ await run('update', {
628
+ tableName,
629
+ columnMappings: { role: 'admin' },
630
+ filters: [{ field: 'id', value: 'u1' }],
631
+ })
632
+ ).status
633
+ ).toBe(403)
634
+ }
635
+ // A browser writes no row at all: a profile edit runs in a server segment,
636
+ // which presents the secret.
637
+ const profile = await run('update', {
638
+ tableName: 'users',
639
+ columnMappings: { name: 'Mallory' },
640
+ filters: [{ field: 'id', value: 'u1' }],
641
+ })
642
+ expect(profile.status).toBe(403)
643
+ expect(profile.queries).toEqual([])
644
+ })
645
+
646
+ it('refuses a create that writes a role column — a new row with a known password is a new admin', async () => {
647
+ for (const columnMappings of [
648
+ { email: 'm@x.io', password: 'hash', role: 'admin' },
649
+ [
650
+ { column: 'email', value: 'm@x.io' },
651
+ { column: '"role"', value: 'admin' },
652
+ ],
653
+ { email: 'm@x.io', 'users.roles': ['admin'] },
654
+ { email: 'm@x.io', roleName: 'admin' },
655
+ ] as unknown[]) {
656
+ const result = await run('create', { tableName: 'users', columnMappings })
657
+ expect(result.status).toBe(403)
658
+ expect(result.queries).toEqual([])
659
+ }
660
+ // The anonymous-visitor row the resolve-user node ensures — from its
661
+ // server segment, which presents the secret.
662
+ expect(
663
+ (
664
+ await run(
665
+ 'create',
666
+ {
667
+ tableName: 'users',
668
+ onConflictDoNothing: true,
669
+ columnMappings: [
670
+ { column: 'id', value: '0b8e9f1e-0000-4000-8000-000000000000' },
671
+ { column: 'email', value: 'anon@x.io' },
672
+ { column: 'name', value: '' },
673
+ { column: 'image', value: '' },
674
+ ],
675
+ },
676
+ internal
677
+ )
678
+ ).status
679
+ ).toBe(200)
680
+ })
681
+
682
+ it('refuses an update that spells the role column quoted or table-qualified', async () => {
683
+ for (const column of ['"role"', 'users.role', '"ROLES"', 'public.users.rolename']) {
684
+ const result = await run('update', {
685
+ tableName: 'users',
686
+ columnMappings: { [column]: 'admin' },
687
+ filters: [{ field: 'id', value: 'u1' }],
688
+ })
689
+ expect(result.status).toBe(403)
690
+ expect(result.queries).toEqual([])
691
+ }
692
+ })
693
+
694
+ it('refuses a browser raw statement that writes the users table, whatever it names', async () => {
695
+ for (const query of [
696
+ // (`SET role` right after SET is the validator's SET ROLE refusal, so
697
+ // these lead with another column to reach the role guard itself.)
698
+ "UPDATE users SET name = name, role = 'admin' WHERE id = $1",
699
+ 'UPDATE "users" SET (name, "role") = ROW(name, $1) WHERE id = $2',
700
+ "INSERT INTO public.users VALUES (gen_random_uuid(), 'm@x.io', 'hash', 'admin')",
701
+ 'WITH promoted AS (UPDATE users SET name = name RETURNING id) SELECT * FROM promoted',
702
+ // \0075 is the u: the same table, spelled where a name scan cannot see it.
703
+ 'UPDATE U&"\\0075sers" SET name = name, role = \'admin\' WHERE id = $1',
704
+ // `$` inside identifiers opens no dollar quote.
705
+ "UPDATE users AS a$z$ SET email = email, role = 'admin' WHERE id = $1 AND 1 = (SELECT 1 AS b$z$)",
706
+ ]) {
707
+ for (const headers of [{}, restricted]) {
708
+ const result = await run('raw-query', { query, params: ['u1', 'u1'] }, headers)
709
+ expect(result.status).toBe(403)
710
+ expect(result.queries).toEqual([])
711
+ }
712
+ }
713
+ expect(
714
+ (
715
+ await run('select', {
716
+ tableName: 'teleport_products',
717
+ rawQueryUserPart: "UPDATE users SET name = name, role = 'admin' RETURNING id",
718
+ })
719
+ ).status
720
+ ).toBe(403)
721
+ // The one caller allowed raw SQL at all never reaches the users table — a
722
+ // statement can hand back a whole row without naming a credential column —
723
+ // nor the customers' orders (its statement is a model's answer to a
724
+ // visitor), while writing a catalogue table is not a role grant.
725
+ expect(
726
+ (
727
+ await run(
728
+ 'raw-query',
729
+ { query: 'SELECT id, name FROM users WHERE id = $1', params: ['u1'] },
730
+ restricted
731
+ )
732
+ ).status
733
+ ).toBe(403)
734
+ expect(
735
+ (
736
+ await run(
737
+ 'raw-query',
738
+ { query: 'SELECT shipping_address FROM teleport_orders WHERE id = $1', params: ['o1'] },
739
+ restricted
740
+ )
741
+ ).status
742
+ ).toBe(403)
743
+ expect(
744
+ (
745
+ await run(
746
+ 'raw-query',
747
+ { query: 'UPDATE teleport_products SET status = $1 WHERE id = $2', params: ['x', 'p1'] },
748
+ restricted
749
+ )
750
+ ).status
751
+ ).toBe(200)
752
+ // The server may.
753
+ expect(
754
+ (
755
+ await run(
756
+ 'raw-query',
757
+ { query: "UPDATE users SET name = name, role = 'admin' WHERE id = $1", params: ['u1'] },
758
+ internal
759
+ )
760
+ ).status
761
+ ).toBe(200)
762
+ })
763
+
764
+ it('guards the users table the session role is read from even when the identity table has another name', async () => {
765
+ const customers = bootRoute(SECRET, { authUsersTableName: 'customers' })
766
+ for (const tableName of ['customers', 'users']) {
767
+ expect(
768
+ (
769
+ await customers('update', {
770
+ tableName,
771
+ columnMappings: { role: 'admin' },
772
+ filters: [{ field: 'id', value: 'u1' }],
773
+ })
774
+ ).status
775
+ ).toBe(403)
776
+ }
777
+ expect(
778
+ (
779
+ await customers('raw-query', {
780
+ query: "UPDATE users SET name = name, role = 'admin'",
781
+ params: [],
782
+ })
783
+ ).status
784
+ ).toBe(403)
785
+ })
786
+
787
+ it('lets a server-side segment set a role, and leaves other tables untouched', async () => {
788
+ expect(
789
+ (
790
+ await run(
791
+ 'update',
792
+ {
793
+ tableName: 'users',
794
+ columnMappings: { role: 'admin' },
795
+ filters: [{ field: 'id', value: 'u1' }],
796
+ },
797
+ internal
798
+ )
799
+ ).status
800
+ ).toBe(200)
801
+ expect(
802
+ (
803
+ await run(
804
+ 'update',
805
+ {
806
+ tableName: 'teleport_product_reviews',
807
+ columnMappings: { role: 'admin' },
808
+ filters: [{ field: 'id', value: 'r1' }],
809
+ },
810
+ internal
811
+ )
812
+ ).status
813
+ ).toBe(200)
814
+ })
815
+ })
816
+
817
+ describe('the other ways a browser could write its own role', () => {
818
+ const signupWith = async (
819
+ body: Record<string, unknown>,
820
+ customUserProperties: Array<{ key: string }> = []
821
+ ): Promise<Record<string, unknown>> => {
822
+ const code = generateSignupRouteFile({
823
+ enabled: true,
824
+ dataSourceType: 'postgresql',
825
+ customUserProperties,
826
+ } as any)
827
+ let created: Record<string, unknown> = {}
828
+ const fakeRequire = (name: string): any => {
829
+ if (name.endsWith('/hash-password')) {
830
+ return (password: string) => 'hashed:' + password
831
+ }
832
+ if (name.endsWith('/auth-options')) {
833
+ return {
834
+ userExistsByEmail: async () => false,
835
+ createUser: async (userData: Record<string, unknown>) => {
836
+ created = userData
837
+ return { id: 'u1', ...userData }
838
+ },
839
+ sanitizeUser: (user: unknown) => user,
840
+ }
841
+ }
842
+ return { resolveRequestLocale: () => 'en' }
843
+ }
844
+ const moduleObj: { exports: any } = { exports: {} }
845
+ new Function('require', 'module', 'exports', 'console', code)(
846
+ fakeRequire,
847
+ moduleObj,
848
+ moduleObj.exports,
849
+ { error: () => undefined, warn: () => undefined, log: () => undefined }
850
+ )
851
+ const res = {
852
+ status() {
853
+ return this
854
+ },
855
+ json() {
856
+ return this
857
+ },
858
+ }
859
+ await moduleObj.exports({ method: 'POST', headers: {}, body }, res)
860
+ return created
861
+ }
862
+
863
+ it('signs a new account up as a plain user whatever role-bearing property the body names', async () => {
864
+ const created = await signupWith(
865
+ {
866
+ email: 'm@x.io',
867
+ password: 'secret1',
868
+ role: 'admin',
869
+ roles: ['admin'],
870
+ Role: 'admin',
871
+ company: 'ACME',
872
+ },
873
+ [{ key: 'roles' }, { key: 'Role' }, { key: 'company' }]
874
+ )
875
+ expect(created.role).toBe('user')
876
+ expect(created.roles).toBeUndefined()
877
+ expect(created.Role).toBeUndefined()
878
+ // An ordinary custom property still lands.
879
+ expect(created.company).toBe('ACME')
880
+ })
881
+
882
+ it('keeps the server signup node from copying a role-bearing config key onto the new row', () => {
883
+ const source = accountSignup.generateServerHandler!()
884
+ expect(source).toContain('const roleBearingKey = /^(roles?|role_?name)$/i;')
885
+ expect(source).toContain(
886
+ 'if (!reservedKeys[configKeys[i]] && !roleBearingKey.test(configKeys[i])) {'
887
+ )
888
+ })
889
+
890
+ it('guards the users table on an auth config that declares no tables', () => {
891
+ expect(resolveAuthUsersTableName({ enabled: true })).toBe('users')
892
+ expect(resolveAuthUsersTableName({ enabled: true, tables: {} })).toBe('users')
893
+ expect(resolveAuthUsersTableName({ enabled: false })).toBeUndefined()
894
+ expect(resolveAuthUsersTableName(undefined)).toBeUndefined()
895
+ })
896
+ })
897
+
898
+ describe('server-side data nodes present the internal secret', () => {
899
+ it('is sent by every node that reaches the route from a server segment', () => {
900
+ for (const node of [
901
+ dataSelect,
902
+ dataCount,
903
+ dataCreateItem,
904
+ dataRawQuery,
905
+ dataUpdateItem,
906
+ dataDeleteItem,
907
+ ]) {
908
+ const source = node.generateHandler()
909
+ expect(source).toContain("'x-internal-data-secret': (__env && __env.NEXTAUTH_SECRET) || ''")
910
+ // Read off the process, which only exists server-side.
911
+ expect(source).toContain('const __env = globalThis.process && globalThis.process.env')
912
+ }
913
+ })
914
+ })
915
+
916
+ describe('data API — the users table never serves its credentials to a browser', () => {
917
+ const userRow = {
918
+ id: 'u1',
919
+ name: 'Ada',
920
+ email: 'ada@shop.test',
921
+ role: 'user',
922
+ password: '$2b$10$hash',
923
+ access_token: 'ya29.token',
924
+ refresh_token: '1//refresh',
925
+ id_token: 'eyJ.id',
926
+ session_state: 's',
927
+ token_type: 'Bearer',
928
+ scope: 'email',
929
+ expires_at: 1790000000,
930
+ }
931
+ const run = bootRoute(SECRET, { authUsersTableName: 'users', rows: [userRow] })
932
+
933
+ it('refuses a browser the users table outright — the list is every customer', async () => {
934
+ for (const body of [
935
+ { tableName: 'users' },
936
+ { tableName: 'users', selectedColumns: ['id', 'password'] },
937
+ ]) {
938
+ const result = await run('select', body)
939
+ expect(result.status).toBe(403)
940
+ expect(result.queries).toEqual([])
941
+ }
942
+ })
943
+
944
+ it('serves the whole row to a server segment, which checks a password or refreshes a token', async () => {
945
+ const result = await run('select', { tableName: 'users' }, internal)
946
+ expect(result.body.rows).toEqual([userRow])
947
+ })
948
+ })