@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.
- package/__tests__/_helpers/bind-workflow-utils.ts +16 -1
- package/__tests__/_helpers/fake-fetch.ts +96 -0
- package/__tests__/_helpers/fake-stripe.ts +52 -0
- package/__tests__/_helpers/load-handler.ts +22 -3
- package/__tests__/_helpers/load-invoice-route.ts +75 -0
- package/__tests__/_helpers/load-payment-drivers.ts +69 -0
- package/__tests__/_helpers/load-server-runtime.ts +33 -0
- package/__tests__/_helpers/run-generated-middleware.ts +50 -9
- package/__tests__/admin-form-hydration-target.test.ts +39 -0
- package/__tests__/admin-form-row-hydration.test.ts +58 -0
- package/__tests__/ai-select-database-data-handler.test.ts +14 -3
- package/__tests__/api-route-file-name-segments.test.ts +33 -0
- package/__tests__/app-secret-env.test.ts +55 -0
- package/__tests__/auth-env-secret-preservation.test.ts +22 -3
- package/__tests__/auth-nextauth-url.test.ts +134 -50
- package/__tests__/cart-add-item-kinds.test.ts +259 -0
- package/__tests__/cart-add-item-line-fields.test.ts +328 -0
- package/__tests__/cart-availability-add-to-cart.test.ts +108 -0
- package/__tests__/cart-get-total-discounts.test.ts +499 -0
- package/__tests__/cart-get-total-product-options.test.ts +195 -0
- package/__tests__/cart-get-total-subscriptions.test.ts +221 -0
- package/__tests__/cart-price-order.test.ts +283 -0
- package/__tests__/cart-update-item-quantity-recurring.test.ts +75 -0
- package/__tests__/client-loop-current-item.test.ts +164 -0
- package/__tests__/cron-route-loop-custom-node.test.ts +123 -0
- package/__tests__/cron-route-loop-templateparams.test.ts +7 -0
- package/__tests__/cron-route-verification.test.ts +252 -0
- package/__tests__/custom-js-runtime-base-url.test.ts +64 -0
- package/__tests__/custom-nodes-admin-module.test.ts +310 -0
- package/__tests__/data-api-browser-reads.test.ts +341 -0
- package/__tests__/data-api-low-stock-autofire.test.ts +67 -17
- package/__tests__/data-api-optional-feature-columns.test.ts +240 -0
- package/__tests__/data-api-protected-tables.test.ts +948 -0
- package/__tests__/data-node-not-awaited.test.ts +7 -3
- package/__tests__/data-write-missing-filter.test.ts +119 -0
- package/__tests__/ecommerce-rewriter-product-options.test.ts +143 -0
- package/__tests__/email-locale-senders.test.ts +1 -1
- package/__tests__/file-storage-upload-picked-files.test.ts +20 -0
- package/__tests__/input-debounce-per-field.test.ts +141 -0
- package/__tests__/internal-request-headers.test.ts +7 -3
- package/__tests__/invoice-data-access-replace.test.ts +340 -0
- package/__tests__/invoice-delivery-fee.test.ts +3 -2
- package/__tests__/invoice-generate-hydration.test.ts +20 -12
- package/__tests__/invoice-order-items-settle.test.ts +51 -46
- package/__tests__/invoice-product-options.test.ts +177 -0
- package/__tests__/invoice-regenerate-route.test.ts +488 -0
- package/__tests__/invoice-regional-tax.test.ts +3 -2
- package/__tests__/invoice-reservation.test.ts +195 -0
- package/__tests__/invoice-route-access.test.ts +275 -0
- package/__tests__/invoice-self-call-origin.test.ts +117 -0
- package/__tests__/invoice-tender.test.ts +550 -0
- package/__tests__/legacy-webhook-self-calls.test.ts +187 -0
- package/__tests__/locale-aware-redirects.test.ts +55 -26
- package/__tests__/loop-collection-unwrap.test.ts +6 -1
- package/__tests__/middleware-subscriber-access.test.ts +269 -0
- package/__tests__/payment-charge-user-earlier-attempt.test.ts +267 -0
- package/__tests__/payment-charge-user-handler-serialization.test.ts +47 -82
- package/__tests__/payment-charge-user-line-descriptions.test.ts +124 -0
- package/__tests__/payment-charge-user-report-refusal.test.ts +105 -0
- package/__tests__/payment-close-checkout-node.test.ts +127 -0
- package/__tests__/payment-driver-close-checkout.test.ts +1163 -0
- package/__tests__/payment-driver-coingate.test.ts +470 -0
- package/__tests__/payment-driver-inspect-checkout.test.ts +648 -0
- package/__tests__/payment-driver-mollie.test.ts +864 -0
- package/__tests__/payment-driver-paddle.test.ts +870 -0
- package/__tests__/payment-driver-paypal-capture.test.ts +158 -0
- package/__tests__/payment-driver-paypal-webhook.test.ts +367 -0
- package/__tests__/payment-driver-razorpay.test.ts +895 -0
- package/__tests__/payment-driver-square.test.ts +977 -0
- package/__tests__/payment-driver-stripe.test.ts +267 -0
- package/__tests__/payment-drivers-module.test.ts +429 -0
- package/__tests__/payment-legacy-webhook-routes.test.ts +588 -0
- package/__tests__/payment-redirect-and-order-notification.test.ts +98 -39
- package/__tests__/payment-refund.test.ts +523 -22
- package/__tests__/payment-subscription-nodes.test.ts +1360 -0
- package/__tests__/payment-webhook-route.test.ts +523 -0
- package/__tests__/paypal-webhook-signature-verification.test.ts +205 -0
- package/__tests__/prune-context-oversized-leaf.test.ts +1 -0
- package/__tests__/prune-context-state-keys.test.ts +89 -0
- package/__tests__/push-node-handlers.test.ts +291 -0
- package/__tests__/route-changed-trigger.test.ts +40 -0
- package/__tests__/runtime-storage-upload-access.test.ts +255 -0
- package/__tests__/security-runtime-shadow.test.ts +103 -1
- package/__tests__/segment-reply-changed-keys.test.ts +146 -0
- package/__tests__/segment-state-keys-emission.test.ts +185 -0
- package/__tests__/segment-state-needs.test.ts +102 -0
- package/__tests__/server-segment-context-integrity.test.ts +210 -0
- package/__tests__/server-step-signing.test.ts +371 -0
- package/__tests__/session-cookie-resolver.test.ts +59 -0
- package/__tests__/stock-decrement-audit.test.ts +17 -0
- package/__tests__/subscriber-access-route.test.ts +406 -0
- package/__tests__/webhook-delivery-lease.test.ts +316 -0
- package/__tests__/workflow-auth-guard.test.ts +253 -2
- package/dist/cjs/admin-form-hydration.d.ts +10 -0
- package/dist/cjs/admin-form-hydration.d.ts.map +1 -0
- package/dist/cjs/admin-form-hydration.js +25 -0
- package/dist/cjs/admin-form-hydration.js.map +1 -0
- package/dist/cjs/api-route-generator.d.ts +19 -3
- package/dist/cjs/api-route-generator.d.ts.map +1 -1
- package/dist/cjs/api-route-generator.js +190 -70
- package/dist/cjs/api-route-generator.js.map +1 -1
- package/dist/cjs/auth-generator.d.ts +4 -1
- package/dist/cjs/auth-generator.d.ts.map +1 -1
- package/dist/cjs/auth-generator.js +241 -62
- package/dist/cjs/auth-generator.js.map +1 -1
- package/dist/cjs/auth-return/signed-in-destination-code.d.ts +17 -0
- package/dist/cjs/auth-return/signed-in-destination-code.d.ts.map +1 -0
- package/dist/cjs/auth-return/signed-in-destination-code.js +37 -0
- package/dist/cjs/auth-return/signed-in-destination-code.js.map +1 -0
- package/dist/cjs/cart-pricing-preamble.d.ts +12 -0
- package/dist/cjs/cart-pricing-preamble.d.ts.map +1 -0
- package/dist/cjs/cart-pricing-preamble.js +23 -0
- package/dist/cjs/cart-pricing-preamble.js.map +1 -0
- package/dist/cjs/cron-request-verification.d.ts +24 -0
- package/dist/cjs/cron-request-verification.d.ts.map +1 -0
- package/dist/cjs/cron-request-verification.js +84 -0
- package/dist/cjs/cron-request-verification.js.map +1 -0
- package/dist/cjs/custom-node-modules.d.ts +30 -0
- package/dist/cjs/custom-node-modules.d.ts.map +1 -0
- package/dist/cjs/custom-node-modules.js +90 -0
- package/dist/cjs/custom-node-modules.js.map +1 -0
- package/dist/cjs/data-api-route-generator.d.ts +27 -0
- package/dist/cjs/data-api-route-generator.d.ts.map +1 -1
- package/dist/cjs/data-api-route-generator.js +366 -29
- package/dist/cjs/data-api-route-generator.js.map +1 -1
- package/dist/cjs/ecommerce/cart-availability.d.ts.map +1 -1
- package/dist/cjs/ecommerce/cart-availability.js +22 -13
- package/dist/cjs/ecommerce/cart-availability.js.map +1 -1
- package/dist/cjs/ecommerce/stock-decrement.d.ts +2 -1
- package/dist/cjs/ecommerce/stock-decrement.d.ts.map +1 -1
- package/dist/cjs/ecommerce/stock-decrement.js +6 -0
- package/dist/cjs/ecommerce/stock-decrement.js.map +1 -1
- package/dist/cjs/executor-generator.d.ts +0 -1
- package/dist/cjs/executor-generator.d.ts.map +1 -1
- package/dist/cjs/executor-generator.js +213 -20
- package/dist/cjs/executor-generator.js.map +1 -1
- package/dist/cjs/index.d.ts +12 -4
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +25 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/invoice/api-routes-code.d.ts +26 -0
- package/dist/cjs/invoice/api-routes-code.d.ts.map +1 -1
- package/dist/cjs/invoice/api-routes-code.js +423 -391
- package/dist/cjs/invoice/api-routes-code.js.map +1 -1
- package/dist/cjs/invoice/data-access-code.d.ts.map +1 -1
- package/dist/cjs/invoice/data-access-code.js +420 -107
- package/dist/cjs/invoice/data-access-code.js.map +1 -1
- package/dist/cjs/invoice/index.d.ts.map +1 -1
- package/dist/cjs/invoice/index.js +24 -0
- package/dist/cjs/invoice/index.js.map +1 -1
- package/dist/cjs/invoice/invoice-assembly-code.d.ts +12 -0
- package/dist/cjs/invoice/invoice-assembly-code.d.ts.map +1 -0
- package/dist/cjs/invoice/invoice-assembly-code.js +517 -0
- package/dist/cjs/invoice/invoice-assembly-code.js.map +1 -0
- package/dist/cjs/invoice/invoice-html-code.d.ts.map +1 -1
- package/dist/cjs/invoice/invoice-html-code.js +111 -9
- package/dist/cjs/invoice/invoice-html-code.js.map +1 -1
- package/dist/cjs/invoice/pdf-service-client-code.d.ts.map +1 -1
- package/dist/cjs/invoice/pdf-service-client-code.js +3 -4
- package/dist/cjs/invoice/pdf-service-client-code.js.map +1 -1
- package/dist/cjs/nodes/account/account-login.d.ts.map +1 -1
- package/dist/cjs/nodes/account/account-login.js +4 -3
- package/dist/cjs/nodes/account/account-login.js.map +1 -1
- package/dist/cjs/nodes/account/account-signup.d.ts.map +1 -1
- package/dist/cjs/nodes/account/account-signup.js +7 -4
- package/dist/cjs/nodes/account/account-signup.js.map +1 -1
- package/dist/cjs/nodes/ai/ai-select-database-data.d.ts.map +1 -1
- package/dist/cjs/nodes/ai/ai-select-database-data.js +6 -1
- package/dist/cjs/nodes/ai/ai-select-database-data.js.map +1 -1
- package/dist/cjs/nodes/browser/browser-get-push-subscription.d.ts +9 -0
- package/dist/cjs/nodes/browser/browser-get-push-subscription.d.ts.map +1 -0
- package/dist/cjs/nodes/browser/browser-get-push-subscription.js +25 -0
- package/dist/cjs/nodes/browser/browser-get-push-subscription.js.map +1 -0
- package/dist/cjs/nodes/browser/browser-show-notification.d.ts +10 -0
- package/dist/cjs/nodes/browser/browser-show-notification.d.ts.map +1 -1
- package/dist/cjs/nodes/browser/browser-show-notification.js +65 -40
- package/dist/cjs/nodes/browser/browser-show-notification.js.map +1 -1
- package/dist/cjs/nodes/browser/browser-subscribe-to-push.d.ts +11 -0
- package/dist/cjs/nodes/browser/browser-subscribe-to-push.d.ts.map +1 -1
- package/dist/cjs/nodes/browser/browser-subscribe-to-push.js +21 -31
- package/dist/cjs/nodes/browser/browser-subscribe-to-push.js.map +1 -1
- package/dist/cjs/nodes/browser/browser-unsubscribe-from-push.d.ts +8 -0
- package/dist/cjs/nodes/browser/browser-unsubscribe-from-push.d.ts.map +1 -0
- package/dist/cjs/nodes/browser/browser-unsubscribe-from-push.js +24 -0
- package/dist/cjs/nodes/browser/browser-unsubscribe-from-push.js.map +1 -0
- package/dist/cjs/nodes/browser/push-api-access.d.ts +12 -0
- package/dist/cjs/nodes/browser/push-api-access.d.ts.map +1 -0
- package/dist/cjs/nodes/browser/push-api-access.js +19 -0
- package/dist/cjs/nodes/browser/push-api-access.js.map +1 -0
- package/dist/cjs/nodes/cart/cart-add-item.d.ts.map +1 -1
- package/dist/cjs/nodes/cart/cart-add-item.js +174 -10
- package/dist/cjs/nodes/cart/cart-add-item.js.map +1 -1
- package/dist/cjs/nodes/cart/cart-clear.d.ts.map +1 -1
- package/dist/cjs/nodes/cart/cart-clear.js +11 -0
- package/dist/cjs/nodes/cart/cart-clear.js.map +1 -1
- package/dist/cjs/nodes/cart/cart-get-total.d.ts.map +1 -1
- package/dist/cjs/nodes/cart/cart-get-total.js +260 -3
- package/dist/cjs/nodes/cart/cart-get-total.js.map +1 -1
- package/dist/cjs/nodes/cart/cart-price-order.d.ts +3 -0
- package/dist/cjs/nodes/cart/cart-price-order.d.ts.map +1 -0
- package/dist/cjs/nodes/cart/cart-price-order.js +281 -0
- package/dist/cjs/nodes/cart/cart-price-order.js.map +1 -0
- package/dist/cjs/nodes/cart/cart-update-item-quantity.d.ts.map +1 -1
- package/dist/cjs/nodes/cart/cart-update-item-quantity.js +7 -0
- package/dist/cjs/nodes/cart/cart-update-item-quantity.js.map +1 -1
- package/dist/cjs/nodes/data/data-count.d.ts.map +1 -1
- package/dist/cjs/nodes/data/data-count.js +6 -1
- package/dist/cjs/nodes/data/data-count.js.map +1 -1
- package/dist/cjs/nodes/data/data-create-item.d.ts.map +1 -1
- package/dist/cjs/nodes/data/data-create-item.js +11 -1
- package/dist/cjs/nodes/data/data-create-item.js.map +1 -1
- package/dist/cjs/nodes/data/data-delete-item.d.ts.map +1 -1
- package/dist/cjs/nodes/data/data-delete-item.js +29 -0
- package/dist/cjs/nodes/data/data-delete-item.js.map +1 -1
- package/dist/cjs/nodes/data/data-raw-query.d.ts.map +1 -1
- package/dist/cjs/nodes/data/data-raw-query.js +6 -1
- package/dist/cjs/nodes/data/data-raw-query.js.map +1 -1
- package/dist/cjs/nodes/data/data-select.d.ts.map +1 -1
- package/dist/cjs/nodes/data/data-select.js +6 -1
- package/dist/cjs/nodes/data/data-select.js.map +1 -1
- package/dist/cjs/nodes/data/data-update-item.d.ts.map +1 -1
- package/dist/cjs/nodes/data/data-update-item.js +29 -0
- package/dist/cjs/nodes/data/data-update-item.js.map +1 -1
- package/dist/cjs/nodes/ecommerce/ecommerce-generate-invoice.d.ts.map +1 -1
- package/dist/cjs/nodes/ecommerce/ecommerce-generate-invoice.js +7 -1
- package/dist/cjs/nodes/ecommerce/ecommerce-generate-invoice.js.map +1 -1
- package/dist/cjs/nodes/file-storage/file-storage-upload.d.ts.map +1 -1
- package/dist/cjs/nodes/file-storage/file-storage-upload.js +7 -0
- package/dist/cjs/nodes/file-storage/file-storage-upload.js.map +1 -1
- package/dist/cjs/nodes/general/general-custom-js.d.ts.map +1 -1
- package/dist/cjs/nodes/general/general-custom-js.js +21 -5
- package/dist/cjs/nodes/general/general-custom-js.js.map +1 -1
- package/dist/cjs/nodes/index.d.ts.map +1 -1
- package/dist/cjs/nodes/index.js +9 -4
- package/dist/cjs/nodes/index.js.map +1 -1
- package/dist/cjs/nodes/payment/payment-billing-portal.d.ts +3 -0
- package/dist/cjs/nodes/payment/payment-billing-portal.d.ts.map +1 -0
- package/dist/cjs/nodes/payment/payment-billing-portal.js +52 -0
- package/dist/cjs/nodes/payment/payment-billing-portal.js.map +1 -0
- package/dist/cjs/nodes/payment/payment-charge-user.d.ts.map +1 -1
- package/dist/cjs/nodes/payment/payment-charge-user.js +227 -360
- package/dist/cjs/nodes/payment/payment-charge-user.js.map +1 -1
- package/dist/cjs/nodes/payment/payment-close-checkout.d.ts +3 -0
- package/dist/cjs/nodes/payment/payment-close-checkout.d.ts.map +1 -0
- package/dist/cjs/nodes/payment/payment-close-checkout.js +141 -0
- package/dist/cjs/nodes/payment/payment-close-checkout.js.map +1 -0
- package/dist/cjs/nodes/payment/payment-ensure-subscription-plan.d.ts +3 -0
- package/dist/cjs/nodes/payment/payment-ensure-subscription-plan.d.ts.map +1 -0
- package/dist/cjs/nodes/payment/payment-ensure-subscription-plan.js +67 -0
- package/dist/cjs/nodes/payment/payment-ensure-subscription-plan.js.map +1 -0
- package/dist/cjs/nodes/payment/payment-manage-subscription.d.ts +3 -0
- package/dist/cjs/nodes/payment/payment-manage-subscription.d.ts.map +1 -0
- package/dist/cjs/nodes/payment/payment-manage-subscription.js +89 -0
- package/dist/cjs/nodes/payment/payment-manage-subscription.js.map +1 -0
- package/dist/cjs/nodes/payment/payment-refund.d.ts.map +1 -1
- package/dist/cjs/nodes/payment/payment-refund.js +50 -404
- package/dist/cjs/nodes/payment/payment-refund.js.map +1 -1
- package/dist/cjs/nodes/push/push-send-notification.d.ts +14 -0
- package/dist/cjs/nodes/push/push-send-notification.d.ts.map +1 -0
- package/dist/cjs/nodes/push/push-send-notification.js +83 -0
- package/dist/cjs/nodes/push/push-send-notification.js.map +1 -0
- package/dist/cjs/payments/drivers/coingate-driver-code.d.ts +16 -0
- package/dist/cjs/payments/drivers/coingate-driver-code.d.ts.map +1 -0
- package/dist/cjs/payments/drivers/coingate-driver-code.js +471 -0
- package/dist/cjs/payments/drivers/coingate-driver-code.js.map +1 -0
- package/dist/cjs/payments/drivers/mollie-driver-code.d.ts +16 -0
- package/dist/cjs/payments/drivers/mollie-driver-code.d.ts.map +1 -0
- package/dist/cjs/payments/drivers/mollie-driver-code.js +623 -0
- package/dist/cjs/payments/drivers/mollie-driver-code.js.map +1 -0
- package/dist/cjs/payments/drivers/paddle-driver-code.d.ts +12 -0
- package/dist/cjs/payments/drivers/paddle-driver-code.d.ts.map +1 -0
- package/dist/cjs/payments/drivers/paddle-driver-code.js +683 -0
- package/dist/cjs/payments/drivers/paddle-driver-code.js.map +1 -0
- package/dist/cjs/payments/drivers/paypal-driver-code.d.ts +12 -0
- package/dist/cjs/payments/drivers/paypal-driver-code.d.ts.map +1 -0
- package/dist/cjs/payments/drivers/paypal-driver-code.js +1261 -0
- package/dist/cjs/payments/drivers/paypal-driver-code.js.map +1 -0
- package/dist/cjs/payments/drivers/razorpay-driver-code.d.ts +12 -0
- package/dist/cjs/payments/drivers/razorpay-driver-code.d.ts.map +1 -0
- package/dist/cjs/payments/drivers/razorpay-driver-code.js +732 -0
- package/dist/cjs/payments/drivers/razorpay-driver-code.js.map +1 -0
- package/dist/cjs/payments/drivers/square-driver-code.d.ts +14 -0
- package/dist/cjs/payments/drivers/square-driver-code.d.ts.map +1 -0
- package/dist/cjs/payments/drivers/square-driver-code.js +931 -0
- package/dist/cjs/payments/drivers/square-driver-code.js.map +1 -0
- package/dist/cjs/payments/drivers/stripe-driver-code.d.ts +12 -0
- package/dist/cjs/payments/drivers/stripe-driver-code.d.ts.map +1 -0
- package/dist/cjs/payments/drivers/stripe-driver-code.js +778 -0
- package/dist/cjs/payments/drivers/stripe-driver-code.js.map +1 -0
- package/dist/cjs/payments/index.d.ts +66 -0
- package/dist/cjs/payments/index.d.ts.map +1 -0
- package/dist/cjs/payments/index.js +175 -0
- package/dist/cjs/payments/index.js.map +1 -0
- package/dist/cjs/payments/payment-core-code.d.ts +19 -0
- package/dist/cjs/payments/payment-core-code.d.ts.map +1 -0
- package/dist/cjs/payments/payment-core-code.js +422 -0
- package/dist/cjs/payments/payment-core-code.js.map +1 -0
- package/dist/cjs/payments/payment-driver-code-map.d.ts +4 -0
- package/dist/cjs/payments/payment-driver-code-map.d.ts.map +1 -0
- package/dist/cjs/payments/payment-driver-code-map.js +21 -0
- package/dist/cjs/payments/payment-driver-code-map.js.map +1 -0
- package/dist/cjs/payments/payment-drivers-scope.d.ts +35 -0
- package/dist/cjs/payments/payment-drivers-scope.d.ts.map +1 -0
- package/dist/cjs/payments/payment-drivers-scope.js +56 -0
- package/dist/cjs/payments/payment-drivers-scope.js.map +1 -0
- package/dist/cjs/payments/payment-registry-code.d.ts +8 -0
- package/dist/cjs/payments/payment-registry-code.d.ts.map +1 -0
- package/dist/cjs/payments/payment-registry-code.js +41 -0
- package/dist/cjs/payments/payment-registry-code.js.map +1 -0
- package/dist/cjs/pg-client-code.d.ts +10 -0
- package/dist/cjs/pg-client-code.d.ts.map +1 -1
- package/dist/cjs/pg-client-code.js +27 -1
- package/dist/cjs/pg-client-code.js.map +1 -1
- package/dist/cjs/runtime-storage-generator.d.ts +28 -0
- package/dist/cjs/runtime-storage-generator.d.ts.map +1 -1
- package/dist/cjs/runtime-storage-generator.js +240 -5
- package/dist/cjs/runtime-storage-generator.js.map +1 -1
- package/dist/cjs/secret-collector.d.ts.map +1 -1
- package/dist/cjs/secret-collector.js +8 -3
- package/dist/cjs/secret-collector.js.map +1 -1
- package/dist/cjs/security-scanner.d.ts +10 -1
- package/dist/cjs/security-scanner.d.ts.map +1 -1
- package/dist/cjs/security-scanner.js +19 -1
- package/dist/cjs/security-scanner.js.map +1 -1
- package/dist/cjs/segment-context-needs.d.ts +38 -0
- package/dist/cjs/segment-context-needs.d.ts.map +1 -0
- package/dist/cjs/segment-context-needs.js +129 -0
- package/dist/cjs/segment-context-needs.js.map +1 -0
- package/dist/cjs/segment-splitter.d.ts.map +1 -1
- package/dist/cjs/segment-splitter.js +6 -1
- package/dist/cjs/segment-splitter.js.map +1 -1
- package/dist/cjs/segment-trust.d.ts +50 -0
- package/dist/cjs/segment-trust.d.ts.map +1 -0
- package/dist/cjs/segment-trust.js +115 -0
- package/dist/cjs/segment-trust.js.map +1 -0
- package/dist/cjs/sent-email-log/sent-email-log-code.d.ts +19 -0
- package/dist/cjs/sent-email-log/sent-email-log-code.d.ts.map +1 -1
- package/dist/cjs/sent-email-log/sent-email-log-code.js +1 -24
- package/dist/cjs/sent-email-log/sent-email-log-code.js.map +1 -1
- package/dist/cjs/server-runtime-code.d.ts +34 -0
- package/dist/cjs/server-runtime-code.d.ts.map +1 -0
- package/dist/cjs/server-runtime-code.js +303 -0
- package/dist/cjs/server-runtime-code.js.map +1 -0
- package/dist/cjs/session-cookie-resolver.d.ts +3 -78
- package/dist/cjs/session-cookie-resolver.d.ts.map +1 -1
- package/dist/cjs/session-cookie-resolver.js +7 -276
- package/dist/cjs/session-cookie-resolver.js.map +1 -1
- package/dist/cjs/subscriber-access-route-generator.d.ts +71 -0
- package/dist/cjs/subscriber-access-route-generator.d.ts.map +1 -0
- package/dist/cjs/subscriber-access-route-generator.js +301 -0
- package/dist/cjs/subscriber-access-route-generator.js.map +1 -0
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/cjs/types.d.ts +6 -0
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/cjs/webhook-delivery-lease/index.d.ts +8 -0
- package/dist/cjs/webhook-delivery-lease/index.d.ts.map +1 -0
- package/dist/cjs/webhook-delivery-lease/index.js +41 -0
- package/dist/cjs/webhook-delivery-lease/index.js.map +1 -0
- package/dist/cjs/webhook-delivery-lease/webhook-delivery-lease-code.d.ts +26 -0
- package/dist/cjs/webhook-delivery-lease/webhook-delivery-lease-code.d.ts.map +1 -0
- package/dist/cjs/webhook-delivery-lease/webhook-delivery-lease-code.js +151 -0
- package/dist/cjs/webhook-delivery-lease/webhook-delivery-lease-code.js.map +1 -0
- package/dist/cjs/webhook-delivery-lease/webhook-delivery-lease-scope.d.ts +16 -0
- package/dist/cjs/webhook-delivery-lease/webhook-delivery-lease-scope.d.ts.map +1 -0
- package/dist/cjs/webhook-delivery-lease/webhook-delivery-lease-scope.js +19 -0
- package/dist/cjs/webhook-delivery-lease/webhook-delivery-lease-scope.js.map +1 -0
- package/dist/cjs/webhook-generator.d.ts +1 -1
- package/dist/cjs/webhook-generator.d.ts.map +1 -1
- package/dist/cjs/webhook-generator.js +342 -254
- package/dist/cjs/webhook-generator.js.map +1 -1
- package/dist/cjs/webhook-signature-verification.d.ts +17 -1
- package/dist/cjs/webhook-signature-verification.d.ts.map +1 -1
- package/dist/cjs/webhook-signature-verification.js +182 -27
- package/dist/cjs/webhook-signature-verification.js.map +1 -1
- package/dist/cjs/workflow-auth-generator.d.ts +9 -6
- package/dist/cjs/workflow-auth-generator.d.ts.map +1 -1
- package/dist/cjs/workflow-auth-generator.js +133 -29
- package/dist/cjs/workflow-auth-generator.js.map +1 -1
- package/dist/cjs/workflow-component-plugin.d.ts.map +1 -1
- package/dist/cjs/workflow-component-plugin.js +65 -28
- package/dist/cjs/workflow-component-plugin.js.map +1 -1
- package/dist/cjs/workflow-project-plugin.d.ts +13 -0
- package/dist/cjs/workflow-project-plugin.d.ts.map +1 -1
- package/dist/cjs/workflow-project-plugin.js +215 -65
- package/dist/cjs/workflow-project-plugin.js.map +1 -1
- package/dist/esm/admin-form-hydration.d.ts +10 -0
- package/dist/esm/admin-form-hydration.d.ts.map +1 -0
- package/dist/esm/admin-form-hydration.js +21 -0
- package/dist/esm/admin-form-hydration.js.map +1 -0
- package/dist/esm/api-route-generator.d.ts +19 -3
- package/dist/esm/api-route-generator.d.ts.map +1 -1
- package/dist/esm/api-route-generator.js +189 -70
- package/dist/esm/api-route-generator.js.map +1 -1
- package/dist/esm/auth-generator.d.ts +4 -1
- package/dist/esm/auth-generator.d.ts.map +1 -1
- package/dist/esm/auth-generator.js +241 -62
- package/dist/esm/auth-generator.js.map +1 -1
- package/dist/esm/auth-return/signed-in-destination-code.d.ts +17 -0
- package/dist/esm/auth-return/signed-in-destination-code.d.ts.map +1 -0
- package/dist/esm/auth-return/signed-in-destination-code.js +33 -0
- package/dist/esm/auth-return/signed-in-destination-code.js.map +1 -0
- package/dist/esm/cart-pricing-preamble.d.ts +12 -0
- package/dist/esm/cart-pricing-preamble.d.ts.map +1 -0
- package/dist/esm/cart-pricing-preamble.js +19 -0
- package/dist/esm/cart-pricing-preamble.js.map +1 -0
- package/dist/esm/cron-request-verification.d.ts +24 -0
- package/dist/esm/cron-request-verification.d.ts.map +1 -0
- package/dist/esm/cron-request-verification.js +80 -0
- package/dist/esm/cron-request-verification.js.map +1 -0
- package/dist/esm/custom-node-modules.d.ts +30 -0
- package/dist/esm/custom-node-modules.d.ts.map +1 -0
- package/dist/esm/custom-node-modules.js +84 -0
- package/dist/esm/custom-node-modules.js.map +1 -0
- package/dist/esm/data-api-route-generator.d.ts +27 -0
- package/dist/esm/data-api-route-generator.d.ts.map +1 -1
- package/dist/esm/data-api-route-generator.js +365 -28
- package/dist/esm/data-api-route-generator.js.map +1 -1
- package/dist/esm/ecommerce/cart-availability.d.ts.map +1 -1
- package/dist/esm/ecommerce/cart-availability.js +22 -13
- package/dist/esm/ecommerce/cart-availability.js.map +1 -1
- package/dist/esm/ecommerce/stock-decrement.d.ts +2 -1
- package/dist/esm/ecommerce/stock-decrement.d.ts.map +1 -1
- package/dist/esm/ecommerce/stock-decrement.js +6 -0
- package/dist/esm/ecommerce/stock-decrement.js.map +1 -1
- package/dist/esm/executor-generator.d.ts +0 -1
- package/dist/esm/executor-generator.d.ts.map +1 -1
- package/dist/esm/executor-generator.js +212 -18
- package/dist/esm/executor-generator.js.map +1 -1
- package/dist/esm/index.d.ts +12 -4
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +10 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/invoice/api-routes-code.d.ts +26 -0
- package/dist/esm/invoice/api-routes-code.d.ts.map +1 -1
- package/dist/esm/invoice/api-routes-code.js +421 -390
- package/dist/esm/invoice/api-routes-code.js.map +1 -1
- package/dist/esm/invoice/data-access-code.d.ts.map +1 -1
- package/dist/esm/invoice/data-access-code.js +420 -107
- package/dist/esm/invoice/data-access-code.js.map +1 -1
- package/dist/esm/invoice/index.d.ts.map +1 -1
- package/dist/esm/invoice/index.js +25 -1
- package/dist/esm/invoice/index.js.map +1 -1
- package/dist/esm/invoice/invoice-assembly-code.d.ts +12 -0
- package/dist/esm/invoice/invoice-assembly-code.d.ts.map +1 -0
- package/dist/esm/invoice/invoice-assembly-code.js +513 -0
- package/dist/esm/invoice/invoice-assembly-code.js.map +1 -0
- package/dist/esm/invoice/invoice-html-code.d.ts.map +1 -1
- package/dist/esm/invoice/invoice-html-code.js +111 -9
- package/dist/esm/invoice/invoice-html-code.js.map +1 -1
- package/dist/esm/invoice/pdf-service-client-code.d.ts.map +1 -1
- package/dist/esm/invoice/pdf-service-client-code.js +3 -4
- package/dist/esm/invoice/pdf-service-client-code.js.map +1 -1
- package/dist/esm/nodes/account/account-login.d.ts.map +1 -1
- package/dist/esm/nodes/account/account-login.js +4 -3
- package/dist/esm/nodes/account/account-login.js.map +1 -1
- package/dist/esm/nodes/account/account-signup.d.ts.map +1 -1
- package/dist/esm/nodes/account/account-signup.js +7 -4
- package/dist/esm/nodes/account/account-signup.js.map +1 -1
- package/dist/esm/nodes/ai/ai-select-database-data.d.ts.map +1 -1
- package/dist/esm/nodes/ai/ai-select-database-data.js +6 -1
- package/dist/esm/nodes/ai/ai-select-database-data.js.map +1 -1
- package/dist/esm/nodes/browser/browser-get-push-subscription.d.ts +9 -0
- package/dist/esm/nodes/browser/browser-get-push-subscription.d.ts.map +1 -0
- package/dist/esm/nodes/browser/browser-get-push-subscription.js +22 -0
- package/dist/esm/nodes/browser/browser-get-push-subscription.js.map +1 -0
- package/dist/esm/nodes/browser/browser-show-notification.d.ts +10 -0
- package/dist/esm/nodes/browser/browser-show-notification.d.ts.map +1 -1
- package/dist/esm/nodes/browser/browser-show-notification.js +65 -40
- package/dist/esm/nodes/browser/browser-show-notification.js.map +1 -1
- package/dist/esm/nodes/browser/browser-subscribe-to-push.d.ts +11 -0
- package/dist/esm/nodes/browser/browser-subscribe-to-push.d.ts.map +1 -1
- package/dist/esm/nodes/browser/browser-subscribe-to-push.js +21 -31
- package/dist/esm/nodes/browser/browser-subscribe-to-push.js.map +1 -1
- package/dist/esm/nodes/browser/browser-unsubscribe-from-push.d.ts +8 -0
- package/dist/esm/nodes/browser/browser-unsubscribe-from-push.d.ts.map +1 -0
- package/dist/esm/nodes/browser/browser-unsubscribe-from-push.js +21 -0
- package/dist/esm/nodes/browser/browser-unsubscribe-from-push.js.map +1 -0
- package/dist/esm/nodes/browser/push-api-access.d.ts +12 -0
- package/dist/esm/nodes/browser/push-api-access.d.ts.map +1 -0
- package/dist/esm/nodes/browser/push-api-access.js +13 -0
- package/dist/esm/nodes/browser/push-api-access.js.map +1 -0
- package/dist/esm/nodes/cart/cart-add-item.d.ts.map +1 -1
- package/dist/esm/nodes/cart/cart-add-item.js +174 -10
- package/dist/esm/nodes/cart/cart-add-item.js.map +1 -1
- package/dist/esm/nodes/cart/cart-clear.d.ts.map +1 -1
- package/dist/esm/nodes/cart/cart-clear.js +11 -0
- package/dist/esm/nodes/cart/cart-clear.js.map +1 -1
- package/dist/esm/nodes/cart/cart-get-total.d.ts.map +1 -1
- package/dist/esm/nodes/cart/cart-get-total.js +261 -4
- package/dist/esm/nodes/cart/cart-get-total.js.map +1 -1
- package/dist/esm/nodes/cart/cart-price-order.d.ts +3 -0
- package/dist/esm/nodes/cart/cart-price-order.d.ts.map +1 -0
- package/dist/esm/nodes/cart/cart-price-order.js +278 -0
- package/dist/esm/nodes/cart/cart-price-order.js.map +1 -0
- package/dist/esm/nodes/cart/cart-update-item-quantity.d.ts.map +1 -1
- package/dist/esm/nodes/cart/cart-update-item-quantity.js +7 -0
- package/dist/esm/nodes/cart/cart-update-item-quantity.js.map +1 -1
- package/dist/esm/nodes/data/data-count.d.ts.map +1 -1
- package/dist/esm/nodes/data/data-count.js +6 -1
- package/dist/esm/nodes/data/data-count.js.map +1 -1
- package/dist/esm/nodes/data/data-create-item.d.ts.map +1 -1
- package/dist/esm/nodes/data/data-create-item.js +11 -1
- package/dist/esm/nodes/data/data-create-item.js.map +1 -1
- package/dist/esm/nodes/data/data-delete-item.d.ts.map +1 -1
- package/dist/esm/nodes/data/data-delete-item.js +29 -0
- package/dist/esm/nodes/data/data-delete-item.js.map +1 -1
- package/dist/esm/nodes/data/data-raw-query.d.ts.map +1 -1
- package/dist/esm/nodes/data/data-raw-query.js +6 -1
- package/dist/esm/nodes/data/data-raw-query.js.map +1 -1
- package/dist/esm/nodes/data/data-select.d.ts.map +1 -1
- package/dist/esm/nodes/data/data-select.js +6 -1
- package/dist/esm/nodes/data/data-select.js.map +1 -1
- package/dist/esm/nodes/data/data-update-item.d.ts.map +1 -1
- package/dist/esm/nodes/data/data-update-item.js +29 -0
- package/dist/esm/nodes/data/data-update-item.js.map +1 -1
- package/dist/esm/nodes/ecommerce/ecommerce-generate-invoice.d.ts.map +1 -1
- package/dist/esm/nodes/ecommerce/ecommerce-generate-invoice.js +7 -1
- package/dist/esm/nodes/ecommerce/ecommerce-generate-invoice.js.map +1 -1
- package/dist/esm/nodes/file-storage/file-storage-upload.d.ts.map +1 -1
- package/dist/esm/nodes/file-storage/file-storage-upload.js +7 -0
- package/dist/esm/nodes/file-storage/file-storage-upload.js.map +1 -1
- package/dist/esm/nodes/general/general-custom-js.d.ts.map +1 -1
- package/dist/esm/nodes/general/general-custom-js.js +21 -5
- package/dist/esm/nodes/general/general-custom-js.js.map +1 -1
- package/dist/esm/nodes/index.d.ts.map +1 -1
- package/dist/esm/nodes/index.js +9 -4
- package/dist/esm/nodes/index.js.map +1 -1
- package/dist/esm/nodes/payment/payment-billing-portal.d.ts +3 -0
- package/dist/esm/nodes/payment/payment-billing-portal.d.ts.map +1 -0
- package/dist/esm/nodes/payment/payment-billing-portal.js +49 -0
- package/dist/esm/nodes/payment/payment-billing-portal.js.map +1 -0
- package/dist/esm/nodes/payment/payment-charge-user.d.ts.map +1 -1
- package/dist/esm/nodes/payment/payment-charge-user.js +227 -360
- package/dist/esm/nodes/payment/payment-charge-user.js.map +1 -1
- package/dist/esm/nodes/payment/payment-close-checkout.d.ts +3 -0
- package/dist/esm/nodes/payment/payment-close-checkout.d.ts.map +1 -0
- package/dist/esm/nodes/payment/payment-close-checkout.js +138 -0
- package/dist/esm/nodes/payment/payment-close-checkout.js.map +1 -0
- package/dist/esm/nodes/payment/payment-ensure-subscription-plan.d.ts +3 -0
- package/dist/esm/nodes/payment/payment-ensure-subscription-plan.d.ts.map +1 -0
- package/dist/esm/nodes/payment/payment-ensure-subscription-plan.js +64 -0
- package/dist/esm/nodes/payment/payment-ensure-subscription-plan.js.map +1 -0
- package/dist/esm/nodes/payment/payment-manage-subscription.d.ts +3 -0
- package/dist/esm/nodes/payment/payment-manage-subscription.d.ts.map +1 -0
- package/dist/esm/nodes/payment/payment-manage-subscription.js +86 -0
- package/dist/esm/nodes/payment/payment-manage-subscription.js.map +1 -0
- package/dist/esm/nodes/payment/payment-refund.d.ts.map +1 -1
- package/dist/esm/nodes/payment/payment-refund.js +50 -404
- package/dist/esm/nodes/payment/payment-refund.js.map +1 -1
- package/dist/esm/nodes/push/push-send-notification.d.ts +14 -0
- package/dist/esm/nodes/push/push-send-notification.d.ts.map +1 -0
- package/dist/esm/nodes/push/push-send-notification.js +80 -0
- package/dist/esm/nodes/push/push-send-notification.js.map +1 -0
- package/dist/esm/payments/drivers/coingate-driver-code.d.ts +16 -0
- package/dist/esm/payments/drivers/coingate-driver-code.d.ts.map +1 -0
- package/dist/esm/payments/drivers/coingate-driver-code.js +467 -0
- package/dist/esm/payments/drivers/coingate-driver-code.js.map +1 -0
- package/dist/esm/payments/drivers/mollie-driver-code.d.ts +16 -0
- package/dist/esm/payments/drivers/mollie-driver-code.d.ts.map +1 -0
- package/dist/esm/payments/drivers/mollie-driver-code.js +619 -0
- package/dist/esm/payments/drivers/mollie-driver-code.js.map +1 -0
- package/dist/esm/payments/drivers/paddle-driver-code.d.ts +12 -0
- package/dist/esm/payments/drivers/paddle-driver-code.d.ts.map +1 -0
- package/dist/esm/payments/drivers/paddle-driver-code.js +679 -0
- package/dist/esm/payments/drivers/paddle-driver-code.js.map +1 -0
- package/dist/esm/payments/drivers/paypal-driver-code.d.ts +12 -0
- package/dist/esm/payments/drivers/paypal-driver-code.d.ts.map +1 -0
- package/dist/esm/payments/drivers/paypal-driver-code.js +1257 -0
- package/dist/esm/payments/drivers/paypal-driver-code.js.map +1 -0
- package/dist/esm/payments/drivers/razorpay-driver-code.d.ts +12 -0
- package/dist/esm/payments/drivers/razorpay-driver-code.d.ts.map +1 -0
- package/dist/esm/payments/drivers/razorpay-driver-code.js +728 -0
- package/dist/esm/payments/drivers/razorpay-driver-code.js.map +1 -0
- package/dist/esm/payments/drivers/square-driver-code.d.ts +14 -0
- package/dist/esm/payments/drivers/square-driver-code.d.ts.map +1 -0
- package/dist/esm/payments/drivers/square-driver-code.js +927 -0
- package/dist/esm/payments/drivers/square-driver-code.js.map +1 -0
- package/dist/esm/payments/drivers/stripe-driver-code.d.ts +12 -0
- package/dist/esm/payments/drivers/stripe-driver-code.d.ts.map +1 -0
- package/dist/esm/payments/drivers/stripe-driver-code.js +774 -0
- package/dist/esm/payments/drivers/stripe-driver-code.js.map +1 -0
- package/dist/esm/payments/index.d.ts +66 -0
- package/dist/esm/payments/index.d.ts.map +1 -0
- package/dist/esm/payments/index.js +164 -0
- package/dist/esm/payments/index.js.map +1 -0
- package/dist/esm/payments/payment-core-code.d.ts +19 -0
- package/dist/esm/payments/payment-core-code.d.ts.map +1 -0
- package/dist/esm/payments/payment-core-code.js +418 -0
- package/dist/esm/payments/payment-core-code.js.map +1 -0
- package/dist/esm/payments/payment-driver-code-map.d.ts +4 -0
- package/dist/esm/payments/payment-driver-code-map.d.ts.map +1 -0
- package/dist/esm/payments/payment-driver-code-map.js +18 -0
- package/dist/esm/payments/payment-driver-code-map.js.map +1 -0
- package/dist/esm/payments/payment-drivers-scope.d.ts +35 -0
- package/dist/esm/payments/payment-drivers-scope.d.ts.map +1 -0
- package/dist/esm/payments/payment-drivers-scope.js +51 -0
- package/dist/esm/payments/payment-drivers-scope.js.map +1 -0
- package/dist/esm/payments/payment-registry-code.d.ts +8 -0
- package/dist/esm/payments/payment-registry-code.d.ts.map +1 -0
- package/dist/esm/payments/payment-registry-code.js +37 -0
- package/dist/esm/payments/payment-registry-code.js.map +1 -0
- package/dist/esm/pg-client-code.d.ts +10 -0
- package/dist/esm/pg-client-code.d.ts.map +1 -1
- package/dist/esm/pg-client-code.js +25 -0
- package/dist/esm/pg-client-code.js.map +1 -1
- package/dist/esm/runtime-storage-generator.d.ts +28 -0
- package/dist/esm/runtime-storage-generator.d.ts.map +1 -1
- package/dist/esm/runtime-storage-generator.js +239 -4
- package/dist/esm/runtime-storage-generator.js.map +1 -1
- package/dist/esm/secret-collector.d.ts.map +1 -1
- package/dist/esm/secret-collector.js +8 -3
- package/dist/esm/secret-collector.js.map +1 -1
- package/dist/esm/security-scanner.d.ts +10 -1
- package/dist/esm/security-scanner.d.ts.map +1 -1
- package/dist/esm/security-scanner.js +18 -0
- package/dist/esm/security-scanner.js.map +1 -1
- package/dist/esm/segment-context-needs.d.ts +38 -0
- package/dist/esm/segment-context-needs.d.ts.map +1 -0
- package/dist/esm/segment-context-needs.js +125 -0
- package/dist/esm/segment-context-needs.js.map +1 -0
- package/dist/esm/segment-splitter.d.ts.map +1 -1
- package/dist/esm/segment-splitter.js +6 -1
- package/dist/esm/segment-splitter.js.map +1 -1
- package/dist/esm/segment-trust.d.ts +50 -0
- package/dist/esm/segment-trust.d.ts.map +1 -0
- package/dist/esm/segment-trust.js +111 -0
- package/dist/esm/segment-trust.js.map +1 -0
- package/dist/esm/sent-email-log/sent-email-log-code.d.ts +19 -0
- package/dist/esm/sent-email-log/sent-email-log-code.d.ts.map +1 -1
- package/dist/esm/sent-email-log/sent-email-log-code.js +2 -25
- package/dist/esm/sent-email-log/sent-email-log-code.js.map +1 -1
- package/dist/esm/server-runtime-code.d.ts +34 -0
- package/dist/esm/server-runtime-code.d.ts.map +1 -0
- package/dist/esm/server-runtime-code.js +299 -0
- package/dist/esm/server-runtime-code.js.map +1 -0
- package/dist/esm/session-cookie-resolver.d.ts +3 -78
- package/dist/esm/session-cookie-resolver.d.ts.map +1 -1
- package/dist/esm/session-cookie-resolver.js +7 -274
- package/dist/esm/session-cookie-resolver.js.map +1 -1
- package/dist/esm/subscriber-access-route-generator.d.ts +71 -0
- package/dist/esm/subscriber-access-route-generator.d.ts.map +1 -0
- package/dist/esm/subscriber-access-route-generator.js +292 -0
- package/dist/esm/subscriber-access-route-generator.js.map +1 -0
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/types.d.ts +6 -0
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/esm/webhook-delivery-lease/index.d.ts +8 -0
- package/dist/esm/webhook-delivery-lease/index.d.ts.map +1 -0
- package/dist/esm/webhook-delivery-lease/index.js +37 -0
- package/dist/esm/webhook-delivery-lease/index.js.map +1 -0
- package/dist/esm/webhook-delivery-lease/webhook-delivery-lease-code.d.ts +26 -0
- package/dist/esm/webhook-delivery-lease/webhook-delivery-lease-code.d.ts.map +1 -0
- package/dist/esm/webhook-delivery-lease/webhook-delivery-lease-code.js +147 -0
- package/dist/esm/webhook-delivery-lease/webhook-delivery-lease-code.js.map +1 -0
- package/dist/esm/webhook-delivery-lease/webhook-delivery-lease-scope.d.ts +16 -0
- package/dist/esm/webhook-delivery-lease/webhook-delivery-lease-scope.d.ts.map +1 -0
- package/dist/esm/webhook-delivery-lease/webhook-delivery-lease-scope.js +16 -0
- package/dist/esm/webhook-delivery-lease/webhook-delivery-lease-scope.js.map +1 -0
- package/dist/esm/webhook-generator.d.ts +1 -1
- package/dist/esm/webhook-generator.d.ts.map +1 -1
- package/dist/esm/webhook-generator.js +342 -254
- package/dist/esm/webhook-generator.js.map +1 -1
- package/dist/esm/webhook-signature-verification.d.ts +17 -1
- package/dist/esm/webhook-signature-verification.d.ts.map +1 -1
- package/dist/esm/webhook-signature-verification.js +179 -25
- package/dist/esm/webhook-signature-verification.js.map +1 -1
- package/dist/esm/workflow-auth-generator.d.ts +9 -6
- package/dist/esm/workflow-auth-generator.d.ts.map +1 -1
- package/dist/esm/workflow-auth-generator.js +132 -28
- package/dist/esm/workflow-auth-generator.js.map +1 -1
- package/dist/esm/workflow-component-plugin.d.ts.map +1 -1
- package/dist/esm/workflow-component-plugin.js +65 -28
- package/dist/esm/workflow-component-plugin.js.map +1 -1
- package/dist/esm/workflow-project-plugin.d.ts +13 -0
- package/dist/esm/workflow-project-plugin.d.ts.map +1 -1
- package/dist/esm/workflow-project-plugin.js +212 -63
- package/dist/esm/workflow-project-plugin.js.map +1 -1
- package/package.json +4 -4
- package/src/admin-form-hydration.ts +28 -0
- package/src/api-route-generator.ts +251 -64
- package/src/auth-generator.ts +273 -53
- package/src/auth-return/signed-in-destination-code.ts +32 -0
- package/src/cart-pricing-preamble.ts +22 -0
- package/src/cron-request-verification.ts +79 -0
- package/src/custom-node-modules.ts +102 -0
- package/src/data-api-route-generator.ts +370 -28
- package/src/ecommerce/cart-availability.ts +22 -13
- package/src/ecommerce/stock-decrement.ts +13 -1
- package/src/executor-generator.ts +212 -19
- package/src/index.ts +28 -7
- package/src/invoice/api-routes-code.ts +424 -391
- package/src/invoice/data-access-code.ts +431 -110
- package/src/invoice/index.ts +31 -1
- package/src/invoice/invoice-assembly-code.ts +514 -0
- package/src/invoice/invoice-html-code.ts +111 -9
- package/src/invoice/pdf-service-client-code.ts +3 -4
- package/src/nodes/account/account-login.ts +4 -3
- package/src/nodes/account/account-signup.ts +7 -4
- package/src/nodes/ai/ai-select-database-data.ts +10 -1
- package/src/nodes/browser/browser-get-push-subscription.ts +23 -0
- package/src/nodes/browser/browser-show-notification.ts +61 -38
- package/src/nodes/browser/browser-subscribe-to-push.ts +26 -36
- package/src/nodes/browser/browser-unsubscribe-from-push.ts +22 -0
- package/src/nodes/browser/push-api-access.ts +20 -0
- package/src/nodes/cart/cart-add-item.ts +200 -9
- package/src/nodes/cart/cart-clear.ts +11 -0
- package/src/nodes/cart/cart-get-total.ts +279 -7
- package/src/nodes/cart/cart-price-order.ts +351 -0
- package/src/nodes/cart/cart-update-item-quantity.ts +7 -0
- package/src/nodes/data/data-count.ts +9 -1
- package/src/nodes/data/data-create-item.ts +15 -1
- package/src/nodes/data/data-delete-item.ts +32 -0
- package/src/nodes/data/data-raw-query.ts +9 -1
- package/src/nodes/data/data-select.ts +9 -1
- package/src/nodes/data/data-update-item.ts +32 -0
- package/src/nodes/ecommerce/ecommerce-generate-invoice.ts +11 -1
- package/src/nodes/file-storage/file-storage-upload.ts +8 -0
- package/src/nodes/general/general-custom-js.ts +21 -5
- package/src/nodes/index.ts +16 -6
- package/src/nodes/payment/payment-billing-portal.ts +51 -0
- package/src/nodes/payment/payment-charge-user.ts +236 -442
- package/src/nodes/payment/payment-close-checkout.ts +137 -0
- package/src/nodes/payment/payment-ensure-subscription-plan.ts +66 -0
- package/src/nodes/payment/payment-manage-subscription.ts +89 -0
- package/src/nodes/payment/payment-refund.ts +52 -467
- package/src/nodes/payment-drivers-global.d.ts +13 -0
- package/src/nodes/push/push-send-notification.ts +83 -0
- package/src/nodes/workflow-utils-global.d.ts +5 -0
- package/src/payments/drivers/coingate-driver-code.ts +466 -0
- package/src/payments/drivers/mollie-driver-code.ts +618 -0
- package/src/payments/drivers/paddle-driver-code.ts +678 -0
- package/src/payments/drivers/paypal-driver-code.ts +1256 -0
- package/src/payments/drivers/razorpay-driver-code.ts +727 -0
- package/src/payments/drivers/square-driver-code.ts +926 -0
- package/src/payments/drivers/stripe-driver-code.ts +773 -0
- package/src/payments/index.ts +204 -0
- package/src/payments/payment-core-code.ts +421 -0
- package/src/payments/payment-driver-code-map.ts +19 -0
- package/src/payments/payment-drivers-scope.ts +66 -0
- package/src/payments/payment-registry-code.ts +38 -0
- package/src/pg-client-code.ts +30 -0
- package/src/runtime-storage-generator.ts +241 -4
- package/src/secret-collector.ts +8 -3
- package/src/security-scanner.ts +22 -0
- package/src/segment-context-needs.ts +148 -0
- package/src/segment-splitter.ts +6 -1
- package/src/segment-trust.ts +170 -0
- package/src/sent-email-log/sent-email-log-code.ts +2 -32
- package/src/server-runtime-code.ts +298 -0
- package/src/session-cookie-resolver.ts +9 -277
- package/src/subscriber-access-route-generator.ts +351 -0
- package/src/types.ts +6 -0
- package/src/webhook-delivery-lease/index.ts +44 -0
- package/src/webhook-delivery-lease/webhook-delivery-lease-code.ts +151 -0
- package/src/webhook-delivery-lease/webhook-delivery-lease-scope.ts +18 -0
- package/src/webhook-generator.ts +359 -260
- package/src/webhook-signature-verification.ts +180 -25
- package/src/workflow-auth-generator.ts +137 -28
- package/src/workflow-component-plugin.ts +77 -20
- package/src/workflow-project-plugin.ts +247 -44
- package/dist/cjs/nodes/payment/payment-cancel-plan.d.ts +0 -3
- package/dist/cjs/nodes/payment/payment-cancel-plan.d.ts.map +0 -1
- package/dist/cjs/nodes/payment/payment-cancel-plan.js +0 -33
- package/dist/cjs/nodes/payment/payment-cancel-plan.js.map +0 -1
- package/dist/cjs/nodes/payment/payment-create-subscription.d.ts +0 -3
- package/dist/cjs/nodes/payment/payment-create-subscription.d.ts.map +0 -1
- package/dist/cjs/nodes/payment/payment-create-subscription.js +0 -41
- package/dist/cjs/nodes/payment/payment-create-subscription.js.map +0 -1
- package/dist/cjs/nodes/payment/payment-subscribe-to-plan.d.ts +0 -3
- package/dist/cjs/nodes/payment/payment-subscribe-to-plan.d.ts.map +0 -1
- package/dist/cjs/nodes/payment/payment-subscribe-to-plan.js +0 -45
- package/dist/cjs/nodes/payment/payment-subscribe-to-plan.js.map +0 -1
- package/dist/esm/nodes/payment/payment-cancel-plan.d.ts +0 -3
- package/dist/esm/nodes/payment/payment-cancel-plan.d.ts.map +0 -1
- package/dist/esm/nodes/payment/payment-cancel-plan.js +0 -30
- package/dist/esm/nodes/payment/payment-cancel-plan.js.map +0 -1
- package/dist/esm/nodes/payment/payment-create-subscription.d.ts +0 -3
- package/dist/esm/nodes/payment/payment-create-subscription.d.ts.map +0 -1
- package/dist/esm/nodes/payment/payment-create-subscription.js +0 -38
- package/dist/esm/nodes/payment/payment-create-subscription.js.map +0 -1
- package/dist/esm/nodes/payment/payment-subscribe-to-plan.d.ts +0 -3
- package/dist/esm/nodes/payment/payment-subscribe-to-plan.d.ts.map +0 -1
- package/dist/esm/nodes/payment/payment-subscribe-to-plan.js +0 -42
- package/dist/esm/nodes/payment/payment-subscribe-to-plan.js.map +0 -1
- package/src/nodes/payment/payment-cancel-plan.ts +0 -33
- package/src/nodes/payment/payment-create-subscription.ts +0 -42
- package/src/nodes/payment/payment-subscribe-to-plan.ts +0 -46
|
@@ -1,27 +1,82 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateInvoicePdfRouteCode = exports.generateInvoiceGenerateRouteCode = void 0;
|
|
4
|
-
const
|
|
3
|
+
exports.generateInvoicePdfRouteCode = exports.generateInvoiceRegenerateRouteCode = exports.generateInvoiceGenerateRouteCode = void 0;
|
|
4
|
+
const session_cookie_resolver_1 = require("../session-cookie-resolver");
|
|
5
|
+
const workflow_auth_generator_1 = require("../workflow-auth-generator");
|
|
6
|
+
/**
|
|
7
|
+
* The roles that act on invoices from a browser: the ones every generated
|
|
8
|
+
* admin-panel page is protected with, since the admin panel is the only
|
|
9
|
+
* browser that issues, rebuilds or lists every invoice.
|
|
10
|
+
*/
|
|
11
|
+
const INVOICE_ADMIN_ROLES = ['admin'];
|
|
12
|
+
/**
|
|
13
|
+
* Who is calling an invoice route, as ES5 source shared by the routes:
|
|
14
|
+
* `invoiceCaller(req)` resolves to `{ server, signedIn, admin, userId }`.
|
|
15
|
+
*
|
|
16
|
+
* `server` is this deployment's own server code — the invoice node of a
|
|
17
|
+
* payment webhook or a checkout segment, the payment webhooks — which presents
|
|
18
|
+
* the app secret in `x-internal-data-secret`. Only server code can read
|
|
19
|
+
* NEXTAUTH_SECRET, so a browser cannot forge it; it is compared in constant
|
|
20
|
+
* time. Everyone else is who their session says they are.
|
|
21
|
+
*/
|
|
22
|
+
const INVOICE_CALLER_CODE = `${(0, session_cookie_resolver_1.generateCommonJsSessionTokenResolverCode)()}
|
|
23
|
+
${workflow_auth_generator_1.ROLE_OF_TOKEN_CODE}
|
|
24
|
+
|
|
25
|
+
var INVOICE_ADMIN_ROLES = ${JSON.stringify(INVOICE_ADMIN_ROLES)};
|
|
26
|
+
|
|
27
|
+
function presentsAppSecret(req) {
|
|
28
|
+
var given = req && req.headers ? req.headers['x-internal-data-secret'] : '';
|
|
29
|
+
var expected = process.env.NEXTAUTH_SECRET;
|
|
30
|
+
if (typeof given !== 'string' || !given || !expected) return false;
|
|
31
|
+
var a = Buffer.from(given);
|
|
32
|
+
var b = Buffer.from(String(expected));
|
|
33
|
+
return a.length === b.length && require('crypto').timingSafeEqual(a, b);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function invoiceCaller(req) {
|
|
37
|
+
if (presentsAppSecret(req)) {
|
|
38
|
+
return { server: true, signedIn: false, admin: false, userId: null };
|
|
39
|
+
}
|
|
40
|
+
var token = null;
|
|
41
|
+
try {
|
|
42
|
+
token = await __tqSessionToken(req);
|
|
43
|
+
} catch (err) {
|
|
44
|
+
console.warn('[invoice] Could not read the session — ' + (err && err.message));
|
|
45
|
+
token = null;
|
|
46
|
+
}
|
|
47
|
+
if (!token) {
|
|
48
|
+
return { server: false, signedIn: false, admin: false, userId: null };
|
|
49
|
+
}
|
|
50
|
+
var role = roleOf(token);
|
|
51
|
+
var userId = token.id != null ? token.id : token.sub;
|
|
52
|
+
return {
|
|
53
|
+
server: false,
|
|
54
|
+
signedIn: true,
|
|
55
|
+
admin: !!role && INVOICE_ADMIN_ROLES.indexOf(role) !== -1,
|
|
56
|
+
userId: userId != null ? String(userId) : null,
|
|
57
|
+
};
|
|
58
|
+
}`;
|
|
5
59
|
const generateInvoiceGenerateRouteCode = (settings) => {
|
|
6
|
-
var _a
|
|
60
|
+
var _a;
|
|
7
61
|
const prefix = settings.invoicePrefix || 'INV-';
|
|
8
|
-
const defaultTaxRate = settings.defaultTaxRate || 0;
|
|
9
|
-
const showDiscount = settings.showDiscount === true;
|
|
10
|
-
const taxIncludedInPrice = settings.taxIncludedInPrice === true;
|
|
11
62
|
const autoGenerate = settings.autoGenerateOnPayment !== false;
|
|
12
63
|
const emailEnabled = ((_a = settings.emailDelivery) === null || _a === void 0 ? void 0 : _a.enabled) === true;
|
|
13
|
-
const templateDocumentJson = ((_b = settings.template) === null || _b === void 0 ? void 0 : _b.document)
|
|
14
|
-
? JSON.stringify(settings.template.document)
|
|
15
|
-
: 'null';
|
|
16
64
|
return `/**
|
|
17
65
|
* POST /api/invoices/generate
|
|
18
66
|
* Generates an invoice PDF, stores it in the database, optionally uploads it
|
|
19
67
|
* to the runtime storage worker (when configured), and optionally sends it
|
|
20
68
|
* via email.
|
|
69
|
+
*
|
|
70
|
+
* Only the store itself issues invoices: its server code (the invoice node,
|
|
71
|
+
* the payment webhooks — they present the app secret) or a signed-in admin.
|
|
72
|
+
* An open route let anyone print invoices on the merchant's letterhead, burn
|
|
73
|
+
* invoice numbers, claim an order's invoice for good, and read another
|
|
74
|
+
* buyer's personal data back from a hydrated order.
|
|
21
75
|
*/
|
|
22
76
|
|
|
23
77
|
var dataAccess = require('../../../utils/invoices/data-access');
|
|
24
78
|
var pdfGenerator = require('../../../utils/invoices/pdf-generator');
|
|
79
|
+
var invoiceAssembly = require('../../../utils/invoices/invoice-assembly');
|
|
25
80
|
${emailEnabled
|
|
26
81
|
? `var emailSender = require('../../../utils/invoices/email-sender');
|
|
27
82
|
var sentEmailLog = require('../../../utils/email/sent-email-log');
|
|
@@ -29,107 +84,38 @@ var emailLocale = require('../../../utils/email/email-locale');`
|
|
|
29
84
|
: ''}
|
|
30
85
|
|
|
31
86
|
var INVOICE_PREFIX = ${JSON.stringify(prefix)};
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
var
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
${regional_invoice_tax_code_1.REGIONAL_INVOICE_TAX_CODE}
|
|
38
|
-
|
|
39
|
-
// Runtime storage configuration. When all three are set, the generated PDF
|
|
40
|
-
// is also POSTed to the storage worker so consumers (e.g. the payment
|
|
41
|
-
// webhook) can store a persistent URL on the order record. Missing/invalid
|
|
42
|
-
// config silently skips the upload — the in-DB PDF (served via
|
|
43
|
-
// /api/invoices/[id]/pdf) is always available as a fallback.
|
|
44
|
-
// Uploads the rendered invoice PDF through THIS project's own
|
|
45
|
-
// \`/api/runtime-storage/upload\` route — the exact same path that the
|
|
46
|
-
// admin-panel asset uploader uses (client-side \`file-storage-upload\`
|
|
47
|
-
// workflow node → the same proxy). Centralising on that one route means:
|
|
48
|
-
//
|
|
49
|
-
// 1. The storage service URL + api key + project id live in one place
|
|
50
|
-
// (the proxy), so invoice and admin uploads can never drift.
|
|
51
|
-
// 2. When runtime storage is not configured, the proxy returns
|
|
52
|
-
// HTTP 500 with \`{ error: 'Runtime storage is not configured' }\`.
|
|
53
|
-
// We surface that as the upload failure reason so the
|
|
54
|
-
// \`invoice_pdf_url\` column stays empty instead of silently
|
|
55
|
-
// holding a stale/fake URL.
|
|
56
|
-
//
|
|
57
|
-
// \`baseUrl\` is the live request origin (http://host:port) stamped at
|
|
58
|
-
// the top of \`handler\` from \`req.headers.host\`. The self-fetch pattern
|
|
59
|
-
// is necessary because this endpoint runs server-side, where Node's
|
|
60
|
-
// undici fetch rejects relative URLs.
|
|
61
|
-
async function uploadInvoicePdfToRuntimeStorage(pdfBuffer, fileName, baseUrl) {
|
|
62
|
-
if (!baseUrl) {
|
|
63
|
-
console.error('[invoice] Runtime storage: cannot compute proxy URL (baseUrl missing). Skipping upload.');
|
|
64
|
-
return { storageUrl: '', error: 'baseUrl missing' };
|
|
65
|
-
}
|
|
66
|
-
if (typeof Blob === 'undefined' || typeof FormData === 'undefined' || typeof fetch === 'undefined') {
|
|
67
|
-
console.error('[invoice] Runtime storage: Node runtime missing Blob/FormData/fetch (requires Node >= 18). Skipping upload.');
|
|
68
|
-
return { storageUrl: '', error: 'node runtime too old' };
|
|
69
|
-
}
|
|
70
|
-
try {
|
|
71
|
-
var proxyUrl = String(baseUrl).replace(/\\/+$/, '') + '/api/runtime-storage/upload';
|
|
72
|
-
console.info('[invoice] Runtime storage: POST ' + proxyUrl + ' (' + pdfBuffer.length + ' bytes, fileName=' + fileName + ', folder=invoices)');
|
|
73
|
-
var blob = new Blob([pdfBuffer], { type: 'application/pdf' });
|
|
74
|
-
var form = new FormData();
|
|
75
|
-
form.append('file', blob, fileName);
|
|
76
|
-
form.append('folder', 'invoices');
|
|
77
|
-
var res = await fetch(proxyUrl, { method: 'POST', body: form });
|
|
78
|
-
var data = {};
|
|
79
|
-
try { data = await res.json(); } catch (_parseErr) { data = {}; }
|
|
80
|
-
if (!res.ok) {
|
|
81
|
-
var reason = (data && (data.error || data.message)) || ('HTTP ' + res.status);
|
|
82
|
-
console.error('[invoice] Runtime storage: upload FAILED via proxy — ' + reason +
|
|
83
|
-
' (this is expected in dev when RUNTIME_STORAGE_URL / RUNTIME_STORAGE_API_KEY / RUNTIME_STORAGE_PROJECT_ID are unset in .env)');
|
|
84
|
-
return { storageUrl: '', error: reason };
|
|
85
|
-
}
|
|
86
|
-
var files = Array.isArray(data.files) ? data.files : [];
|
|
87
|
-
var first = files.length > 0 ? files[0] : null;
|
|
88
|
-
var resolvedUrl = first && first.url ? String(first.url) : (data.url ? String(data.url) : '');
|
|
89
|
-
var resolvedId = first && first.id ? String(first.id) : (data.id ? String(data.id) : '');
|
|
90
|
-
if (resolvedUrl) {
|
|
91
|
-
console.info('[invoice] Runtime storage: upload OK — fileId=' + (resolvedId || '(missing)') + ', storageUrl=' + resolvedUrl);
|
|
92
|
-
} else {
|
|
93
|
-
console.error('[invoice] Runtime storage: proxy returned 2xx but no url in payload — ' + JSON.stringify(data).slice(0, 500));
|
|
94
|
-
}
|
|
95
|
-
return { storageUrl: resolvedUrl, fileId: resolvedId };
|
|
96
|
-
} catch (err) {
|
|
97
|
-
console.error('[invoice] Runtime storage: upload threw — ' + (err && err.message));
|
|
98
|
-
return { storageUrl: '', error: (err && err.message) || 'upload threw' };
|
|
99
|
-
}
|
|
100
|
-
}
|
|
87
|
+
// How long a reserved invoice may wait for its PDF before another request for
|
|
88
|
+
// the same order finishes it: longer than any one request lives.
|
|
89
|
+
var UNFINISHED_INVOICE_STALE_SECONDS = 900;
|
|
90
|
+
|
|
91
|
+
${INVOICE_CALLER_CODE}
|
|
101
92
|
|
|
102
93
|
// ---------------------------------------------------------------------------
|
|
103
94
|
// Waiting for the order's line items to be fully written.
|
|
104
95
|
//
|
|
105
|
-
//
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
//
|
|
109
|
-
// the
|
|
110
|
-
//
|
|
111
|
-
// real 3-line order was invoiced with a single line and a total 225.45
|
|
112
|
-
// short of what the buyer was charged, because the other two rows were
|
|
113
|
-
// still in flight when the hydration query ran.
|
|
96
|
+
// The checkout workflow writes the \`teleport_orders\` row first and then
|
|
97
|
+
// inserts \`teleport_order_items\` one HTTP round-trip at a time, so a caller
|
|
98
|
+
// that reaches this endpoint early can hydrate a HALF-WRITTEN order: a real
|
|
99
|
+
// 3-line order was once invoiced with a single line and a total 225.45 short
|
|
100
|
+
// of what the buyer was charged, because the other two rows were still in
|
|
101
|
+
// flight when the hydration query ran.
|
|
114
102
|
//
|
|
115
|
-
// So don't race it — wait for the order to settle, then hydrate.
|
|
103
|
+
// So don't race it — wait for the order to settle, then hydrate. Two exit
|
|
116
104
|
// conditions, cheapest first:
|
|
117
105
|
//
|
|
118
|
-
// 1. \`
|
|
119
|
-
//
|
|
120
|
-
//
|
|
121
|
-
//
|
|
122
|
-
//
|
|
123
|
-
//
|
|
124
|
-
// so a non-empty order number proves every line has been written.
|
|
125
|
-
// 3. The row count is identical across \`SETTLE_STABLE_READS\` consecutive
|
|
106
|
+
// 1. \`teleport_orders.order_number\` is populated. Checkout backfills the
|
|
107
|
+
// order number only AFTER the item loop has run to completion (the
|
|
108
|
+
// settled branch does it in "Mark Order As Settled", the online-payment
|
|
109
|
+
// branch in "Set Order Number Before Payment Redirect"), so a non-empty
|
|
110
|
+
// order number proves every line has been written.
|
|
111
|
+
// 2. The row count is identical across \`SETTLE_STABLE_READS\` consecutive
|
|
126
112
|
// reads — the fallback for orders written by a flow that never sets an
|
|
127
113
|
// order number.
|
|
128
114
|
//
|
|
129
|
-
// An order that is already complete — every webhook-driven call,
|
|
130
|
-
// hand-built admin call —
|
|
131
|
-
// only request that ever pays for a
|
|
132
|
-
// have shipped a wrong invoice.
|
|
115
|
+
// An order that is already complete — every webhook-driven call, the
|
|
116
|
+
// checkout's own settled-branch call, and any hand-built admin call —
|
|
117
|
+
// satisfies (1) on the FIRST read, so the only request that ever pays for a
|
|
118
|
+
// poll is the one that would otherwise have shipped a wrong invoice.
|
|
133
119
|
var SETTLE_TIMEOUT_MS = 6000;
|
|
134
120
|
var SETTLE_POLL_MS = 400;
|
|
135
121
|
var SETTLE_STABLE_READS = 3;
|
|
@@ -138,7 +124,7 @@ function sleepMs(ms) {
|
|
|
138
124
|
return new Promise(function (resolve) { setTimeout(resolve, ms); });
|
|
139
125
|
}
|
|
140
126
|
|
|
141
|
-
async function hydrateOrderWhenSettled(orderId
|
|
127
|
+
async function hydrateOrderWhenSettled(orderId) {
|
|
142
128
|
var deadline = Date.now() + SETTLE_TIMEOUT_MS;
|
|
143
129
|
var lastCount = -1;
|
|
144
130
|
var repeats = 0;
|
|
@@ -156,13 +142,6 @@ async function hydrateOrderWhenSettled(orderId, expectedItemCount) {
|
|
|
156
142
|
var rows = Array.isArray(hydrated.items) ? hydrated.items : [];
|
|
157
143
|
var count = rows.length;
|
|
158
144
|
|
|
159
|
-
if (expectedItemCount > 0 && count >= expectedItemCount) {
|
|
160
|
-
if (attempts > 1) {
|
|
161
|
-
console.info('[invoice] Order ' + orderId + ' settled at ' + count + ' line(s) after ' + attempts + ' read(s) (expected ' + expectedItemCount + ')');
|
|
162
|
-
}
|
|
163
|
-
return hydrated;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
145
|
var orderNumber = hydrated.order.order_number;
|
|
167
146
|
if (count > 0 && orderNumber != null && String(orderNumber).length > 0) {
|
|
168
147
|
if (attempts > 1) {
|
|
@@ -184,8 +163,7 @@ async function hydrateOrderWhenSettled(orderId, expectedItemCount) {
|
|
|
184
163
|
|
|
185
164
|
if (Date.now() >= deadline) {
|
|
186
165
|
console.warn('[invoice] Order ' + orderId + ' did not settle within ' + SETTLE_TIMEOUT_MS +
|
|
187
|
-
'ms — invoicing the ' + count + ' line(s) visible now'
|
|
188
|
-
(expectedItemCount > 0 ? ' (expected ' + expectedItemCount + ')' : ''));
|
|
166
|
+
'ms — invoicing the ' + count + ' line(s) visible now');
|
|
189
167
|
return hydrated;
|
|
190
168
|
}
|
|
191
169
|
|
|
@@ -193,33 +171,24 @@ async function hydrateOrderWhenSettled(orderId, expectedItemCount) {
|
|
|
193
171
|
}
|
|
194
172
|
}
|
|
195
173
|
|
|
196
|
-
var CURRENCY_SYMBOLS = {
|
|
197
|
-
'USD': '$', 'EUR': '\\u20AC', 'GBP': '\\u00A3', 'JPY': '\\u00A5',
|
|
198
|
-
'CAD': 'C$', 'AUD': 'A$', 'CHF': 'CHF ', 'CNY': '\\u00A5',
|
|
199
|
-
'INR': '\\u20B9', 'BRL': 'R$', 'KRW': '\\u20A9', 'MXN': 'MX$',
|
|
200
|
-
'SEK': 'kr', 'NOK': 'kr', 'DKK': 'kr', 'PLN': 'z\\u0142',
|
|
201
|
-
'CZK': 'K\\u010D', 'HUF': 'Ft', 'RON': 'lei', 'BGN': 'лв',
|
|
202
|
-
'HRK': 'kn', 'TRY': '\\u20BA', 'ZAR': 'R', 'SGD': 'S$',
|
|
203
|
-
'HKD': 'HK$', 'NZD': 'NZ$', 'THB': '\\u0E3F', 'MYR': 'RM',
|
|
204
|
-
'PHP': '\\u20B1', 'IDR': 'Rp', 'TWD': 'NT$', 'AED': 'AED',
|
|
205
|
-
'SAR': 'SAR', 'ILS': '\\u20AA', 'EGP': 'E\\u00A3', 'NGN': '\\u20A6',
|
|
206
|
-
'KES': 'KSh', 'GHS': 'GH\\u20B5', 'COP': 'COL$', 'ARS': 'AR$',
|
|
207
|
-
'CLP': 'CLP$', 'PEN': 'S/.', 'VND': '\\u20AB', 'UAH': '\\u20B4',
|
|
208
|
-
};
|
|
209
|
-
|
|
210
174
|
module.exports = async function handler(req, res) {
|
|
211
175
|
if (req.method !== 'POST') {
|
|
212
176
|
res.status(405).json({ error: 'Method not allowed' });
|
|
213
177
|
return;
|
|
214
178
|
}
|
|
215
179
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
180
|
+
var caller = await invoiceCaller(req);
|
|
181
|
+
if (!caller.server && !caller.admin) {
|
|
182
|
+
res.status(caller.signedIn ? 403 : 401).json({
|
|
183
|
+
success: false,
|
|
184
|
+
error: caller.signedIn ? 'Only the store can issue invoices.' : 'Unauthenticated',
|
|
185
|
+
});
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// The live request origin, so the runtime-storage upload can self-fetch the
|
|
190
|
+
// same \`/api/runtime-storage/upload\` route the admin-panel uploader hits.
|
|
191
|
+
var __baseUrl = invoiceAssembly.requestBaseUrl(req);
|
|
223
192
|
|
|
224
193
|
try {
|
|
225
194
|
var body = typeof req.body === 'string' ? JSON.parse(req.body) : (req.body || {});
|
|
@@ -231,21 +200,11 @@ module.exports = async function handler(req, res) {
|
|
|
231
200
|
|
|
232
201
|
var callerSuppliedItems = Array.isArray(body.items) && body.items.length > 0;
|
|
233
202
|
|
|
234
|
-
// How many line items the caller believes this order has. Used only to
|
|
235
|
-
// stop \`hydrateOrderWhenSettled\` polling the moment the order is whole —
|
|
236
|
-
// never to reject or pad the invoice, so a wrong count can at worst make
|
|
237
|
-
// us wait a little longer and fall through to the other exit conditions.
|
|
238
|
-
var expectedItemCount = Number(body.expectedItemCount);
|
|
239
|
-
if (!isFinite(expectedItemCount) || expectedItemCount < 0) {
|
|
240
|
-
expectedItemCount = 0;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
203
|
console.info('[invoice] === /api/invoices/generate === baseUrl=' + __baseUrl);
|
|
244
204
|
console.info('[invoice] Request received:', {
|
|
245
205
|
orderId: body.orderId || null,
|
|
246
206
|
hasBodyItems: callerSuppliedItems,
|
|
247
207
|
bodyItemCount: Array.isArray(body.items) ? body.items.length : 0,
|
|
248
|
-
expectedItemCount: expectedItemCount,
|
|
249
208
|
hasCustomerEmail: !!body.customerEmail,
|
|
250
209
|
requestedCurrency: body.currency || null,
|
|
251
210
|
});
|
|
@@ -272,7 +231,7 @@ module.exports = async function handler(req, res) {
|
|
|
272
231
|
try {
|
|
273
232
|
var hydrated = callerSuppliedItems
|
|
274
233
|
? await dataAccess.getOrderWithItems(body.orderId)
|
|
275
|
-
: await hydrateOrderWhenSettled(body.orderId
|
|
234
|
+
: await hydrateOrderWhenSettled(body.orderId);
|
|
276
235
|
if (hydrated && hydrated.order) {
|
|
277
236
|
hydratedOrder = hydrated.order;
|
|
278
237
|
hydratedItems = Array.isArray(hydrated.items) ? hydrated.items : [];
|
|
@@ -287,274 +246,73 @@ module.exports = async function handler(req, res) {
|
|
|
287
246
|
console.info('[invoice] No orderId in request — skipping DB hydration, using body.* fields verbatim');
|
|
288
247
|
}
|
|
289
248
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
productId: row.product_id || row.productId || null,
|
|
295
|
-
// Paired with \`productId\` to find the rate a line was charged at
|
|
296
|
-
// on an order priced by region (see resolveRegionalInvoiceTax).
|
|
297
|
-
variantId: row.variant_id || row.variantId || null,
|
|
298
|
-
name: row.product_name || row.name || 'Item',
|
|
299
|
-
variantLabel: row.variant_label || row.variantLabel || null,
|
|
300
|
-
variantSwatches: row.variant_swatches || row.variantSwatches || null,
|
|
301
|
-
quantity: Number(row.quantity) || 1,
|
|
302
|
-
unitPrice: Number(row.unit_price || row.unitPrice || row.price) || 0,
|
|
303
|
-
totalPrice: Number(row.total_price || row.totalPrice) || 0,
|
|
304
|
-
currency: row.currency || null,
|
|
305
|
-
};
|
|
306
|
-
});
|
|
307
|
-
if (items.length === 0) {
|
|
249
|
+
// Lines, prices, discounts, tax, delivery and the gift-card tender — the
|
|
250
|
+
// same assembly the admin panel's regenerate route rebuilds an invoice with.
|
|
251
|
+
var invoiceData = invoiceAssembly.assembleInvoiceData(body, hydratedOrder, hydratedItems);
|
|
252
|
+
if (!invoiceData) {
|
|
308
253
|
res.status(400).json({ error: 'At least one item is required' });
|
|
309
254
|
return;
|
|
310
255
|
}
|
|
311
|
-
|
|
312
|
-
var currency =
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
var
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
//
|
|
335
|
-
// A discount STORED ON THE ORDER is money the buyer was not charged, so it
|
|
336
|
-
// is subtracted whatever \`SHOW_DISCOUNT\` says — that flag governs whether
|
|
337
|
-
// the template renders a discount ROW, and honouring it here would print a
|
|
338
|
-
// total larger than the card was debited. \`SHOW_DISCOUNT\` still gates a
|
|
339
|
-
// BODY-supplied amount, which is the manual/ad-hoc path a merchant opts
|
|
340
|
-
// into.
|
|
341
|
-
//
|
|
342
|
-
// The payment webhook calls this route with just an \`orderId\`, so the
|
|
343
|
-
// order row — not the body — is the usual source.
|
|
344
|
-
var discountAmount = 0;
|
|
345
|
-
if (SHOW_DISCOUNT && body.discountAmount != null && body.discountAmount !== '') {
|
|
346
|
-
discountAmount = Number(body.discountAmount) || 0;
|
|
347
|
-
} else if (orderShippingSource.discount_amount != null) {
|
|
348
|
-
discountAmount = Number(orderShippingSource.discount_amount) || 0;
|
|
349
|
-
}
|
|
350
|
-
if (!(discountAmount > 0)) { discountAmount = 0; }
|
|
351
|
-
|
|
352
|
-
var taxRate = body.taxRate != null ? Number(body.taxRate) : DEFAULT_TAX_RATE;
|
|
353
|
-
var subtotal;
|
|
354
|
-
var taxAmount = 0;
|
|
355
|
-
var taxableAmount;
|
|
356
|
-
if (taxRate > 0 && TAX_INCLUDED_IN_PRICE) {
|
|
357
|
-
// Prices already include VAT — extract net subtotal and tax out of the gross sum.
|
|
358
|
-
taxableAmount = grossLineSum - discountAmount;
|
|
359
|
-
var netAmount = taxableAmount / (1 + taxRate / 100);
|
|
360
|
-
taxAmount = taxableAmount - netAmount;
|
|
361
|
-
subtotal = netAmount;
|
|
362
|
-
} else {
|
|
363
|
-
subtotal = grossLineSum;
|
|
364
|
-
taxableAmount = subtotal - discountAmount;
|
|
365
|
-
if (taxRate > 0) {
|
|
366
|
-
taxAmount = taxableAmount * (taxRate / 100);
|
|
256
|
+
var items = invoiceData.items;
|
|
257
|
+
var currency = invoiceData.currency;
|
|
258
|
+
|
|
259
|
+
// The number and the row are taken before the PDF is rendered, under one
|
|
260
|
+
// lock (see reserveInvoice): an order gets one invoice however many times
|
|
261
|
+
// its payment is reported, and no two invoices share a number.
|
|
262
|
+
var reservation = await dataAccess.reserveInvoice(invoiceData, items, INVOICE_PREFIX);
|
|
263
|
+
var held = reservation.invoice;
|
|
264
|
+
if (!reservation.created) {
|
|
265
|
+
if (Number(held.pdf_size_bytes) > 0) {
|
|
266
|
+
console.info('[invoice] Order ' + body.orderId + ' already has invoice ' + held.invoice_number + ' — returning it');
|
|
267
|
+
var heldPdfUrl = held.pdf_url || ('/api/invoices/' + held.id + '/pdf');
|
|
268
|
+
res.status(200).json({
|
|
269
|
+
success: true,
|
|
270
|
+
alreadyIssued: true,
|
|
271
|
+
invoiceId: held.id,
|
|
272
|
+
invoiceNumber: held.invoice_number,
|
|
273
|
+
storageUrl: heldPdfUrl.indexOf('/api/invoices/') === 0 ? '' : heldPdfUrl,
|
|
274
|
+
pdfUrl: heldPdfUrl,
|
|
275
|
+
total: Number(held.total) || 0,
|
|
276
|
+
currency: held.currency || currency,
|
|
277
|
+
});
|
|
278
|
+
return;
|
|
367
279
|
}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
// the merchant's CURRENT delivery settings — the order is a historical
|
|
376
|
-
// record and its settings may have changed since.
|
|
377
|
-
//
|
|
378
|
-
// It is added to the total but NOT into \`subtotal\` / \`taxAmount\`: those two
|
|
379
|
-
// describe the GOODS, which is what \`teleport_invoice_items\` holds and what
|
|
380
|
-
// the VAT breakdown is computed from. The storefront charges the configured
|
|
381
|
-
// delivery price verbatim (\`computeShippingMeta\` never taxes it), so the
|
|
382
|
-
// invoice must not tax it either — otherwise the invoice total stops
|
|
383
|
-
// matching \`teleport_orders.total_amount\`, i.e. the amount actually taken.
|
|
384
|
-
// 0 for pickup orders, free-delivery orders, and orders placed before the
|
|
385
|
-
// column existed.
|
|
386
|
-
var shippingAmount = Number(
|
|
387
|
-
body.shippingAmount != null ? body.shippingAmount : (orderShippingSource.shipping_amount || 0)
|
|
388
|
-
);
|
|
389
|
-
if (!isFinite(shippingAmount) || shippingAmount < 0) {
|
|
390
|
-
shippingAmount = 0;
|
|
391
|
-
}
|
|
392
|
-
var total = goodsTotal + shippingAmount;
|
|
393
|
-
|
|
394
|
-
// An order priced by region records the rate each line was charged at, so
|
|
395
|
-
// its invoice is computed from that record instead of the store default.
|
|
396
|
-
// A caller that states its own \`taxRate\` keeps the single-rate path.
|
|
397
|
-
var taxIncludedInPrice = TAX_INCLUDED_IN_PRICE;
|
|
398
|
-
var regionalTaxBreakdown = body.taxRate == null
|
|
399
|
-
? parseOrderTaxBreakdown(orderShippingSource.tax_breakdown)
|
|
400
|
-
: null;
|
|
401
|
-
if (regionalTaxBreakdown) {
|
|
402
|
-
var regionalTax = resolveRegionalInvoiceTax(regionalTaxBreakdown, items, discountAmount, shippingAmount);
|
|
403
|
-
taxRate = regionalTax.taxRate;
|
|
404
|
-
taxIncludedInPrice = regionalTax.taxIncluded;
|
|
405
|
-
subtotal = regionalTax.subtotal;
|
|
406
|
-
taxAmount = regionalTax.taxAmount;
|
|
407
|
-
shippingAmount = regionalTax.shippingNet;
|
|
408
|
-
total = regionalTax.total;
|
|
409
|
-
for (var ti = 0; ti < items.length; ti++) {
|
|
410
|
-
items[ti].taxRate = regionalTax.itemTax[ti].rate;
|
|
411
|
-
items[ti].taxIncluded = regionalTax.itemTax[ti].included;
|
|
412
|
-
items[ti].taxAmount = regionalTax.itemTax[ti].amount;
|
|
280
|
+
// Reserved, never finished: another request is rendering it now, or the
|
|
281
|
+
// one that reserved it died — then the first request to find it stale
|
|
282
|
+
// finishes it under the same number.
|
|
283
|
+
if (!(await dataAccess.claimStaleInvoice(held.id, UNFINISHED_INVOICE_STALE_SECONDS))) {
|
|
284
|
+
console.info('[invoice] Order ' + body.orderId + ' invoice ' + held.invoice_number + ' is being issued by another request');
|
|
285
|
+
res.status(409).json({ success: false, inProgress: true, error: "This order's invoice is being issued by another request." });
|
|
286
|
+
return;
|
|
413
287
|
}
|
|
288
|
+
console.warn('[invoice] Finishing invoice ' + held.invoice_number + ' for order ' + body.orderId + ' — the request that reserved it never did');
|
|
289
|
+
invoiceData.id = held.id;
|
|
290
|
+
invoiceData.invoiceNumber = held.invoice_number;
|
|
414
291
|
}
|
|
415
|
-
|
|
416
|
-
// Cross-check against the amount the order was actually placed for. The
|
|
417
|
-
// invoice is built from line items, the order carries the charged total,
|
|
418
|
-
// and the two must agree — when they don't, the invoice is being written
|
|
419
|
-
// from an incomplete set of lines (exactly what a lost race against
|
|
420
|
-
// checkout's item loop looks like). Log-only: a mismatch must never stop
|
|
421
|
-
// the merchant getting an invoice, but it has to be visible in the
|
|
422
|
-
// function logs instead of silently shipping a short bill.
|
|
423
|
-
var orderTotalAmount = Number(orderShippingSource.total_amount);
|
|
424
|
-
if (isFinite(orderTotalAmount) && orderTotalAmount > 0 && Math.abs(orderTotalAmount - total) > 0.02) {
|
|
425
|
-
console.warn('[invoice] Total mismatch for order ' + (body.orderId || '(none)') +
|
|
426
|
-
' — invoice total ' + (Math.round(total * 100) / 100) +
|
|
427
|
-
' vs teleport_orders.total_amount ' + orderTotalAmount +
|
|
428
|
-
' across ' + items.length + ' line item(s). The invoice may be missing lines.');
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
var nextNumber = await dataAccess.getNextInvoiceNumber(INVOICE_PREFIX);
|
|
432
|
-
var invoiceNumber = INVOICE_PREFIX + String(nextNumber).padStart(4, '0');
|
|
433
|
-
|
|
434
|
-
var issueDate = body.issueDate || new Date().toISOString().split('T')[0];
|
|
435
|
-
var parsedIssueDate = new Date(issueDate);
|
|
436
|
-
if (isNaN(parsedIssueDate.getTime())) {
|
|
437
|
-
issueDate = new Date().toISOString().split('T')[0];
|
|
438
|
-
parsedIssueDate = new Date(issueDate);
|
|
439
|
-
}
|
|
440
|
-
// \`dueDate\` defaults to issueDate + 30 days (industry-standard
|
|
441
|
-
// Net 30 terms) when the caller doesn't pass one. Without this
|
|
442
|
-
// default, every invoice generated from the order-notification /
|
|
443
|
-
// payment-webhook paths shipped with an empty \`{{dueDate}}\` slot
|
|
444
|
-
// in the buyer email + PDF — the merchant template literally
|
|
445
|
-
// rendered "Due Date: " with no date — because none of those
|
|
446
|
-
// callers know what payment terms the merchant uses.
|
|
447
|
-
//
|
|
448
|
-
// We compute it from \`parsedIssueDate\` (already validated above)
|
|
449
|
-
// so a bad caller-provided \`issueDate\` doesn't propagate into a
|
|
450
|
-
// bad \`dueDate\`. ISO yyyy-mm-dd is the same format the issueDate
|
|
451
|
-
// path produces, so downstream date formatters get a single shape.
|
|
452
|
-
var DEFAULT_DUE_DATE_OFFSET_DAYS = 30;
|
|
453
|
-
var dueDate = body.dueDate || '';
|
|
454
|
-
if (dueDate) {
|
|
455
|
-
var parsedDue = new Date(dueDate);
|
|
456
|
-
if (isNaN(parsedDue.getTime())) dueDate = '';
|
|
457
|
-
}
|
|
458
|
-
if (!dueDate) {
|
|
459
|
-
var __defaultDue = new Date(parsedIssueDate.getTime());
|
|
460
|
-
__defaultDue.setUTCDate(__defaultDue.getUTCDate() + DEFAULT_DUE_DATE_OFFSET_DAYS);
|
|
461
|
-
dueDate = __defaultDue.toISOString().split('T')[0];
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
// Order-derived fallbacks. When the caller didn't pass a customer
|
|
465
|
-
// field but the order has one, use it. Kept permissive on field
|
|
466
|
-
// names (billing_* wins, falls back to shipping_*) because a buyer
|
|
467
|
-
// who checked "bill to a different address" has both on the order.
|
|
468
|
-
var orderRow = orderShippingSource;
|
|
469
|
-
var fallbackCustomerName =
|
|
470
|
-
orderRow.billing_name || orderRow.shipping_name || orderRow.customer_name || '';
|
|
471
|
-
var fallbackCustomerEmail = orderRow.billing_email || orderRow.customer_email || '';
|
|
472
|
-
var fallbackCustomerAddress = orderRow.billing_address || orderRow.shipping_address || '';
|
|
473
|
-
var fallbackCustomerCity = orderRow.shipping_city || '';
|
|
474
|
-
var fallbackCustomerState = orderRow.shipping_state || '';
|
|
475
|
-
var fallbackCustomerZip = orderRow.shipping_zip || '';
|
|
476
|
-
var fallbackCustomerCountry = orderRow.shipping_country || '';
|
|
477
|
-
var fallbackPaymentMethod = orderRow.payment_method || '';
|
|
478
|
-
var fallbackPaymentProvider = orderRow.payment_provider || '';
|
|
479
|
-
var fallbackPaymentIntentId = orderRow.payment_intent_id || '';
|
|
480
|
-
var fallbackNotes = orderRow.notes || '';
|
|
292
|
+
var invoiceNumber = invoiceData.invoiceNumber;
|
|
481
293
|
${emailEnabled
|
|
482
294
|
? `
|
|
483
295
|
// The language the invoice email goes out in: the one stamped on the
|
|
484
296
|
// order at checkout (the buyer's storefront), else the one the caller
|
|
485
297
|
// named, else the language of the request itself. A cron or a webhook
|
|
486
298
|
// has neither of the last two and lands on the store's main language.
|
|
299
|
+
var orderRow = hydratedOrder || {};
|
|
487
300
|
var invoiceLocale = emailLocale.normalizeEmailLocale(orderRow.locale)
|
|
488
301
|
|| emailLocale.normalizeEmailLocale(body.locale)
|
|
489
302
|
|| emailLocale.resolveRequestLocale(req);
|
|
303
|
+
invoiceData.locale = invoiceLocale;
|
|
490
304
|
`
|
|
491
305
|
: ''}
|
|
492
|
-
var invoiceData = {
|
|
493
|
-
id: body.id || require('crypto').randomUUID(),
|
|
494
|
-
invoiceNumber: invoiceNumber,
|
|
495
|
-
status: body.status || 'issued',
|
|
496
|
-
issueDate: issueDate,
|
|
497
|
-
dueDate: dueDate,
|
|
498
|
-
paidAt: body.paidAt || null,
|
|
499
|
-
customerName: body.customerName || fallbackCustomerName || '',
|
|
500
|
-
customerEmail: body.customerEmail || fallbackCustomerEmail || '',${emailEnabled ? '\n locale: invoiceLocale,' : ''}
|
|
501
|
-
customerAddress: body.customerAddress || fallbackCustomerAddress || '',
|
|
502
|
-
customerCity: body.customerCity || fallbackCustomerCity || '',
|
|
503
|
-
customerState: body.customerState || fallbackCustomerState || '',
|
|
504
|
-
customerZip: body.customerZip || fallbackCustomerZip || '',
|
|
505
|
-
customerCountry: body.customerCountry || fallbackCustomerCountry || '',
|
|
506
|
-
customerVat: body.customerVat || '',
|
|
507
|
-
companyName: pdfGenerator.COMPANY_DETAILS.companyName || '',
|
|
508
|
-
companyAddress: pdfGenerator.COMPANY_DETAILS.companyAddress || '',
|
|
509
|
-
companyCity: pdfGenerator.COMPANY_DETAILS.companyCity || '',
|
|
510
|
-
companyState: pdfGenerator.COMPANY_DETAILS.companyState || '',
|
|
511
|
-
companyZip: pdfGenerator.COMPANY_DETAILS.companyZip || '',
|
|
512
|
-
companyCountry: pdfGenerator.COMPANY_DETAILS.companyCountry || '',
|
|
513
|
-
companyVat: pdfGenerator.COMPANY_DETAILS.companyVat || '',
|
|
514
|
-
companyRegNumber: pdfGenerator.COMPANY_DETAILS.companyRegNumber || '',
|
|
515
|
-
companyEmail: pdfGenerator.COMPANY_DETAILS.companyEmail || '',
|
|
516
|
-
companyPhone: pdfGenerator.COMPANY_DETAILS.companyPhone || '',
|
|
517
|
-
companyLogoUrl: body.companyLogoUrl || '',
|
|
518
|
-
companyWebsite: pdfGenerator.COMPANY_DETAILS.companyWebsite || '',
|
|
519
|
-
subtotal: Math.round(subtotal * 100) / 100,
|
|
520
|
-
taxRate: taxRate,
|
|
521
|
-
taxAmount: Math.round(taxAmount * 100) / 100,
|
|
522
|
-
// Surfacing the inclusion mode so the PDF builder can apply the SAME
|
|
523
|
-
// formulas the GUI uses (invoice-vat-formulas.ts) when it derives
|
|
524
|
-
// per-line unitPriceNet / lineVatAmount / lineTotalGross. Without
|
|
525
|
-
// this flag the builder can't tell whether the stored unitPrice is
|
|
526
|
-
// a net (added on top) or a gross (included in price) value, and
|
|
527
|
-
// the line-item table renders blank cells.
|
|
528
|
-
taxIncludedInPrice: taxIncludedInPrice,
|
|
529
|
-
discountAmount: Math.round(discountAmount * 100) / 100,
|
|
530
|
-
// Delivery fee, surfaced so the PDF/HTML renderer can print its own line
|
|
531
|
-
// and the merchant's template can bind \`invoice.shippingAmount\`.
|
|
532
|
-
shippingAmount: Math.round(shippingAmount * 100) / 100,
|
|
533
|
-
total: Math.round(total * 100) / 100,
|
|
534
|
-
currency: currency,
|
|
535
|
-
currencySymbol: currencySymbol,
|
|
536
|
-
paymentMethod: body.paymentMethod || fallbackPaymentMethod || '',
|
|
537
|
-
paymentProvider: body.paymentProvider || fallbackPaymentProvider || '',
|
|
538
|
-
paymentIntentId: body.paymentIntentId || fallbackPaymentIntentId || '',
|
|
539
|
-
orderId: body.orderId || '',
|
|
540
|
-
notes: body.notes || fallbackNotes || '',
|
|
541
|
-
items: items,
|
|
542
|
-
templateSnapshot: TEMPLATE_DOCUMENT ? JSON.stringify(TEMPLATE_DOCUMENT) : null,
|
|
543
|
-
};
|
|
544
306
|
|
|
545
307
|
var pdfBuffer = await pdfGenerator.generateInvoicePdf(invoiceData);
|
|
546
308
|
console.info('[invoice] PDF generated: ' + pdfBuffer.length + ' bytes for ' + invoiceData.invoiceNumber);
|
|
547
309
|
|
|
548
|
-
invoiceData.pdfData = pdfBuffer;
|
|
549
|
-
invoiceData.pdfSizeBytes = pdfBuffer.length;
|
|
550
310
|
invoiceData.pdfUrl = '/api/invoices/' + invoiceData.id + '/pdf';
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
await dataAccess.insertInvoiceItems(invoiceData.id, items);
|
|
554
|
-
console.info('[invoice] DB insert OK — teleport_invoices.id=' + invoiceData.id + ', number=' + invoiceData.invoiceNumber + ', pdf_size_bytes=' + pdfBuffer.length + ', items=' + items.length + ' (accessible at ' + invoiceData.pdfUrl + ')');
|
|
311
|
+
await dataAccess.storeInvoicePdf(invoiceData.id, pdfBuffer, invoiceData.pdfUrl);
|
|
312
|
+
console.info('[invoice] PDF stored — teleport_invoices.id=' + invoiceData.id + ', number=' + invoiceData.invoiceNumber + ', pdf_size_bytes=' + pdfBuffer.length + ', items=' + items.length + ' (accessible at ' + invoiceData.pdfUrl + ')');
|
|
555
313
|
|
|
556
314
|
var safeFileName = String(invoiceNumber || invoiceData.id).replace(/[^a-zA-Z0-9._-]/g, '_') + '.pdf';
|
|
557
|
-
var uploadResult = await uploadInvoicePdfToRuntimeStorage(pdfBuffer, safeFileName, __baseUrl);
|
|
315
|
+
var uploadResult = await invoiceAssembly.uploadInvoicePdfToRuntimeStorage(pdfBuffer, safeFileName, __baseUrl);
|
|
558
316
|
var storageUrl = (uploadResult && uploadResult.storageUrl) || '';
|
|
559
317
|
|
|
560
318
|
// Persist the runtime-storage URL onto \`teleport_invoices.pdf_url\` once
|
|
@@ -574,6 +332,7 @@ ${emailEnabled
|
|
|
574
332
|
} catch (updateErr) {
|
|
575
333
|
console.error('[invoice] DB update FAILED for pdf_url=' + storageUrl + ' (id=' + invoiceData.id + '): ' + (updateErr && updateErr.message));
|
|
576
334
|
}
|
|
335
|
+
await invoiceAssembly.recordStoredInvoicePdfKey(invoiceData.id, uploadResult.fileId);
|
|
577
336
|
} else {
|
|
578
337
|
console.info('[invoice] Skipping pdf_url update — storage upload did not yield a URL; keeping DB fallback ' + invoiceData.pdfUrl);
|
|
579
338
|
}
|
|
@@ -672,20 +431,284 @@ ${emailEnabled
|
|
|
672
431
|
${emailEnabled
|
|
673
432
|
? ` await sentEmailLog.settleSentEmailLog();
|
|
674
433
|
`
|
|
675
|
-
: ''}
|
|
434
|
+
: ''} // The error names the store's tables and data: server log only (above).
|
|
435
|
+
res.status(500).json({ success: false, error: 'Failed to generate invoice' });
|
|
676
436
|
}
|
|
677
437
|
};
|
|
678
438
|
`;
|
|
679
439
|
};
|
|
680
440
|
exports.generateInvoiceGenerateRouteCode = generateInvoiceGenerateRouteCode;
|
|
441
|
+
/** The roles allowed to rebuild an invoice (the admin panel is the only caller). */
|
|
442
|
+
const REGENERATE_INVOICE_ROLES = INVOICE_ADMIN_ROLES;
|
|
443
|
+
/**
|
|
444
|
+
* POST /api/invoices/[id]/regenerate — the admin panel's "Regenerate" action.
|
|
445
|
+
*
|
|
446
|
+
* Rebuilds ONE invoice from its order with the very assembly that issued it at
|
|
447
|
+
* payment (`utils/invoices/invoice-assembly.js`), IN PLACE: the same id, number,
|
|
448
|
+
* dates and status, so the order, the sent-email ledger and any refund recorded
|
|
449
|
+
* against it keep pointing at a valid invoice. What a merchant corrected on the
|
|
450
|
+
* invoice itself (customer details, notes, payment method) wins over the order;
|
|
451
|
+
* the lines and every figure are recomputed from the order. The old PDF is
|
|
452
|
+
* replaced — and its runtime-storage copy deleted — and the customer is never
|
|
453
|
+
* emailed.
|
|
454
|
+
*
|
|
455
|
+
* Unlike `/generate`, which the payment webhook calls server-to-server, this
|
|
456
|
+
* route is reached from the merchant's browser only, so it checks the session
|
|
457
|
+
* itself: signed in, with an admin role.
|
|
458
|
+
*/
|
|
459
|
+
const generateInvoiceRegenerateRouteCode = () => {
|
|
460
|
+
return `/**
|
|
461
|
+
* POST /api/invoices/[id]/regenerate
|
|
462
|
+
* Rebuilds one invoice from its order, in place, for the admin panel. Same
|
|
463
|
+
* number, id and dates; a freshly rendered PDF replaces the old one; no email.
|
|
464
|
+
*/
|
|
465
|
+
|
|
466
|
+
var dataAccess = require('../../../../utils/invoices/data-access');
|
|
467
|
+
var pdfGenerator = require('../../../../utils/invoices/pdf-generator');
|
|
468
|
+
var invoiceAssembly = require('../../../../utils/invoices/invoice-assembly');
|
|
469
|
+
|
|
470
|
+
${(0, session_cookie_resolver_1.generateCommonJsSessionTokenResolverCode)()}
|
|
471
|
+
${workflow_auth_generator_1.ROLE_OF_TOKEN_CODE}
|
|
472
|
+
|
|
473
|
+
var REGENERATE_ALLOWED_ROLES = ${JSON.stringify(REGENERATE_INVOICE_ROLES)};
|
|
474
|
+
|
|
475
|
+
var MESSAGES = {
|
|
476
|
+
unauthenticated: 'Your session has ended. Sign in again to regenerate invoices.',
|
|
477
|
+
forbidden: 'Only an admin can regenerate invoices.',
|
|
478
|
+
missingId: 'Invoice id is required.',
|
|
479
|
+
notFound: 'This invoice no longer exists.',
|
|
480
|
+
notLinked: 'This invoice is not linked to an order, so there is nothing to rebuild it from.',
|
|
481
|
+
orderGone: 'The order this invoice was issued for no longer exists.',
|
|
482
|
+
noLines: 'The order has no products left to invoice.',
|
|
483
|
+
failed: 'The invoice could not be regenerated.',
|
|
484
|
+
orderNotUpdated: 'The invoice was rebuilt, but its order could not be updated, so the customer still sees the previous PDF. Regenerate it again.',
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
// 'YYYY-MM-DD' of a stored date, the shape the assembly and the PDF expect.
|
|
488
|
+
// pg hands a DATE/TIMESTAMP over as a Date built from the naive column value
|
|
489
|
+
// in LOCAL time, so its local calendar day is the stored one; a string is cut
|
|
490
|
+
// to its date part. Empty when unreadable — the assembly then falls back
|
|
491
|
+
// exactly as it does at payment.
|
|
492
|
+
function calendarDate(value) {
|
|
493
|
+
if (!value) return '';
|
|
494
|
+
if (value instanceof Date) {
|
|
495
|
+
if (isNaN(value.getTime())) return '';
|
|
496
|
+
return value.getFullYear() + '-' + String(value.getMonth() + 1).padStart(2, '0') + '-' + String(value.getDate()).padStart(2, '0');
|
|
497
|
+
}
|
|
498
|
+
var match = /^(\\d{4}-\\d{2}-\\d{2})/.exec(String(value));
|
|
499
|
+
return match ? match[1] : '';
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// What the invoice itself says, stated over the order: the identity of the
|
|
503
|
+
// document (id, dates, status) and what a merchant can correct with Edit —
|
|
504
|
+
// the customer details, the notes and the payment method. Everything left out
|
|
505
|
+
// (the lines, prices, discounts, tax, delivery, gift card, currency) is read
|
|
506
|
+
// from the order, exactly as at payment. An empty field falls back to the
|
|
507
|
+
// order too.
|
|
508
|
+
function regenerationBody(invoice) {
|
|
509
|
+
return {
|
|
510
|
+
orderId: String(invoice.order_id),
|
|
511
|
+
id: String(invoice.id),
|
|
512
|
+
status: invoice.status || 'issued',
|
|
513
|
+
issueDate: calendarDate(invoice.issue_date),
|
|
514
|
+
dueDate: calendarDate(invoice.due_date),
|
|
515
|
+
paidAt: invoice.paid_at || null,
|
|
516
|
+
customerName: invoice.customer_name || '',
|
|
517
|
+
customerEmail: invoice.customer_email || '',
|
|
518
|
+
customerAddress: invoice.customer_address || '',
|
|
519
|
+
customerCity: invoice.customer_city || '',
|
|
520
|
+
customerState: invoice.customer_state || '',
|
|
521
|
+
customerZip: invoice.customer_zip || '',
|
|
522
|
+
customerCountry: invoice.customer_country || '',
|
|
523
|
+
customerVat: invoice.customer_vat || '',
|
|
524
|
+
paymentMethod: invoice.payment_method || '',
|
|
525
|
+
paymentProvider: invoice.payment_provider || '',
|
|
526
|
+
paymentIntentId: invoice.payment_intent_id || '',
|
|
527
|
+
notes: invoice.notes || '',
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
async function sessionRole(req) {
|
|
532
|
+
try {
|
|
533
|
+
var token = await __tqSessionToken(req);
|
|
534
|
+
return token ? { signedIn: true, role: roleOf(token) } : { signedIn: false, role: null };
|
|
535
|
+
} catch (err) {
|
|
536
|
+
console.warn('[invoice] Regenerate: could not read the session — ' + (err && err.message));
|
|
537
|
+
return { signedIn: false, role: null };
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// Postgres refuses an id that is not a UUID ("invalid_text_representation").
|
|
542
|
+
var MALFORMED_ID_ERROR_CODE = '22P02';
|
|
543
|
+
|
|
544
|
+
// A malformed id is a missing invoice; any other failure (an outage, a full
|
|
545
|
+
// pool) is a server error, never "this invoice no longer exists".
|
|
546
|
+
async function findInvoice(invoiceId) {
|
|
547
|
+
try {
|
|
548
|
+
return await dataAccess.getInvoiceById(invoiceId);
|
|
549
|
+
} catch (err) {
|
|
550
|
+
if (err && err.code === MALFORMED_ID_ERROR_CODE) return null;
|
|
551
|
+
throw err;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
module.exports = async function handler(req, res) {
|
|
556
|
+
if (req.method !== 'POST') {
|
|
557
|
+
res.setHeader('Allow', 'POST');
|
|
558
|
+
res.status(405).json({ success: false, error: 'Method not allowed' });
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
var session = await sessionRole(req);
|
|
563
|
+
if (!session.signedIn) {
|
|
564
|
+
res.status(401).json({ success: false, error: MESSAGES.unauthenticated });
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
if (!session.role || REGENERATE_ALLOWED_ROLES.indexOf(session.role) < 0) {
|
|
568
|
+
res.status(403).json({ success: false, error: MESSAGES.forbidden });
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
var invoiceId = String((req.query && req.query.id) || '').trim();
|
|
573
|
+
if (!invoiceId) {
|
|
574
|
+
res.status(400).json({ success: false, error: MESSAGES.missingId });
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
try {
|
|
579
|
+
var invoice = await findInvoice(invoiceId);
|
|
580
|
+
if (!invoice) {
|
|
581
|
+
res.status(404).json({ success: false, error: MESSAGES.notFound });
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
if (!invoice.order_id) {
|
|
585
|
+
res.status(409).json({ success: false, error: MESSAGES.notLinked });
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
var hydrated = await dataAccess.getOrderWithItems(String(invoice.order_id));
|
|
590
|
+
if (!hydrated || !hydrated.order) {
|
|
591
|
+
res.status(409).json({ success: false, error: MESSAGES.orderGone });
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
var invoiceData = invoiceAssembly.assembleInvoiceData(
|
|
596
|
+
regenerationBody(invoice),
|
|
597
|
+
hydrated.order,
|
|
598
|
+
Array.isArray(hydrated.items) ? hydrated.items : []
|
|
599
|
+
);
|
|
600
|
+
if (!invoiceData) {
|
|
601
|
+
res.status(409).json({ success: false, error: MESSAGES.noLines });
|
|
602
|
+
return;
|
|
603
|
+
}
|
|
604
|
+
invoiceData.invoiceNumber = String(invoice.invoice_number || '');
|
|
605
|
+
|
|
606
|
+
// Rendered BEFORE anything is written: a PDF service that is down leaves
|
|
607
|
+
// the invoice exactly as it was.
|
|
608
|
+
var pdfBuffer = await pdfGenerator.generateInvoicePdf(invoiceData);
|
|
609
|
+
invoiceData.pdfData = pdfBuffer;
|
|
610
|
+
invoiceData.pdfSizeBytes = pdfBuffer.length;
|
|
611
|
+
invoiceData.pdfUrl = '/api/invoices/' + invoiceData.id + '/pdf';
|
|
612
|
+
|
|
613
|
+
await dataAccess.replaceInvoice(invoiceData.id, invoiceData, invoiceData.items);
|
|
614
|
+
console.info('[invoice] Regenerated ' + invoiceData.invoiceNumber + ' (id=' + invoiceData.id + ', items=' + invoiceData.items.length + ', pdf_size_bytes=' + pdfBuffer.length + ')');
|
|
615
|
+
|
|
616
|
+
// The new PDF's public copy. The row already serves the new bytes through
|
|
617
|
+
// /api/invoices/<id>/pdf, so a failed upload costs nothing but the public URL.
|
|
618
|
+
var previousStorageKey = invoice.pdf_storage_key ? String(invoice.pdf_storage_key) : '';
|
|
619
|
+
var safeFileName = String(invoiceData.invoiceNumber || invoiceData.id).replace(/[^a-zA-Z0-9._-]/g, '_') + '.pdf';
|
|
620
|
+
var upload = await invoiceAssembly.uploadInvoicePdfToRuntimeStorage(pdfBuffer, safeFileName, invoiceAssembly.requestBaseUrl(req));
|
|
621
|
+
var storedUrl = upload && upload.storageUrl ? String(upload.storageUrl) : '';
|
|
622
|
+
var storageKey = storedUrl ? String(upload.fileId || '') : '';
|
|
623
|
+
var pdfUrl = storedUrl || invoiceData.pdfUrl;
|
|
624
|
+
|
|
625
|
+
// The order BEFORE the old copy goes: the customer's "View invoice" (their
|
|
626
|
+
// profile, the order page) opens the order's link, so until it names the
|
|
627
|
+
// new PDF the old copy must stay. On failure the new copy is dropped
|
|
628
|
+
// instead and nothing else changes, so regenerating again starts clean.
|
|
629
|
+
try {
|
|
630
|
+
await dataAccess.linkOrderToInvoice(invoiceData.orderId, invoiceData.id, invoiceData.invoiceNumber, pdfUrl);
|
|
631
|
+
} catch (linkErr) {
|
|
632
|
+
console.error('[invoice] Regenerate: could not update order ' + invoiceData.orderId + ' — ' + (linkErr && linkErr.message));
|
|
633
|
+
if (storageKey) {
|
|
634
|
+
await invoiceAssembly.deleteStoredInvoicePdf(storageKey);
|
|
635
|
+
}
|
|
636
|
+
res.status(500).json({ success: false, error: MESSAGES.orderNotUpdated });
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
if (storedUrl) {
|
|
641
|
+
try {
|
|
642
|
+
await dataAccess.updateInvoice(invoiceData.id, { pdf_url: storedUrl });
|
|
643
|
+
} catch (updateErr) {
|
|
644
|
+
console.error('[invoice] Regenerate: could not save pdf_url=' + storedUrl + ' (id=' + invoiceData.id + '): ' + (updateErr && updateErr.message));
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
invoiceData.pdfUrl = pdfUrl;
|
|
648
|
+
if (storageKey !== previousStorageKey) {
|
|
649
|
+
await invoiceAssembly.recordStoredInvoicePdfKey(invoiceData.id, storageKey);
|
|
650
|
+
}
|
|
651
|
+
if (previousStorageKey && previousStorageKey !== storageKey) {
|
|
652
|
+
await invoiceAssembly.deleteStoredInvoicePdf(previousStorageKey);
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
res.status(200).json({
|
|
656
|
+
success: true,
|
|
657
|
+
invoiceId: invoiceData.id,
|
|
658
|
+
invoiceNumber: invoiceData.invoiceNumber,
|
|
659
|
+
pdfUrl: invoiceData.pdfUrl,
|
|
660
|
+
total: invoiceData.total,
|
|
661
|
+
currency: invoiceData.currency,
|
|
662
|
+
});
|
|
663
|
+
} catch (error) {
|
|
664
|
+
console.error('[invoice] Regeneration threw:', error && error.stack ? error.stack : error);
|
|
665
|
+
// The error names the store's tables and data: server log only (above).
|
|
666
|
+
res.status(500).json({ success: false, error: MESSAGES.failed });
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
`;
|
|
670
|
+
};
|
|
671
|
+
exports.generateInvoiceRegenerateRouteCode = generateInvoiceRegenerateRouteCode;
|
|
672
|
+
/**
|
|
673
|
+
* GET /api/invoices/[id]/pdf — the invoice PDF kept in the database, the link
|
|
674
|
+
* an order shows when runtime storage is not configured.
|
|
675
|
+
*
|
|
676
|
+
* An invoice carries its buyer's name, address and what they bought, so it is
|
|
677
|
+
* served to the order's own buyer (their session), a signed-in admin, or the
|
|
678
|
+
* store's server code — and to nobody else, whoever knows the id. An invoice
|
|
679
|
+
* someone may not read answers exactly like one that does not exist.
|
|
680
|
+
*/
|
|
681
681
|
const generateInvoicePdfRouteCode = () => {
|
|
682
682
|
return `/**
|
|
683
683
|
* GET /api/invoices/[id]/pdf
|
|
684
|
-
* Returns the invoice PDF binary for download.
|
|
684
|
+
* Returns the invoice PDF binary for download, to its buyer or the store.
|
|
685
685
|
*/
|
|
686
686
|
|
|
687
687
|
var dataAccess = require('../../../../utils/invoices/data-access');
|
|
688
688
|
|
|
689
|
+
${INVOICE_CALLER_CODE}
|
|
690
|
+
|
|
691
|
+
// Postgres refuses an id that is not a UUID ("invalid_text_representation").
|
|
692
|
+
var MALFORMED_ID_ERROR_CODE = '22P02';
|
|
693
|
+
|
|
694
|
+
async function findInvoice(invoiceId) {
|
|
695
|
+
try {
|
|
696
|
+
return await dataAccess.getInvoiceById(invoiceId);
|
|
697
|
+
} catch (err) {
|
|
698
|
+
if (err && err.code === MALFORMED_ID_ERROR_CODE) return null;
|
|
699
|
+
throw err;
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
// The buyer of the invoice's order: the order row's owner, read from the order
|
|
704
|
+
// itself — an invoice's own customer fields are editable text.
|
|
705
|
+
async function isOrderOwner(invoice, userId) {
|
|
706
|
+
if (!userId || !invoice || !invoice.order_id) return false;
|
|
707
|
+
var hydrated = await dataAccess.getOrderWithItems(String(invoice.order_id));
|
|
708
|
+
var owner = hydrated && hydrated.order ? hydrated.order.user_id : null;
|
|
709
|
+
return owner != null && String(owner) === String(userId);
|
|
710
|
+
}
|
|
711
|
+
|
|
689
712
|
module.exports = async function handler(req, res) {
|
|
690
713
|
if (req.method !== 'GET') {
|
|
691
714
|
res.status(405).json({ error: 'Method not allowed' });
|
|
@@ -693,14 +716,20 @@ module.exports = async function handler(req, res) {
|
|
|
693
716
|
}
|
|
694
717
|
|
|
695
718
|
try {
|
|
719
|
+
var caller = await invoiceCaller(req);
|
|
720
|
+
if (!caller.server && !caller.signedIn) {
|
|
721
|
+
res.status(401).json({ error: 'Unauthenticated' });
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
|
|
696
725
|
var invoiceId = req.query.id;
|
|
697
726
|
if (!invoiceId) {
|
|
698
727
|
res.status(400).json({ error: 'Invoice ID is required' });
|
|
699
728
|
return;
|
|
700
729
|
}
|
|
701
730
|
|
|
702
|
-
var invoice = await
|
|
703
|
-
if (!invoice) {
|
|
731
|
+
var invoice = await findInvoice(String(invoiceId));
|
|
732
|
+
if (!invoice || (!caller.server && !caller.admin && !(await isOrderOwner(invoice, caller.userId)))) {
|
|
704
733
|
res.status(404).json({ error: 'Invoice not found' });
|
|
705
734
|
return;
|
|
706
735
|
}
|
|
@@ -725,10 +754,13 @@ module.exports = async function handler(req, res) {
|
|
|
725
754
|
res.setHeader('Content-Type', 'application/pdf');
|
|
726
755
|
res.setHeader('Content-Disposition', 'attachment; filename="' + safeFilename + '"; filename*=UTF-8' + "'" + "'" + encodeURIComponent(rawFilename));
|
|
727
756
|
res.setHeader('Content-Length', pdfBuffer.length);
|
|
757
|
+
// Personal data: never kept by a shared cache.
|
|
758
|
+
res.setHeader('Cache-Control', 'private, no-store');
|
|
728
759
|
res.status(200).end(pdfBuffer);
|
|
729
760
|
} catch (error) {
|
|
761
|
+
// The error names the store's tables and data: server log only.
|
|
730
762
|
console.error('Invoice PDF download error:', error);
|
|
731
|
-
res.status(500).json({ success: false, error:
|
|
763
|
+
res.status(500).json({ success: false, error: 'Failed to retrieve invoice PDF' });
|
|
732
764
|
}
|
|
733
765
|
};
|
|
734
766
|
`;
|