@vtex/faststore 0.0.6 → 0.0.8
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/CHANGELOG.md +99 -0
- package/dist/actions.json +152 -1
- package/dist/catalog.json +2541 -1278
- package/dist/cli/UnreachableCaseError-Crd168Vu.js +10 -0
- package/dist/cli/UnreachableCaseError-Crd168Vu.js.map +1 -0
- package/dist/cli/cacheControl-CEojH_TM.js +158 -0
- package/dist/cli/cacheControl-CEojH_TM.js.map +1 -0
- package/dist/cli/cachePolicy-m2vASMRW.js +26 -0
- package/dist/cli/cachePolicy-m2vASMRW.js.map +1 -0
- package/dist/cli/computeCoreSchemaHash-DPJZj-qJ.js +10 -0
- package/dist/cli/computeCoreSchemaHash-DPJZj-qJ.js.map +1 -0
- package/dist/cli/default-BCQHcwbL.js +253 -0
- package/dist/cli/default-BCQHcwbL.js.map +1 -0
- package/dist/cli/disableSuggestions-yO9UqiWn.js +21 -0
- package/dist/cli/disableSuggestions-yO9UqiWn.js.map +1 -0
- package/dist/cli/dist-C1JhdHfo.js +2001 -0
- package/dist/cli/dist-C1JhdHfo.js.map +1 -0
- package/dist/cli/graphql-DG9thCDG.js +14589 -0
- package/dist/cli/graphql-DG9thCDG.js.map +1 -0
- package/dist/cli/index.d.ts +799 -0
- package/dist/cli/index.js +36459 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/index.min-BsIHDfFK.js +613 -0
- package/dist/cli/index.min-BsIHDfFK.js.map +1 -0
- package/dist/cli/inlineTrace-uLgOJ3TH.js +52 -0
- package/dist/cli/inlineTrace-uLgOJ3TH.js.map +1 -0
- package/dist/cli/internalPlugin-DnuwN4_4.js +11 -0
- package/dist/cli/internalPlugin-DnuwN4_4.js.map +1 -0
- package/dist/cli/packageVersion-DQAnIEil.js +6 -0
- package/dist/cli/packageVersion-DQAnIEil.js.map +1 -0
- package/dist/cli/rolldown-runtime-BMI-E3GI.js +44 -0
- package/dist/cli/schemaIsSubgraph-DoGh3OYj.js +17 -0
- package/dist/cli/schemaIsSubgraph-DoGh3OYj.js.map +1 -0
- package/dist/cli/schemaReporting-K-me-3-v.js +199 -0
- package/dist/cli/schemaReporting-K-me-3-v.js.map +1 -0
- package/dist/cli/server-runtime.js +49879 -0
- package/dist/cli/server-runtime.js.map +1 -0
- package/dist/cli/traceTreeBuilder-BIcV2U7b.js +9118 -0
- package/dist/cli/traceTreeBuilder-BIcV2U7b.js.map +1 -0
- package/dist/cli/usageReporting-Bpl8vSZX.js +10201 -0
- package/dist/cli/usageReporting-Bpl8vSZX.js.map +1 -0
- package/dist/cli/v4-CBhFvC49.js +42 -0
- package/dist/cli/v4-CBhFvC49.js.map +1 -0
- package/dist/client.d.ts +5 -1
- package/dist/client.js +5 -1
- package/dist/components.d.ts +38 -9
- package/dist/components.js +42 -13
- package/dist/content-types.json +616 -0
- package/dist/core/dist/define-component.d.ts +43 -1
- package/dist/core/dist/index.d.ts +2 -2
- package/dist/docs/account-access-gate.md +4 -4
- package/dist/docs/account-address-book.md +519 -0
- package/dist/docs/account-entry-point.md +1 -1
- package/dist/docs/account-menu-identity.md +160 -0
- package/dist/docs/account-menu.md +107 -24
- package/dist/docs/alert-dialog.md +2 -2
- package/dist/docs/avatar.md +103 -0
- package/dist/docs/billing-address.md +17 -9
- package/dist/docs/card-entry.md +37 -6
- package/dist/docs/cardholder-document.md +16 -14
- package/dist/docs/cart-item.md +1 -1
- package/dist/docs/cart.md +8 -8
- package/dist/docs/client-profile-fieldset.md +7 -5
- package/dist/docs/copy-text.md +84 -0
- package/dist/docs/document-field.md +8 -8
- package/dist/docs/footer-link-group.md +2 -2
- package/dist/docs/header-root.md +1 -1
- package/dist/docs/incentives.md +2 -2
- package/dist/docs/logo.md +5 -5
- package/dist/docs/my-account-profile.md +5 -5
- package/dist/docs/navigation-link-list.md +2 -2
- package/dist/docs/navigation-link.md +3 -3
- package/dist/docs/order-cancel.md +52 -0
- package/dist/docs/order-delivery-address.md +63 -0
- package/dist/docs/order-delivery-group.md +83 -0
- package/dist/docs/order-details-back.md +41 -0
- package/dist/docs/order-details-header.md +48 -0
- package/dist/docs/order-list-row.md +46 -0
- package/dist/docs/order-list-search.md +101 -0
- package/dist/docs/order-list-views.md +97 -0
- package/dist/docs/order-list.md +94 -0
- package/dist/docs/order-payment.md +94 -0
- package/dist/docs/order-placed-date.md +49 -0
- package/dist/docs/order-placed-payment-summary.md +13 -15
- package/dist/docs/order-placed.md +225 -0
- package/dist/docs/order-progress.md +88 -0
- package/dist/docs/order-status-badge.md +91 -0
- package/dist/docs/order-summary.md +53 -0
- package/dist/docs/payment-method-badges.md +14 -3
- package/dist/docs/place-order.md +13 -9
- package/dist/docs/product-shelf.md +20 -13
- package/dist/docs/saved-cards.md +2 -2
- package/dist/docs/select.md +19 -6
- package/dist/docs/session.md +1 -1
- package/dist/docs/shipping-address.md +1 -1
- package/dist/docs/sign-in-redirect.md +6 -6
- package/dist/docs/toast.md +7 -3
- package/dist/index.d.ts +7 -3
- package/dist/index.js +2 -1
- package/dist/internal/client.d.ts +6 -1
- package/dist/internal/client.js +8 -3
- package/dist/internal/content.d.ts +2 -2
- package/dist/internal/server.d.ts +8 -1
- package/dist/internal/server.js +8 -1
- package/dist/matter/account-access-gate/account-access-gate.d.ts +2 -1
- package/dist/matter/account-access-gate/account-access-gate.js +19 -16
- package/dist/matter/account-access-gate/account-access-gate.js.map +1 -1
- package/dist/matter/account-address-book/account-address-book-delete.d.ts +60 -0
- package/dist/matter/account-address-book/account-address-book-delete.js +184 -0
- package/dist/matter/account-address-book/account-address-book-delete.js.map +1 -0
- package/dist/matter/account-address-book/account-address-book-deliverability.d.ts +19 -0
- package/dist/matter/account-address-book/account-address-book-deliverability.js +50 -0
- package/dist/matter/account-address-book/account-address-book-deliverability.js.map +1 -0
- package/dist/matter/account-address-book/account-address-book-form-parts.d.ts +42 -0
- package/dist/matter/account-address-book/account-address-book-form-parts.js +146 -0
- package/dist/matter/account-address-book/account-address-book-form-parts.js.map +1 -0
- package/dist/matter/account-address-book/account-address-book-profile-notice.d.ts +25 -0
- package/dist/matter/account-address-book/account-address-book-profile-notice.js +72 -0
- package/dist/matter/account-address-book/account-address-book-profile-notice.js.map +1 -0
- package/dist/matter/account-address-book/account-address-book.d.ts +120 -0
- package/dist/matter/account-address-book/account-address-book.js +469 -0
- package/dist/matter/account-address-book/account-address-book.js.map +1 -0
- package/dist/matter/account-address-book/account-address-country-switch.js +59 -0
- package/dist/matter/account-address-book/account-address-country-switch.js.map +1 -0
- package/dist/matter/account-address-book/account-address-country.d.ts +36 -0
- package/dist/matter/account-address-book/account-address-country.js +151 -0
- package/dist/matter/account-address-book/account-address-country.js.map +1 -0
- package/dist/matter/account-address-book/account-address-first-line.js +11 -0
- package/dist/matter/account-address-book/account-address-first-line.js.map +1 -0
- package/dist/matter/account-address-book/account-address-form-context.d.ts +55 -0
- package/dist/matter/account-address-book/account-address-form-context.js +14 -0
- package/dist/matter/account-address-book/account-address-form-context.js.map +1 -0
- package/dist/matter/account-address-book/account-address-form.d.ts +85 -0
- package/dist/matter/account-address-book/account-address-form.js +946 -0
- package/dist/matter/account-address-book/account-address-form.js.map +1 -0
- package/dist/matter/account-address-book/account-address-postal-autofill.js +189 -0
- package/dist/matter/account-address-book/account-address-postal-autofill.js.map +1 -0
- package/dist/matter/account-address-book/account-address-record.d.ts +26 -0
- package/dist/matter/account-address-book/account-address-record.js +138 -0
- package/dist/matter/account-address-book/account-address-record.js.map +1 -0
- package/dist/matter/account-entry-point/account-entry-point.js +11 -11
- package/dist/matter/account-entry-point/account-entry-point.js.map +1 -1
- package/dist/matter/account-menu/account-menu.d.ts +77 -3
- package/dist/matter/account-menu/account-menu.js +252 -19
- package/dist/matter/account-menu/account-menu.js.map +1 -1
- package/dist/matter/account-menu/sign-out-failure.js +50 -0
- package/dist/matter/account-menu/sign-out-failure.js.map +1 -0
- package/dist/matter/account-menu-identity/account-menu-identity.d.ts +21 -0
- package/dist/matter/account-menu-identity/account-menu-identity.js +88 -0
- package/dist/matter/account-menu-identity/account-menu-identity.js.map +1 -0
- package/dist/matter/billing-address/billing-address.d.ts +30 -17
- package/dist/matter/billing-address/billing-address.js +128 -33
- package/dist/matter/billing-address/billing-address.js.map +1 -1
- package/dist/matter/breadcrumb/breadcrumb.js +2 -2
- package/dist/matter/breadcrumb/breadcrumb.js.map +1 -1
- package/dist/matter/card-entry/card-capture.js +4 -3
- package/dist/matter/card-entry/card-capture.js.map +1 -1
- package/dist/matter/card-entry/card-entry.d.ts +5 -3
- package/dist/matter/card-entry/card-entry.js +78 -27
- package/dist/matter/card-entry/card-entry.js.map +1 -1
- package/dist/matter/cardholder-document/cardholder-document.d.ts +10 -9
- package/dist/matter/cardholder-document/cardholder-document.js +36 -16
- package/dist/matter/cardholder-document/cardholder-document.js.map +1 -1
- package/dist/matter/cart/cart.d.ts +7 -2
- package/dist/matter/cart/cart.js +29 -26
- package/dist/matter/cart/cart.js.map +1 -1
- package/dist/matter/cart-item/cart-item.js +2 -2
- package/dist/matter/cart-item/cart-item.js.map +1 -1
- package/dist/matter/client-preferences/client-preferences-fieldset.js +2 -2
- package/dist/matter/client-profile-form/client-profile-fieldset.js +9 -6
- package/dist/matter/client-profile-form/client-profile-fieldset.js.map +1 -1
- package/dist/matter/identity-edit/identity-edit.js +3 -3
- package/dist/matter/identity-edit/identity-edit.js.map +1 -1
- package/dist/matter/identity-summary/identity-summary.js +4 -3
- package/dist/matter/identity-summary/identity-summary.js.map +1 -1
- package/dist/matter/my-account-profile/my-account-profile.d.ts +6 -3
- package/dist/matter/my-account-profile/my-account-profile.js +6 -5
- package/dist/matter/my-account-profile/my-account-profile.js.map +1 -1
- package/dist/matter/order-cancel/order-cancel.d.ts +110 -0
- package/dist/matter/order-cancel/order-cancel.js +344 -0
- package/dist/matter/order-cancel/order-cancel.js.map +1 -0
- package/dist/matter/order-delivery-address/order-delivery-address.d.ts +73 -0
- package/dist/matter/order-delivery-address/order-delivery-address.js +172 -0
- package/dist/matter/order-delivery-address/order-delivery-address.js.map +1 -0
- package/dist/matter/order-delivery-group/order-delivery-group.d.ts +128 -0
- package/dist/matter/order-delivery-group/order-delivery-group.js +408 -0
- package/dist/matter/order-delivery-group/order-delivery-group.js.map +1 -0
- package/dist/matter/order-details-header/order-details-header.d.ts +104 -0
- package/dist/matter/order-details-header/order-details-header.js +190 -0
- package/dist/matter/order-details-header/order-details-header.js.map +1 -0
- package/dist/matter/order-list/customer-orders-filter.d.ts +12 -0
- package/dist/matter/order-list/customer-orders-filter.js +30 -0
- package/dist/matter/order-list/customer-orders-filter.js.map +1 -0
- package/dist/matter/order-list/order-list.d.ts +121 -0
- package/dist/matter/order-list/order-list.js +395 -0
- package/dist/matter/order-list/order-list.js.map +1 -0
- package/dist/matter/order-list-row/order-list-row.d.ts +44 -0
- package/dist/matter/order-list-row/order-list-row.js +127 -0
- package/dist/matter/order-list-row/order-list-row.js.map +1 -0
- package/dist/matter/order-list-search/order-list-search.d.ts +72 -0
- package/dist/matter/order-list-search/order-list-search.js +296 -0
- package/dist/matter/order-list-search/order-list-search.js.map +1 -0
- package/dist/matter/order-list-views/order-list-views.d.ts +65 -0
- package/dist/matter/order-list-views/order-list-views.js +154 -0
- package/dist/matter/order-list-views/order-list-views.js.map +1 -0
- package/dist/matter/order-payment/order-payment.d.ts +83 -0
- package/dist/matter/order-payment/order-payment.js +258 -0
- package/dist/matter/order-payment/order-payment.js.map +1 -0
- package/dist/matter/order-placed/order-placed-deliveries.d.ts +145 -0
- package/dist/matter/order-placed/order-placed-deliveries.js +380 -0
- package/dist/matter/order-placed/order-placed-deliveries.js.map +1 -0
- package/dist/matter/order-placed/order-placed.d.ts +122 -0
- package/dist/matter/order-placed/order-placed.js +452 -0
- package/dist/matter/order-placed/order-placed.js.map +1 -0
- package/dist/matter/order-placed-date/order-placed-date.d.ts +45 -0
- package/dist/matter/order-placed-date/order-placed-date.js +92 -0
- package/dist/matter/order-placed-date/order-placed-date.js.map +1 -0
- package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.d.ts +5 -8
- package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js +29 -81
- package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js.map +1 -1
- package/dist/matter/order-progress/order-progress.d.ts +85 -0
- package/dist/matter/order-progress/order-progress.js +203 -0
- package/dist/matter/order-progress/order-progress.js.map +1 -0
- package/dist/matter/order-summary/order-summary.d.ts +81 -0
- package/dist/matter/order-summary/order-summary.js +192 -0
- package/dist/matter/order-summary/order-summary.js.map +1 -0
- package/dist/matter/payment/cardholder-document-rule.d.ts +35 -0
- package/dist/matter/payment/cardholder-document-rule.js +35 -0
- package/dist/matter/payment/cardholder-document-rule.js.map +1 -0
- package/dist/matter/payment/payment-card-capture.js +38 -23
- package/dist/matter/payment/payment-card-capture.js.map +1 -1
- package/dist/matter/payment/payment-controller.js +12 -0
- package/dist/matter/payment/payment-controller.js.map +1 -1
- package/dist/matter/payment/payment-method-badges.js +4 -2
- package/dist/matter/payment/payment-method-badges.js.map +1 -1
- package/dist/matter/payment/payment.js +12 -0
- package/dist/matter/payment/payment.js.map +1 -1
- package/dist/matter/payment/use-payment-method-selection.d.ts +39 -0
- package/dist/matter/payment/use-payment-method-selection.js +30 -2
- package/dist/matter/payment/use-payment-method-selection.js.map +1 -1
- package/dist/matter/payment/use-payment-submit-gate.d.ts +16 -2
- package/dist/matter/payment/use-payment-submit-gate.js +42 -14
- package/dist/matter/payment/use-payment-submit-gate.js.map +1 -1
- package/dist/matter/place-order/place-order.d.ts +12 -7
- package/dist/matter/place-order/place-order.js +126 -103
- package/dist/matter/place-order/place-order.js.map +1 -1
- package/dist/matter/pricing/pricing.js +5 -5
- package/dist/matter/pricing/pricing.js.map +1 -1
- package/dist/matter/product-shelf/product-shelf.d.ts +61 -31
- package/dist/matter/product-shelf/product-shelf.js +157 -57
- package/dist/matter/product-shelf/product-shelf.js.map +1 -1
- package/dist/matter/region/region.js +1 -1
- package/dist/matter/saved-cards/saved-cards.js +27 -15
- package/dist/matter/saved-cards/saved-cards.js.map +1 -1
- package/dist/matter/session/session.js +2 -2
- package/dist/matter/session/session.js.map +1 -1
- package/dist/matter/shipping-address/country-descriptors.d.ts +1 -0
- package/dist/matter/shipping-address/country-descriptors.js +23 -1
- package/dist/matter/shipping-address/country-descriptors.js.map +1 -1
- package/dist/matter/shipping-address/shipping-address.js +63 -15
- package/dist/matter/shipping-address/shipping-address.js.map +1 -1
- package/dist/matter/shipping-simulator/shipping-simulator.d.ts +1 -1
- package/dist/matter/shipping-simulator/shipping-simulator.js.map +1 -1
- package/dist/matter/sign-in-redirect/sign-in-redirect.js +48 -10
- package/dist/matter/sign-in-redirect/sign-in-redirect.js.map +1 -1
- package/dist/matter/variant-selector/variant-selector.js +2 -2
- package/dist/matter/variant-selector/variant-selector.js.map +1 -1
- package/dist/particles/address-summary/address-summary.js +2 -2
- package/dist/particles/address-summary/address-summary.js.map +1 -1
- package/dist/particles/alert-dialog/alert-dialog.d.ts +5 -1
- package/dist/particles/alert-dialog/alert-dialog.js +5 -2
- package/dist/particles/alert-dialog/alert-dialog.js.map +1 -1
- package/dist/particles/avatar/avatar.d.ts +17 -0
- package/dist/particles/avatar/avatar.js +65 -0
- package/dist/particles/avatar/avatar.js.map +1 -0
- package/dist/particles/copy-text/copy-text.d.ts +28 -0
- package/dist/particles/copy-text/copy-text.js +140 -0
- package/dist/particles/copy-text/copy-text.js.map +1 -0
- package/dist/particles/document-field/document-field.d.ts +34 -5
- package/dist/particles/document-field/document-field.js +115 -19
- package/dist/particles/document-field/document-field.js.map +1 -1
- package/dist/particles/field/field.js +1 -1
- package/dist/particles/field/field.js.map +1 -1
- package/dist/particles/footer-link-group/footer-link-group.d.ts +6 -2
- package/dist/particles/footer-link-group/footer-link-group.js +18 -7
- package/dist/particles/footer-link-group/footer-link-group.js.map +1 -1
- package/dist/particles/incentives/incentives.d.ts +6 -2
- package/dist/particles/incentives/incentives.js +7 -2
- package/dist/particles/incentives/incentives.js.map +1 -1
- package/dist/particles/logo/logo.d.ts +3 -2
- package/dist/particles/logo/logo.js +20 -8
- package/dist/particles/logo/logo.js.map +1 -1
- package/dist/particles/navigation-link/navigation-link.d.ts +2 -3
- package/dist/particles/navigation-link/navigation-link.js +4 -4
- package/dist/particles/navigation-link/navigation-link.js.map +1 -1
- package/dist/particles/navigation-link-list/navigation-link-list.d.ts +6 -2
- package/dist/particles/navigation-link-list/navigation-link-list.js +18 -7
- package/dist/particles/navigation-link-list/navigation-link-list.js.map +1 -1
- package/dist/particles/order-details-back/order-details-back.d.ts +28 -0
- package/dist/particles/order-details-back/order-details-back.js +52 -0
- package/dist/particles/order-details-back/order-details-back.js.map +1 -0
- package/dist/particles/order-status-badge/order-status-badge.d.ts +19 -0
- package/dist/particles/order-status-badge/order-status-badge.js +50 -0
- package/dist/particles/order-status-badge/order-status-badge.js.map +1 -0
- package/dist/particles/phone-field/phone-field.js +2 -2
- package/dist/particles/phone-field/phone-field.js.map +1 -1
- package/dist/particles/select/select.js +6 -6
- package/dist/particles/select/select.js.map +1 -1
- package/dist/particles/toast/toast.d.ts +1 -1
- package/dist/particles/toast/toast.js +32 -6
- package/dist/particles/toast/toast.js.map +1 -1
- package/dist/schema.graphql +1079 -54
- package/dist/sdk/actions/address-action-provider.d.ts +16 -0
- package/dist/sdk/actions/address-action-provider.js +20 -0
- package/dist/sdk/actions/address-action-provider.js.map +1 -0
- package/dist/sdk/actions/analytics-action-provider.js +1 -1
- package/dist/sdk/actions/index.d.ts +3 -1
- package/dist/sdk/actions/index.js +3 -1
- package/dist/sdk/actions/order-action-provider.d.ts +12 -0
- package/dist/sdk/actions/order-action-provider.js +16 -0
- package/dist/sdk/actions/order-action-provider.js.map +1 -0
- package/dist/sdk/actions/types.d.ts +6 -2
- package/dist/sdk/address/address-fields.js +38 -0
- package/dist/sdk/address/address-fields.js.map +1 -0
- package/dist/sdk/address/checkout-readiness.js +17 -0
- package/dist/sdk/address/checkout-readiness.js.map +1 -0
- package/dist/sdk/address/constants.js +60 -0
- package/dist/sdk/address/constants.js.map +1 -0
- package/dist/sdk/address/country-display.js +19 -0
- package/dist/sdk/address/country-display.js.map +1 -0
- package/dist/sdk/address/country-rules.js +30 -0
- package/dist/sdk/address/country-rules.js.map +1 -0
- package/dist/sdk/address/format-address.js +18 -0
- package/dist/sdk/address/format-address.js.map +1 -0
- package/dist/sdk/address/iso-countries.js +262 -0
- package/dist/sdk/address/iso-countries.js.map +1 -0
- package/dist/sdk/address/layouts.js +56 -0
- package/dist/sdk/address/layouts.js.map +1 -0
- package/dist/sdk/address/messages.js +97 -0
- package/dist/sdk/address/messages.js.map +1 -0
- package/dist/sdk/address/operations.d.ts +54 -0
- package/dist/sdk/address/operations.js +83 -0
- package/dist/sdk/address/operations.js.map +1 -0
- package/dist/sdk/address/postal-code-lookup-operations.js +23 -0
- package/dist/sdk/address/postal-code-lookup-operations.js.map +1 -0
- package/dist/sdk/address/postal-code.js +11 -0
- package/dist/sdk/address/postal-code.js.map +1 -0
- package/dist/sdk/address/schema.js +14 -0
- package/dist/sdk/address/schema.js.map +1 -0
- package/dist/sdk/address/server-fields.js +25 -0
- package/dist/sdk/address/server-fields.js.map +1 -0
- package/dist/sdk/address/switch-country.js +57 -0
- package/dist/sdk/address/switch-country.js.map +1 -0
- package/dist/sdk/address/types.d.ts +26 -0
- package/dist/sdk/address/use-address-actions.d.ts +29 -0
- package/dist/sdk/address/use-address-actions.js +247 -0
- package/dist/sdk/address/use-address-actions.js.map +1 -0
- package/dist/sdk/address/use-address-by-postal-code.js +57 -0
- package/dist/sdk/address/use-address-by-postal-code.js.map +1 -0
- package/dist/sdk/address/validate-address.js +62 -0
- package/dist/sdk/address/validate-address.js.map +1 -0
- package/dist/sdk/analytics/use-analytics-actions.js +2 -1
- package/dist/sdk/analytics/use-analytics-actions.js.map +1 -1
- package/dist/sdk/cache/storefront-cache.js +29 -4
- package/dist/sdk/cache/storefront-cache.js.map +1 -1
- package/dist/sdk/cart/use-cart-actions.js +9 -8
- package/dist/sdk/cart/use-cart-actions.js.map +1 -1
- package/dist/sdk/cart/use-cart-validate-on-open.js +2 -1
- package/dist/sdk/cart/use-cart-validate-on-open.js.map +1 -1
- package/dist/sdk/client/fetch-page-data.d.ts +11 -0
- package/dist/sdk/client/fetch-page-data.js +12 -1
- package/dist/sdk/client/fetch-page-data.js.map +1 -1
- package/dist/sdk/content/create-content-runtime.d.ts +22 -1
- package/dist/sdk/content/create-content-runtime.js +90 -9
- package/dist/sdk/content/create-content-runtime.js.map +1 -1
- package/dist/sdk/data/empty-content-value.js +16 -0
- package/dist/sdk/data/empty-content-value.js.map +1 -0
- package/dist/sdk/data/failed-fields.js +23 -0
- package/dist/sdk/data/failed-fields.js.map +1 -0
- package/dist/sdk/data/hot-data-provider.js +2 -1
- package/dist/sdk/data/hot-data-provider.js.map +1 -1
- package/dist/sdk/data/index.js +1 -1
- package/dist/sdk/data/page-reactive-data-root.d.ts +45 -7
- package/dist/sdk/data/page-reactive-data-root.js +88 -12
- package/dist/sdk/data/page-reactive-data-root.js.map +1 -1
- package/dist/sdk/data/variables-from-content.d.ts +43 -0
- package/dist/sdk/data/variables-from-content.js +57 -0
- package/dist/sdk/data/variables-from-content.js.map +1 -0
- package/dist/sdk/generated/fragment-types.js +2 -0
- package/dist/sdk/generated/fragment-types.js.map +1 -1
- package/dist/sdk/generated/gql.js +4 -1
- package/dist/sdk/generated/gql.js.map +1 -1
- package/dist/sdk/generated/graphql.d.ts +8 -0
- package/dist/sdk/generated/graphql.js +296 -1
- package/dist/sdk/generated/graphql.js.map +1 -1
- package/dist/sdk/i18n/messages/en-US.js +138 -1
- package/dist/sdk/i18n/messages/en-US.json +138 -1
- package/dist/sdk/i18n/messages/en-US.json.d.ts +137 -0
- package/dist/sdk/i18n/messages/es-ES.js +138 -1
- package/dist/sdk/i18n/messages/es-ES.json +138 -1
- package/dist/sdk/i18n/messages/pt-BR.js +138 -1
- package/dist/sdk/i18n/messages/pt-BR.json +138 -1
- package/dist/sdk/identity/use-identity-actions.js +5 -4
- package/dist/sdk/identity/use-identity-actions.js.map +1 -1
- package/dist/sdk/navigation/current-page.js +30 -0
- package/dist/sdk/navigation/current-page.js.map +1 -0
- package/dist/sdk/navigation/not-found-log.d.ts +28 -0
- package/dist/sdk/navigation/not-found-log.js +133 -0
- package/dist/sdk/navigation/not-found-log.js.map +1 -0
- package/dist/sdk/navigation/path.js +25 -0
- package/dist/sdk/navigation/path.js.map +1 -0
- package/dist/sdk/navigation/redirect.d.ts +11 -0
- package/dist/sdk/navigation/redirect.js +22 -0
- package/dist/sdk/navigation/redirect.js.map +1 -0
- package/dist/sdk/navigation/report.js +70 -0
- package/dist/sdk/navigation/report.js.map +1 -0
- package/dist/sdk/navigation/resolve-storefront-href.d.ts +12 -0
- package/dist/sdk/navigation/resolve-storefront-href.js +214 -0
- package/dist/sdk/navigation/resolve-storefront-href.js.map +1 -0
- package/dist/sdk/navigation/route-identity-provider.d.ts +11 -0
- package/dist/sdk/navigation/route-identity-provider.js +20 -0
- package/dist/sdk/navigation/route-identity-provider.js.map +1 -0
- package/dist/sdk/navigation/route-map-provider.d.ts +19 -0
- package/dist/sdk/navigation/route-map-provider.js +29 -0
- package/dist/sdk/navigation/route-map-provider.js.map +1 -0
- package/dist/sdk/navigation/storefront-link.d.ts +16 -0
- package/dist/sdk/navigation/storefront-link.js +66 -0
- package/dist/sdk/navigation/storefront-link.js.map +1 -0
- package/dist/sdk/navigation/types.d.ts +45 -0
- package/dist/sdk/navigation/use-storefront-navigation.d.ts +26 -0
- package/dist/sdk/navigation/use-storefront-navigation.js +73 -0
- package/dist/sdk/navigation/use-storefront-navigation.js.map +1 -0
- package/dist/sdk/navigation/use-storefront-route.d.ts +26 -0
- package/dist/sdk/navigation/use-storefront-route.js +87 -0
- package/dist/sdk/navigation/use-storefront-route.js.map +1 -0
- package/dist/sdk/navigation/use-storefront-search-params.d.ts +11 -0
- package/dist/sdk/navigation/use-storefront-search-params.js +16 -0
- package/dist/sdk/navigation/use-storefront-search-params.js.map +1 -0
- package/dist/sdk/orders/completion-badge.d.ts +8 -0
- package/dist/sdk/orders/completion-badge.js +47 -0
- package/dist/sdk/orders/completion-badge.js.map +1 -0
- package/dist/sdk/orders/order-operations.d.ts +19 -0
- package/dist/sdk/orders/order-operations.js +21 -0
- package/dist/sdk/orders/order-operations.js.map +1 -0
- package/dist/sdk/orders/use-order-actions.d.ts +23 -0
- package/dist/sdk/orders/use-order-actions.js +62 -0
- package/dist/sdk/orders/use-order-actions.js.map +1 -0
- package/dist/sdk/payment/gateway-origin.js +26 -13
- package/dist/sdk/payment/gateway-origin.js.map +1 -1
- package/dist/sdk/payment/gateway.d.ts +14 -2
- package/dist/sdk/payment/gateway.js +32 -14
- package/dist/sdk/payment/gateway.js.map +1 -1
- package/dist/sdk/payment/operations.js +11 -0
- package/dist/sdk/payment/operations.js.map +1 -1
- package/dist/sdk/payment/submission-registry.d.ts +2 -1
- package/dist/sdk/payment/submission-registry.js +12 -8
- package/dist/sdk/payment/submission-registry.js.map +1 -1
- package/dist/sdk/payment/use-payment-actions.d.ts +5 -3
- package/dist/sdk/payment/use-payment-actions.js +6 -3
- package/dist/sdk/payment/use-payment-actions.js.map +1 -1
- package/dist/sdk/payment/use-place-order.d.ts +6 -3
- package/dist/sdk/payment/use-place-order.js +334 -144
- package/dist/sdk/payment/use-place-order.js.map +1 -1
- package/dist/sdk/region/use-region-actions.js +2 -1
- package/dist/sdk/region/use-region-actions.js.map +1 -1
- package/dist/sdk/seo/page-alternates.d.ts +55 -0
- package/dist/sdk/seo/page-alternates.js +132 -0
- package/dist/sdk/seo/page-alternates.js.map +1 -0
- package/dist/sdk/session/read-server-session.d.ts +21 -0
- package/dist/sdk/session/read-server-session.js +61 -0
- package/dist/sdk/session/read-server-session.js.map +1 -0
- package/dist/sdk/session/use-session-actions.js +5 -4
- package/dist/sdk/session/use-session-actions.js.map +1 -1
- package/dist/sdk/session/use-session-revalidation.js +2 -1
- package/dist/sdk/session/use-session-revalidation.js.map +1 -1
- package/dist/sdk/shipping/use-shipping-actions.js +3 -2
- package/dist/sdk/shipping/use-shipping-actions.js.map +1 -1
- package/dist/utils/own-value.js +19 -0
- package/dist/utils/own-value.js.map +1 -0
- package/dist/utils/safe-href.d.ts +11 -0
- package/dist/utils/safe-href.js +31 -22
- package/dist/utils/safe-href.js.map +1 -1
- package/package.json +17 -2
- package/skills/storefront-asset/SKILL.md +111 -0
- package/skills/storefront-asset/references/api-side.md +153 -0
- package/skills/storefront-asset/references/findings.md +40 -0
- package/skills/storefront-asset/references/ui-side.md +94 -0
- package/src/styles/tailwind.css +27 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"order-progress.js","names":[],"sources":["../../../src/matter/order-progress/order-progress.tsx"],"sourcesContent":["'use client';\n\nimport { type ContentValue, defineComponent, defineContentType } from '@vtex/fs-core';\nimport type { ComponentPropsWithRef, Ref } from 'react';\nimport { useIntl } from '../../sdk/i18n/client.js';\nimport type { MessageId } from '../../sdk/i18n/locales.js';\n\nconst fragment = /* GraphQL */ `\n fragment OrderProgressData on Query {\n customerOrder(id: $orderId) {\n id\n completion {\n view\n label\n }\n progress {\n stage\n paymentFailed\n cancelled\n }\n }\n }\n`;\n\nexport const OrderProgressContent = defineContentType({\n id: 'order-progress',\n title: 'Order Progress',\n description: 'The stage names, the state sentences, and the accessible name of the progress list.',\n schema: {\n type: 'object',\n additionalProperties: false,\n properties: {\n label: { type: 'string', title: 'Accessible name' },\n placed: { type: 'string', title: 'Order placed' },\n payment: { type: 'string', title: 'Payment' },\n processing: { type: 'string', title: 'Processing' },\n shipping: { type: 'string', title: 'Shipping' },\n stateDone: { type: 'string', title: 'Completed' },\n stateCurrent: { type: 'string', title: 'In progress' },\n statePending: { type: 'string', title: 'Not started' },\n },\n },\n});\n\nexport type OrderProgressContentValue = ContentValue<typeof OrderProgressContent>;\n\nexport type OrderProgressStage = 'placed' | 'payment' | 'processing' | 'shipping';\n\nexport type OrderProgressStageState = 'done' | 'current' | 'failed' | 'not-applicable' | 'pending';\n\nexport type OrderProgressLineState = 'done' | 'pending' | 'not-applicable';\n\nexport type OrderProgressOrder = {\n id: string;\n completion: { view: string; label: string };\n progress: { stage: string; paymentFailed: boolean; cancelled: boolean };\n};\n\n/**\n * The `customerOrder` root the generator passes as `$data`. A single-root fragment is bound to\n * that field's value, so this is the order itself, or null when the read resolves nothing.\n */\nexport type OrderProgressData = OrderProgressOrder | null;\n\nexport type OrderProgressProps = Readonly<{\n $data?: OrderProgressData | null;\n $content?: OrderProgressContentValue;\n className?: string;\n ref?: Ref<HTMLOListElement>;\n}>;\n\nconst STAGES = ['placed', 'payment', 'processing', 'shipping'] as const satisfies readonly OrderProgressStage[];\n\nconst STAGE_LABELS: Record<OrderProgressStage, MessageId> = {\n placed: 'fs/order.stage.placed',\n payment: 'fs/order.stage.payment',\n processing: 'fs/order.stage.processing',\n shipping: 'fs/order.stage.shipping',\n};\n\nconst STATE_LABELS: Partial<Record<OrderProgressStageState, MessageId>> = {\n done: 'fs/order.stage-state.done',\n current: 'fs/order.stage-state.current',\n pending: 'fs/order.stage-state.pending',\n};\n\nexport const OrderProgressDefinition = defineComponent<OrderProgressProps>({\n name: 'OrderProgress',\n importPath: '@vtex/faststore/components',\n component: OrderProgress,\n content: OrderProgressContent,\n fragment,\n fetchStrategy: 'static',\n skeleton: OrderProgressSkeleton,\n editor: { label: 'Order Progress', category: 'content' },\n schema: {},\n guideline:\n 'Four stages of one order on the order page: placed, payment, processing, shipping, with a line up to the current one. Stage names and state sentences are content; a blank field keeps the catalogue. Reads the stage the API resolved; style each stage through its state hook.',\n});\n\nfunction authored(value: string | undefined, fallback: string): string {\n const trimmed = value?.trim();\n return trimmed || fallback;\n}\n\nfunction currentStage(value: string): OrderProgressStage {\n switch (value) {\n case 'PAYMENT':\n return 'payment';\n case 'PROCESSING':\n return 'processing';\n case 'SHIPPING':\n return 'shipping';\n default:\n return 'placed';\n }\n}\n\ntype StageModel = {\n stage: OrderProgressStage;\n state: OrderProgressStageState;\n line: OrderProgressLineState | null;\n};\n\nfunction stageState(index: number, current: number, order: OrderProgressOrder): OrderProgressStageState {\n if (order.progress.cancelled) {\n return STAGES[index] === 'payment' ? 'failed' : 'not-applicable';\n }\n if (index < current) {\n return 'done';\n }\n if (index > current) {\n return 'pending';\n }\n if (order.progress.paymentFailed) {\n return 'failed';\n }\n return order.completion.view === 'COMPLETED' ? 'done' : 'current';\n}\n\nfunction lineState(state: OrderProgressStageState, cancelled: boolean): OrderProgressLineState {\n if (cancelled) {\n return 'not-applicable';\n }\n return state === 'pending' ? 'pending' : 'done';\n}\n\nfunction stageModels(order: OrderProgressOrder): StageModel[] {\n const current = STAGES.indexOf(currentStage(order.progress.stage));\n return STAGES.map((stage, index) => {\n const state = stageState(index, current, order);\n return { stage, state, line: index === 0 ? null : lineState(state, order.progress.cancelled) };\n });\n}\n\nexport function OrderProgressSkeleton({ className, ...props }: ComponentPropsWithRef<'div'>) {\n return (\n <div {...props} className={className} data-fs-order-progress-skeleton=\"\" aria-hidden=\"true\">\n {STAGES.map((stage) => (\n <span key={stage} data-fs-order-progress-skeleton-stage=\"\" />\n ))}\n </div>\n );\n}\n\nfunction stageSentence(stage: OrderProgressStage, content: OrderProgressContentValue | undefined): string | undefined {\n switch (stage) {\n case 'placed':\n return content?.placed;\n case 'payment':\n return content?.payment;\n case 'processing':\n return content?.processing;\n case 'shipping':\n return content?.shipping;\n }\n}\n\nfunction stateSentence(\n state: OrderProgressStageState,\n content: OrderProgressContentValue | undefined,\n): string | undefined {\n switch (state) {\n case 'done':\n return content?.stateDone;\n case 'current':\n return content?.stateCurrent;\n case 'pending':\n return content?.statePending;\n default:\n return undefined;\n }\n}\n\nexport function OrderProgress({ $data, $content, className, ref }: OrderProgressProps) {\n const intl = useIntl();\n const order = $data;\n if (!order) {\n return null;\n }\n\n const stages = stageModels(order);\n\n return (\n <ol\n ref={ref}\n aria-label={authored($content?.label, intl.formatMessage({ id: 'fs/order.progress.label' }))}\n className={className}\n data-fs-order-progress=\"\"\n data-fs-order-progress-current={currentStage(order.progress.stage)}\n data-fs-order-progress-cancelled={order.progress.cancelled ? '' : undefined}\n >\n {stages.map(({ stage, state, line }) => {\n const statusLabel = STATE_LABELS[state];\n return (\n <li\n key={stage}\n data-fs-order-progress-stage={stage}\n data-fs-order-progress-stage-state={state}\n aria-current={state === 'current' ? 'step' : undefined}\n >\n <span data-fs-order-progress-track=\"\">\n {line ? (\n <span data-fs-order-progress-line=\"\" data-fs-order-progress-line-state={line} aria-hidden=\"true\" />\n ) : null}\n <span data-fs-order-progress-marker=\"\" aria-hidden=\"true\" />\n </span>\n <span data-fs-order-progress-label=\"\">\n {authored(stageSentence(stage, $content), intl.formatMessage({ id: STAGE_LABELS[stage] }))}\n </span>\n {statusLabel ? (\n <span data-fs-order-progress-status=\"\">\n {authored(stateSentence(state, $content), intl.formatMessage({ id: statusLabel }))}\n </span>\n ) : null}\n </li>\n );\n })}\n </ol>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { ContentValue } from "../../core/dist/define-content-type.js";
|
|
2
|
+
import { ComponentDefinition } from "../../core/dist/define-component.js";
|
|
3
|
+
import "../../core/dist/index.js";
|
|
4
|
+
import { ComponentPropsWithRef, Ref } from "react";
|
|
5
|
+
//#region src/matter/order-summary/order-summary.d.ts
|
|
6
|
+
export declare const OrderSummaryContent: {
|
|
7
|
+
readonly id: "order-summary";
|
|
8
|
+
readonly title: "Order Summary";
|
|
9
|
+
readonly description: "The heading and the labels of the known total lines. An unknown total id keeps the name the API sent.";
|
|
10
|
+
readonly schema: {
|
|
11
|
+
readonly type: "object";
|
|
12
|
+
readonly additionalProperties: false;
|
|
13
|
+
readonly properties: {
|
|
14
|
+
readonly heading: {
|
|
15
|
+
readonly type: "string";
|
|
16
|
+
readonly title: "Heading";
|
|
17
|
+
};
|
|
18
|
+
readonly items: {
|
|
19
|
+
readonly type: "string";
|
|
20
|
+
readonly title: "Items";
|
|
21
|
+
};
|
|
22
|
+
readonly shipping: {
|
|
23
|
+
readonly type: "string";
|
|
24
|
+
readonly title: "Shipping";
|
|
25
|
+
};
|
|
26
|
+
readonly discounts: {
|
|
27
|
+
readonly type: "string";
|
|
28
|
+
readonly title: "Discounts";
|
|
29
|
+
};
|
|
30
|
+
readonly tax: {
|
|
31
|
+
readonly type: "string";
|
|
32
|
+
readonly title: "Tax";
|
|
33
|
+
};
|
|
34
|
+
readonly change: {
|
|
35
|
+
readonly type: "string";
|
|
36
|
+
readonly title: "Change";
|
|
37
|
+
};
|
|
38
|
+
readonly interest: {
|
|
39
|
+
readonly type: "string";
|
|
40
|
+
readonly title: "Interest";
|
|
41
|
+
};
|
|
42
|
+
readonly grandTotal: {
|
|
43
|
+
readonly type: "string";
|
|
44
|
+
readonly title: "Total";
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
export type OrderSummaryContentValue = ContentValue<typeof OrderSummaryContent>;
|
|
50
|
+
export type OrderSummaryMoney = {
|
|
51
|
+
amount: string | number;
|
|
52
|
+
currencyCode: string;
|
|
53
|
+
};
|
|
54
|
+
export type OrderSummaryTotal = {
|
|
55
|
+
id: string;
|
|
56
|
+
name: string;
|
|
57
|
+
value: OrderSummaryMoney;
|
|
58
|
+
};
|
|
59
|
+
export type OrderSummaryData = {
|
|
60
|
+
id: string;
|
|
61
|
+
total: OrderSummaryMoney;
|
|
62
|
+
totals: OrderSummaryTotal[];
|
|
63
|
+
};
|
|
64
|
+
export type OrderSummaryProps = Readonly<{
|
|
65
|
+
/** The `customerOrder` value of the page query. `null` when the read returned no order. */
|
|
66
|
+
$data?: OrderSummaryData | null;
|
|
67
|
+
$content?: OrderSummaryContentValue;
|
|
68
|
+
className?: string;
|
|
69
|
+
ref?: Ref<HTMLElement>;
|
|
70
|
+
}>;
|
|
71
|
+
export declare const OrderSummaryDefinition: ComponentDefinition<Readonly<{
|
|
72
|
+
/** The `customerOrder` value of the page query. `null` when the read returned no order. */
|
|
73
|
+
$data?: OrderSummaryData | null;
|
|
74
|
+
$content?: OrderSummaryContentValue;
|
|
75
|
+
className?: string;
|
|
76
|
+
ref?: Ref<HTMLElement>;
|
|
77
|
+
}>>;
|
|
78
|
+
export declare function OrderSummarySkeleton({ className, ...props }: ComponentPropsWithRef<'div'>): import("react/jsx-runtime").JSX.Element;
|
|
79
|
+
export declare function OrderSummary({ $data, $content, className, ref }: OrderSummaryProps): import("react/jsx-runtime").JSX.Element | null;
|
|
80
|
+
//#endregion
|
|
81
|
+
//# sourceMappingURL=order-summary.d.ts.map
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { defineComponent } from "../../core/dist/define-component.js";
|
|
3
|
+
import { defineContentType } from "../../core/dist/define-content-type.js";
|
|
4
|
+
import "../../core/dist/index.js";
|
|
5
|
+
import { useStorefrontFormatters } from "../../sdk/format/client.js";
|
|
6
|
+
import { useIntl } from "../../sdk/i18n/client.js";
|
|
7
|
+
import { useId } from "react";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
//#region src/matter/order-summary/order-summary.tsx
|
|
10
|
+
const fragment = `
|
|
11
|
+
fragment OrderSummaryData on Query {
|
|
12
|
+
customerOrder(id: $orderId) {
|
|
13
|
+
id
|
|
14
|
+
total {
|
|
15
|
+
amount
|
|
16
|
+
currencyCode
|
|
17
|
+
}
|
|
18
|
+
totals {
|
|
19
|
+
id
|
|
20
|
+
name
|
|
21
|
+
value {
|
|
22
|
+
amount
|
|
23
|
+
currencyCode
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
`;
|
|
29
|
+
const OrderSummaryContent = defineContentType({
|
|
30
|
+
id: "order-summary",
|
|
31
|
+
title: "Order Summary",
|
|
32
|
+
description: "The heading and the labels of the known total lines. An unknown total id keeps the name the API sent.",
|
|
33
|
+
schema: {
|
|
34
|
+
type: "object",
|
|
35
|
+
additionalProperties: false,
|
|
36
|
+
properties: {
|
|
37
|
+
heading: {
|
|
38
|
+
type: "string",
|
|
39
|
+
title: "Heading"
|
|
40
|
+
},
|
|
41
|
+
items: {
|
|
42
|
+
type: "string",
|
|
43
|
+
title: "Items"
|
|
44
|
+
},
|
|
45
|
+
shipping: {
|
|
46
|
+
type: "string",
|
|
47
|
+
title: "Shipping"
|
|
48
|
+
},
|
|
49
|
+
discounts: {
|
|
50
|
+
type: "string",
|
|
51
|
+
title: "Discounts"
|
|
52
|
+
},
|
|
53
|
+
tax: {
|
|
54
|
+
type: "string",
|
|
55
|
+
title: "Tax"
|
|
56
|
+
},
|
|
57
|
+
change: {
|
|
58
|
+
type: "string",
|
|
59
|
+
title: "Change"
|
|
60
|
+
},
|
|
61
|
+
interest: {
|
|
62
|
+
type: "string",
|
|
63
|
+
title: "Interest"
|
|
64
|
+
},
|
|
65
|
+
grandTotal: {
|
|
66
|
+
type: "string",
|
|
67
|
+
title: "Total"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
/** Catalogue labels for the total ids this page knows. Any other id keeps its upstream name. */
|
|
73
|
+
const KNOWN_TOTAL_LABELS = {
|
|
74
|
+
Items: {
|
|
75
|
+
message: "fs/order.totals.items",
|
|
76
|
+
field: "items"
|
|
77
|
+
},
|
|
78
|
+
Shipping: {
|
|
79
|
+
message: "fs/order.totals.shipping",
|
|
80
|
+
field: "shipping"
|
|
81
|
+
},
|
|
82
|
+
Discounts: {
|
|
83
|
+
message: "fs/order.totals.discounts",
|
|
84
|
+
field: "discounts"
|
|
85
|
+
},
|
|
86
|
+
Tax: {
|
|
87
|
+
message: "fs/order.totals.tax",
|
|
88
|
+
field: "tax"
|
|
89
|
+
},
|
|
90
|
+
Change: {
|
|
91
|
+
message: "fs/order.totals.change",
|
|
92
|
+
field: "change"
|
|
93
|
+
},
|
|
94
|
+
Interest: {
|
|
95
|
+
message: "fs/order.totals.interest",
|
|
96
|
+
field: "interest"
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
const OrderSummaryDefinition = defineComponent({
|
|
100
|
+
name: "OrderSummary",
|
|
101
|
+
importPath: "@vtex/faststore/components",
|
|
102
|
+
component: OrderSummary,
|
|
103
|
+
content: OrderSummaryContent,
|
|
104
|
+
fragment,
|
|
105
|
+
fetchStrategy: "static",
|
|
106
|
+
skeleton: OrderSummarySkeleton,
|
|
107
|
+
editor: {
|
|
108
|
+
label: "Order Summary",
|
|
109
|
+
category: "content"
|
|
110
|
+
},
|
|
111
|
+
schema: {},
|
|
112
|
+
guideline: "The total lines of one placed order (items, shipping, discounts, and any other line OMS recorded, zero and negative included) followed by the grand total the API returns. Known labels are content; a blank field keeps the catalogue, and an unknown total id keeps the name the API sent. Place it on the order page; it never adds the lines up itself."
|
|
113
|
+
});
|
|
114
|
+
function authored(value, fallback) {
|
|
115
|
+
return value?.trim() || fallback;
|
|
116
|
+
}
|
|
117
|
+
function moneyAmount(amount) {
|
|
118
|
+
if (typeof amount === "string" && amount.trim() === "") return null;
|
|
119
|
+
const value = typeof amount === "number" ? amount : Number(amount);
|
|
120
|
+
return Number.isFinite(value) ? value : null;
|
|
121
|
+
}
|
|
122
|
+
function lineSign(amount) {
|
|
123
|
+
if (amount == null) return;
|
|
124
|
+
if (amount < 0) return "negative";
|
|
125
|
+
return amount === 0 ? "zero" : "positive";
|
|
126
|
+
}
|
|
127
|
+
function OrderSummarySkeleton({ className, ...props }) {
|
|
128
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
129
|
+
...props,
|
|
130
|
+
className,
|
|
131
|
+
"data-fs-order-summary-skeleton": "",
|
|
132
|
+
"aria-hidden": "true",
|
|
133
|
+
children: [
|
|
134
|
+
/* @__PURE__ */ jsx("span", { "data-fs-order-summary-skeleton-line": "" }),
|
|
135
|
+
/* @__PURE__ */ jsx("span", { "data-fs-order-summary-skeleton-line": "" }),
|
|
136
|
+
/* @__PURE__ */ jsx("span", { "data-fs-order-summary-skeleton-line": "" }),
|
|
137
|
+
/* @__PURE__ */ jsx("span", { "data-fs-order-summary-skeleton-total": "" })
|
|
138
|
+
]
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
function OrderSummary({ $data, $content, className, ref }) {
|
|
142
|
+
const intl = useIntl();
|
|
143
|
+
const headingId = useId();
|
|
144
|
+
const { formatMoney } = useStorefrontFormatters();
|
|
145
|
+
if (!$data) return null;
|
|
146
|
+
const totalAmount = moneyAmount($data.total.amount);
|
|
147
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
148
|
+
ref,
|
|
149
|
+
"aria-labelledby": headingId,
|
|
150
|
+
className,
|
|
151
|
+
"data-fs-order-summary": "",
|
|
152
|
+
children: [/* @__PURE__ */ jsx("h2", {
|
|
153
|
+
id: headingId,
|
|
154
|
+
"data-fs-order-summary-heading": "",
|
|
155
|
+
children: authored($content?.heading, intl.formatMessage({ id: "fs/order.totals.heading" }))
|
|
156
|
+
}), /* @__PURE__ */ jsxs("dl", {
|
|
157
|
+
"data-fs-order-summary-lines": "",
|
|
158
|
+
children: [$data.totals.map((total, index) => {
|
|
159
|
+
const amount = moneyAmount(total.value.amount);
|
|
160
|
+
const known = KNOWN_TOTAL_LABELS[total.id];
|
|
161
|
+
const label = known ? authored($content?.[known.field], intl.formatMessage({ id: known.message })) : total.name;
|
|
162
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
163
|
+
"data-fs-order-summary-line": "",
|
|
164
|
+
"data-fs-order-summary-line-id": total.id,
|
|
165
|
+
"data-fs-order-summary-line-sign": lineSign(amount),
|
|
166
|
+
children: [/* @__PURE__ */ jsx("dt", {
|
|
167
|
+
"data-fs-order-summary-label": "",
|
|
168
|
+
children: label
|
|
169
|
+
}), /* @__PURE__ */ jsx("dd", {
|
|
170
|
+
"data-fs-order-summary-value": "",
|
|
171
|
+
children: amount == null ? null : formatMoney(amount, { currency: total.value.currencyCode })
|
|
172
|
+
})]
|
|
173
|
+
}, `${total.id}-${index}`);
|
|
174
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
175
|
+
"data-fs-order-summary-total": "",
|
|
176
|
+
children: [/* @__PURE__ */ jsx("dt", {
|
|
177
|
+
"data-fs-order-summary-label": "",
|
|
178
|
+
"data-fs-order-summary-total-label": "",
|
|
179
|
+
children: authored($content?.grandTotal, intl.formatMessage({ id: "fs/order.totals.grand-total" }))
|
|
180
|
+
}), /* @__PURE__ */ jsx("dd", {
|
|
181
|
+
"data-fs-order-summary-value": "",
|
|
182
|
+
"data-fs-order-summary-total-value": "",
|
|
183
|
+
children: totalAmount == null ? null : formatMoney(totalAmount, { currency: $data.total.currencyCode })
|
|
184
|
+
})]
|
|
185
|
+
})]
|
|
186
|
+
})]
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
//#endregion
|
|
190
|
+
export { OrderSummary, OrderSummaryContent, OrderSummaryDefinition, OrderSummarySkeleton };
|
|
191
|
+
|
|
192
|
+
//# sourceMappingURL=order-summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"order-summary.js","names":[],"sources":["../../../src/matter/order-summary/order-summary.tsx"],"sourcesContent":["'use client';\n\nimport { type ContentValue, defineComponent, defineContentType } from '@vtex/fs-core';\nimport { type ComponentPropsWithRef, type Ref, useId } from 'react';\nimport { useStorefrontFormatters } from '../../sdk/format/client.js';\nimport { useIntl } from '../../sdk/i18n/client.js';\nimport type { MessageId } from '../../sdk/i18n/locales.js';\n\nconst fragment = /* GraphQL */ `\n fragment OrderSummaryData on Query {\n customerOrder(id: $orderId) {\n id\n total {\n amount\n currencyCode\n }\n totals {\n id\n name\n value {\n amount\n currencyCode\n }\n }\n }\n }\n`;\n\nexport const OrderSummaryContent = defineContentType({\n id: 'order-summary',\n title: 'Order Summary',\n description: 'The heading and the labels of the known total lines. An unknown total id keeps the name the API sent.',\n schema: {\n type: 'object',\n additionalProperties: false,\n properties: {\n heading: { type: 'string', title: 'Heading' },\n items: { type: 'string', title: 'Items' },\n shipping: { type: 'string', title: 'Shipping' },\n discounts: { type: 'string', title: 'Discounts' },\n tax: { type: 'string', title: 'Tax' },\n change: { type: 'string', title: 'Change' },\n interest: { type: 'string', title: 'Interest' },\n grandTotal: { type: 'string', title: 'Total' },\n },\n },\n});\n\nexport type OrderSummaryContentValue = ContentValue<typeof OrderSummaryContent>;\n\nexport type OrderSummaryMoney = { amount: string | number; currencyCode: string };\n\nexport type OrderSummaryTotal = {\n id: string;\n name: string;\n value: OrderSummaryMoney;\n};\n\nexport type OrderSummaryData = {\n id: string;\n total: OrderSummaryMoney;\n totals: OrderSummaryTotal[];\n};\n\nexport type OrderSummaryProps = Readonly<{\n /** The `customerOrder` value of the page query. `null` when the read returned no order. */\n $data?: OrderSummaryData | null;\n $content?: OrderSummaryContentValue;\n className?: string;\n ref?: Ref<HTMLElement>;\n}>;\n\ntype LineSign = 'negative' | 'zero' | 'positive';\n\n/** Catalogue labels for the total ids this page knows. Any other id keeps its upstream name. */\nconst KNOWN_TOTAL_LABELS = {\n Items: { message: 'fs/order.totals.items', field: 'items' },\n Shipping: { message: 'fs/order.totals.shipping', field: 'shipping' },\n Discounts: { message: 'fs/order.totals.discounts', field: 'discounts' },\n Tax: { message: 'fs/order.totals.tax', field: 'tax' },\n Change: { message: 'fs/order.totals.change', field: 'change' },\n Interest: { message: 'fs/order.totals.interest', field: 'interest' },\n} as const satisfies Record<string, { message: MessageId; field: keyof OrderSummaryContentValue }>;\n\nexport const OrderSummaryDefinition = defineComponent<OrderSummaryProps>({\n name: 'OrderSummary',\n importPath: '@vtex/faststore/components',\n component: OrderSummary,\n content: OrderSummaryContent,\n fragment,\n fetchStrategy: 'static',\n skeleton: OrderSummarySkeleton,\n editor: { label: 'Order Summary', category: 'content' },\n schema: {},\n guideline:\n 'The total lines of one placed order (items, shipping, discounts, and any other line OMS recorded, zero and negative included) followed by the grand total the API returns. Known labels are content; a blank field keeps the catalogue, and an unknown total id keeps the name the API sent. Place it on the order page; it never adds the lines up itself.',\n});\n\nfunction authored(value: string | undefined, fallback: string): string {\n const trimmed = value?.trim();\n return trimmed || fallback;\n}\n\nfunction moneyAmount(amount: string | number): number | null {\n // Number('') and Number(' ') are 0, which would print a blank upstream amount as a real zero.\n if (typeof amount === 'string' && amount.trim() === '') {\n return null;\n }\n const value = typeof amount === 'number' ? amount : Number(amount);\n return Number.isFinite(value) ? value : null;\n}\n\nfunction lineSign(amount: number | null): LineSign | undefined {\n if (amount == null) {\n return undefined;\n }\n if (amount < 0) {\n return 'negative';\n }\n return amount === 0 ? 'zero' : 'positive';\n}\n\nexport function OrderSummarySkeleton({ className, ...props }: ComponentPropsWithRef<'div'>) {\n return (\n <div {...props} className={className} data-fs-order-summary-skeleton=\"\" aria-hidden=\"true\">\n <span data-fs-order-summary-skeleton-line=\"\" />\n <span data-fs-order-summary-skeleton-line=\"\" />\n <span data-fs-order-summary-skeleton-line=\"\" />\n <span data-fs-order-summary-skeleton-total=\"\" />\n </div>\n );\n}\n\nexport function OrderSummary({ $data, $content, className, ref }: OrderSummaryProps) {\n const intl = useIntl();\n const headingId = useId();\n const { formatMoney } = useStorefrontFormatters();\n\n if (!$data) {\n return null;\n }\n\n const totalAmount = moneyAmount($data.total.amount);\n\n return (\n <section ref={ref} aria-labelledby={headingId} className={className} data-fs-order-summary=\"\">\n <h2 id={headingId} data-fs-order-summary-heading=\"\">\n {authored($content?.heading, intl.formatMessage({ id: 'fs/order.totals.heading' }))}\n </h2>\n <dl data-fs-order-summary-lines=\"\">\n {$data.totals.map((total, index) => {\n const amount = moneyAmount(total.value.amount);\n const known = KNOWN_TOTAL_LABELS[total.id as keyof typeof KNOWN_TOTAL_LABELS];\n const label = known\n ? authored($content?.[known.field], intl.formatMessage({ id: known.message }))\n : total.name;\n return (\n <div\n key={`${total.id}-${index}`}\n data-fs-order-summary-line=\"\"\n data-fs-order-summary-line-id={total.id}\n data-fs-order-summary-line-sign={lineSign(amount)}\n >\n <dt data-fs-order-summary-label=\"\">{label}</dt>\n <dd data-fs-order-summary-value=\"\">\n {amount == null ? null : formatMoney(amount, { currency: total.value.currencyCode })}\n </dd>\n </div>\n );\n })}\n <div data-fs-order-summary-total=\"\">\n <dt data-fs-order-summary-label=\"\" data-fs-order-summary-total-label=\"\">\n {authored($content?.grandTotal, intl.formatMessage({ id: 'fs/order.totals.grand-total' }))}\n </dt>\n <dd data-fs-order-summary-value=\"\" data-fs-order-summary-total-value=\"\">\n {totalAmount == null ? null : formatMoney(totalAmount, { currency: $data.total.currencyCode })}\n </dd>\n </div>\n </dl>\n </section>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { DocumentType } from "../../particles/document-field/document-field.js";
|
|
2
|
+
import { PaymentSectionCountry, PaymentSectionMethod } from "./use-payment-method-selection.js";
|
|
3
|
+
//#region src/matter/payment/cardholder-document-rule.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Which cardholder document applies (T42, docs/features/credit-card-r2/rfc.md § D17). Two sources, one
|
|
6
|
+
* rule: the *country* decides which document type exists (`resolveCountryDocumentType`), the selected
|
|
7
|
+
* *method* decides whether the shopper is asked and whether the answer is mandatory
|
|
8
|
+
* (`resolveCardholderDocument`). The field, the submit gate and the card capture all read the rule
|
|
9
|
+
* through these two functions, so they cannot disagree. Pure and total.
|
|
10
|
+
*/
|
|
11
|
+
export type CardholderDocumentRule = Readonly<{
|
|
12
|
+
type: DocumentType;
|
|
13
|
+
required: boolean;
|
|
14
|
+
}>;
|
|
15
|
+
/**
|
|
16
|
+
* The document type the store's country asks for, or `null`. Matches `storeCountryCode` against the
|
|
17
|
+
* rows by array search (never an index or `in`, so a prototype key such as `constructor` matches
|
|
18
|
+
* nothing) and returns the first displayable document type this build knows. The table's `required`
|
|
19
|
+
* is read by no one: the method's `documentRequired` owns that half.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveCountryDocumentType({ storeCountryCode, countries }: Readonly<{
|
|
22
|
+
storeCountryCode?: string | null;
|
|
23
|
+
countries?: readonly PaymentSectionCountry[] | null;
|
|
24
|
+
}>): DocumentType | null;
|
|
25
|
+
/**
|
|
26
|
+
* The rule for the selected method under the store's country. `null` (no field, no refusal, nothing
|
|
27
|
+
* sent) when no method is selected, when the method does not ask for a document, or when the country
|
|
28
|
+
* has no document type.
|
|
29
|
+
*/
|
|
30
|
+
export declare function resolveCardholderDocument({ method, countryDocumentType }: Readonly<{
|
|
31
|
+
method: PaymentSectionMethod | null;
|
|
32
|
+
countryDocumentType: DocumentType | null;
|
|
33
|
+
}>): CardholderDocumentRule | null;
|
|
34
|
+
//#endregion
|
|
35
|
+
//# sourceMappingURL=cardholder-document-rule.d.ts.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { documentTypeFromId } from "../../particles/document-field/document-field.js";
|
|
2
|
+
//#region src/matter/payment/cardholder-document-rule.ts
|
|
3
|
+
/**
|
|
4
|
+
* The document type the store's country asks for, or `null`. Matches `storeCountryCode` against the
|
|
5
|
+
* rows by array search (never an index or `in`, so a prototype key such as `constructor` matches
|
|
6
|
+
* nothing) and returns the first displayable document type this build knows. The table's `required`
|
|
7
|
+
* is read by no one: the method's `documentRequired` owns that half.
|
|
8
|
+
*/
|
|
9
|
+
function resolveCountryDocumentType({ storeCountryCode, countries }) {
|
|
10
|
+
if (!storeCountryCode || !countries) return null;
|
|
11
|
+
const row = countries.find((country) => country.countryCode === storeCountryCode);
|
|
12
|
+
if (!row) return null;
|
|
13
|
+
for (const document of row.documents) {
|
|
14
|
+
if (!document.displayable) continue;
|
|
15
|
+
const type = documentTypeFromId(document.type);
|
|
16
|
+
if (type) return type;
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The rule for the selected method under the store's country. `null` (no field, no refusal, nothing
|
|
22
|
+
* sent) when no method is selected, when the method does not ask for a document, or when the country
|
|
23
|
+
* has no document type.
|
|
24
|
+
*/
|
|
25
|
+
function resolveCardholderDocument({ method, countryDocumentType }) {
|
|
26
|
+
if (!method?.validator.documentDisplayable || countryDocumentType === null) return null;
|
|
27
|
+
return {
|
|
28
|
+
type: countryDocumentType,
|
|
29
|
+
required: method.validator.documentRequired
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { resolveCardholderDocument, resolveCountryDocumentType };
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=cardholder-document-rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cardholder-document-rule.js","names":[],"sources":["../../../src/matter/payment/cardholder-document-rule.ts"],"sourcesContent":["import { type DocumentType, documentTypeFromId } from '../../particles/document-field/document-field.js';\nimport type { PaymentSectionCountry, PaymentSectionMethod } from './use-payment-method-selection.js';\n\n/**\n * Which cardholder document applies (T42, docs/features/credit-card-r2/rfc.md § D17). Two sources, one\n * rule: the *country* decides which document type exists (`resolveCountryDocumentType`), the selected\n * *method* decides whether the shopper is asked and whether the answer is mandatory\n * (`resolveCardholderDocument`). The field, the submit gate and the card capture all read the rule\n * through these two functions, so they cannot disagree. Pure and total.\n */\n\nexport type CardholderDocumentRule = Readonly<{ type: DocumentType; required: boolean }>;\n\n/**\n * The document type the store's country asks for, or `null`. Matches `storeCountryCode` against the\n * rows by array search (never an index or `in`, so a prototype key such as `constructor` matches\n * nothing) and returns the first displayable document type this build knows. The table's `required`\n * is read by no one: the method's `documentRequired` owns that half.\n */\nexport function resolveCountryDocumentType({\n storeCountryCode,\n countries,\n}: Readonly<{\n storeCountryCode?: string | null;\n countries?: readonly PaymentSectionCountry[] | null;\n}>): DocumentType | null {\n if (!storeCountryCode || !countries) return null;\n const row = countries.find((country) => country.countryCode === storeCountryCode);\n if (!row) return null;\n for (const document of row.documents) {\n if (!document.displayable) continue;\n const type = documentTypeFromId(document.type);\n if (type) return type;\n }\n return null;\n}\n\n/**\n * The rule for the selected method under the store's country. `null` (no field, no refusal, nothing\n * sent) when no method is selected, when the method does not ask for a document, or when the country\n * has no document type.\n */\nexport function resolveCardholderDocument({\n method,\n countryDocumentType,\n}: Readonly<{\n method: PaymentSectionMethod | null;\n countryDocumentType: DocumentType | null;\n}>): CardholderDocumentRule | null {\n if (!method?.validator.documentDisplayable || countryDocumentType === null) return null;\n return { type: countryDocumentType, required: method.validator.documentRequired };\n}\n"],"mappings":";;;;;;;;AAmBA,SAAgB,2BAA2B,EACzC,kBACA,aAIuB;CACvB,IAAI,CAAC,oBAAoB,CAAC,WAAW,OAAO;CAC5C,MAAM,MAAM,UAAU,MAAM,YAAY,QAAQ,gBAAgB,gBAAgB;CAChF,IAAI,CAAC,KAAK,OAAO;CACjB,KAAK,MAAM,YAAY,IAAI,WAAW;EACpC,IAAI,CAAC,SAAS,aAAa;EAC3B,MAAM,OAAO,mBAAmB,SAAS,IAAI;EAC7C,IAAI,MAAM,OAAO;CACnB;CACA,OAAO;AACT;;;;;;AAOA,SAAgB,0BAA0B,EACxC,QACA,uBAIiC;CACjC,IAAI,CAAC,QAAQ,UAAU,uBAAuB,wBAAwB,MAAM,OAAO;CACnF,OAAO;EAAE,MAAM;EAAqB,UAAU,OAAO,UAAU;CAAiB;AAClF"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { usePaymentSubmission } from "../../sdk/payment/submission-registry.js";
|
|
3
3
|
import { PAYMENT_NETWORK_ERROR_CODE } from "../../sdk/payment/operations.js";
|
|
4
4
|
import { CardCaptureContext } from "../card-entry/card-capture.js";
|
|
5
|
+
import { resolveCardholderDocument } from "./cardholder-document-rule.js";
|
|
5
6
|
import { isCardMethod } from "./use-payment-method-selection.js";
|
|
6
7
|
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef } from "react";
|
|
7
8
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -16,6 +17,35 @@ const MISSING_GATEWAY_ACTION_ERROR = {
|
|
|
16
17
|
code: PAYMENT_NETWORK_ERROR_CODE,
|
|
17
18
|
message: "Unable to complete the request. Please try again."
|
|
18
19
|
};
|
|
20
|
+
/**
|
|
21
|
+
* Folds the draft's non-sensitive values into the captured card and sends it through `sendPayments`.
|
|
22
|
+
* `facts` is `latest.current` read at submission time, never a value a closure captured earlier.
|
|
23
|
+
*/
|
|
24
|
+
async function sendNewCard({ selection, $actions }, transaction, card) {
|
|
25
|
+
const sendPayments = $actions?.payment?.sendPayments;
|
|
26
|
+
if (!sendPayments) {
|
|
27
|
+
console.error("[CardEntry] the payment action namespace is not injected");
|
|
28
|
+
return {
|
|
29
|
+
reachedGateway: false,
|
|
30
|
+
userErrors: [MISSING_GATEWAY_ACTION_ERROR]
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const { draft, allMethods, persistedMethodId, countryDocumentType } = selection;
|
|
34
|
+
const documentRule = resolveCardholderDocument({
|
|
35
|
+
method: allMethods.find((method) => method.id === persistedMethodId) ?? null,
|
|
36
|
+
countryDocumentType
|
|
37
|
+
});
|
|
38
|
+
return sendPayments({
|
|
39
|
+
transaction,
|
|
40
|
+
card: {
|
|
41
|
+
kind: "new",
|
|
42
|
+
...card,
|
|
43
|
+
document: documentRule ? draft.document ?? void 0 : void 0,
|
|
44
|
+
cardLabel: draft.cardLabel ?? void 0,
|
|
45
|
+
saveCard: draft.saveCard ?? void 0
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
19
49
|
function PaymentCardCaptureProvider({ selection, cart, $actions, children }) {
|
|
20
50
|
const { register } = usePaymentSubmission();
|
|
21
51
|
const latest = useRef({
|
|
@@ -57,26 +87,9 @@ function PaymentCardCaptureProvider({ selection, cart, $actions, children }) {
|
|
|
57
87
|
$actions,
|
|
58
88
|
dispatchAddPaymentInfo
|
|
59
89
|
]);
|
|
60
|
-
const registerCapture = useCallback((capture, preflight) => {
|
|
61
|
-
const submit = (transaction) => capture(
|
|
62
|
-
|
|
63
|
-
if (!sendPayments) {
|
|
64
|
-
console.error("[CardEntry] the payment action namespace is not injected");
|
|
65
|
-
return [MISSING_GATEWAY_ACTION_ERROR];
|
|
66
|
-
}
|
|
67
|
-
const { draft } = latest.current.selection;
|
|
68
|
-
return sendPayments({
|
|
69
|
-
transaction,
|
|
70
|
-
card: {
|
|
71
|
-
kind: "new",
|
|
72
|
-
...card,
|
|
73
|
-
document: draft.document ?? void 0,
|
|
74
|
-
cardLabel: draft.cardLabel ?? void 0,
|
|
75
|
-
saveCard: draft.saveCard ?? void 0
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
const unregister = register("new-card", submit, preflight);
|
|
90
|
+
const registerCapture = useCallback((capture, preflight, explainMissingMethod) => {
|
|
91
|
+
const submit = (transaction) => capture((card) => sendNewCard(latest.current, transaction, card));
|
|
92
|
+
const unregister = register("new-card", submit, preflight, explainMissingMethod);
|
|
80
93
|
activeCaptures.current += 1;
|
|
81
94
|
dispatchAddPaymentInfo();
|
|
82
95
|
return () => {
|
|
@@ -84,12 +97,13 @@ function PaymentCardCaptureProvider({ selection, cart, $actions, children }) {
|
|
|
84
97
|
unregister();
|
|
85
98
|
};
|
|
86
99
|
}, [register, dispatchAddPaymentInfo]);
|
|
87
|
-
const { methods, placing, selectMethod, selectNewCard, setDraftBin, draft, cardPaymentCollapsed, cardModeActive, selectedMethodId, selectionOutOfScope, selectedMethod } = selection;
|
|
100
|
+
const { methods, placing, attempt, selectMethod, selectNewCard, setDraftBin, draft, cardPaymentCollapsed, cardModeActive, selectedMethodId, selectionOutOfScope, selectedMethod } = selection;
|
|
101
|
+
const locked = attempt?.phase === "sent" || attempt?.phase === "unresolved";
|
|
88
102
|
const selectionNonCard = selectedMethod !== null && !isCardMethod(selectedMethod);
|
|
89
103
|
const value = useMemo(() => ({
|
|
90
104
|
networks: methods,
|
|
91
|
-
busy: placing,
|
|
92
|
-
clearOn: "
|
|
105
|
+
busy: placing || locked,
|
|
106
|
+
clearOn: "any-outcome",
|
|
93
107
|
registerCapture,
|
|
94
108
|
selection: {
|
|
95
109
|
selectMethod,
|
|
@@ -106,6 +120,7 @@ function PaymentCardCaptureProvider({ selection, cart, $actions, children }) {
|
|
|
106
120
|
}), [
|
|
107
121
|
methods,
|
|
108
122
|
placing,
|
|
123
|
+
locked,
|
|
109
124
|
registerCapture,
|
|
110
125
|
selectMethod,
|
|
111
126
|
selectNewCard,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payment-card-capture.js","names":[],"sources":["../../../src/matter/payment/payment-card-capture.tsx"],"sourcesContent":["'use client';\n\nimport { type ReactNode, useCallback, useEffect, useLayoutEffect, useMemo, useRef } from 'react';\nimport type { ComponentActions } from '../../sdk/actions/types.js';\nimport { PAYMENT_NETWORK_ERROR_CODE, type PaymentUserError } from '../../sdk/payment/operations.js';\nimport { type PaymentSubmission, usePaymentSubmission } from '../../sdk/payment/submission-registry.js';\nimport {\n type CardCapture,\n CardCaptureContext,\n type CardCaptureContextValue,\n type CardCapturePreflight,\n} from '../card-entry/card-capture.js';\nimport { isCardMethod, type PaymentMethodSelection } from './use-payment-method-selection.js';\n\n/**\n * The checkout's `card-capture` provider (specs/sfs-3457-card-entry-card-capture-context.md),\n * rendered by both payment roots inside their `PaymentSubmissionProvider`. It hands `CardEntry` the\n * scoped methods and the selection facts, registers its capture as the `new-card` submission, folds\n * the draft's non-sensitive values into the card, and sends it through `sendPayments`. It also owns\n * `add_payment_info`, which needs the cart total `CardEntry` no longer reads.\n */\n\nexport type PaymentCartData = {\n total?: { amount: number; currencyCode: string } | null;\n} | null;\n\n/** The `add_payment_info` payment type for a card group; `undefined` for any other group (T140). */\nfunction paymentTypeOf(groupName: string | undefined): 'Credit Card' | 'Debit Card' | undefined {\n if (groupName === 'creditCardPaymentGroup') return 'Credit Card';\n if (groupName === 'debitCardPaymentGroup') return 'Debit Card';\n return undefined;\n}\n\n/** Mirrors `usePaymentActions`' own infrastructure-failure code for the same underlying meaning. */\nconst MISSING_GATEWAY_ACTION_ERROR: PaymentUserError = {\n code: PAYMENT_NETWORK_ERROR_CODE,\n message: 'Unable to complete the request. Please try again.',\n};\n\ntype PaymentCardCaptureProviderProps = Readonly<{\n selection: PaymentMethodSelection;\n cart: PaymentCartData | undefined;\n $actions: ComponentActions | undefined;\n children: ReactNode;\n}>;\n\nexport function PaymentCardCaptureProvider({ selection, cart, $actions, children }: PaymentCardCaptureProviderProps) {\n const { register } = usePaymentSubmission();\n // Read at submission and analytics time, never captured by a closure: the place-order sequence must\n // fold the draft as it stands then, and a keystroke must not re-render the section.\n const latest = useRef({ selection, $actions });\n useLayoutEffect(() => {\n latest.current = { selection, $actions };\n });\n\n const total = cart?.total ?? null;\n const totalRef = useRef(total);\n const activeCaptures = useRef(0);\n const analyticsDispatched = useRef(false);\n\n // `add_payment_info` (T2), once per root, when a card capture is mounted and the cart total has\n // resolved. T140, Decision 5: `paymentType` comes from whatever is selected when it fires, and the key\n // is absent otherwise; a later selection never re-fires it.\n const dispatchAddPaymentInfo = useCallback(() => {\n const currentTotal = totalRef.current;\n if (analyticsDispatched.current || activeCaptures.current === 0 || !currentTotal) return;\n const track = latest.current.$actions?.analytics?.track;\n if (!track) return;\n const { methods, selectedMethodId } = latest.current.selection;\n const paymentType = paymentTypeOf(methods.find((method) => method.id === selectedMethodId)?.groupName);\n track({\n name: 'add_payment_info',\n value: { amount: currentTotal.amount, currencyCode: currentTotal.currencyCode },\n // The key itself must be absent when nothing resolves to a known card kind — never a present\n // key holding `undefined` (toEcommercePayload's own doc comment carries the rest of this rule).\n ...(paymentType ? { paymentType } : {}),\n });\n analyticsDispatched.current = true;\n }, []);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: `$actions` re-runs the dispatch when the analytics namespace arrives after the total; the dispatch reads it through `latest`.\n useEffect(() => {\n totalRef.current = total;\n dispatchAddPaymentInfo();\n }, [total, $actions, dispatchAddPaymentInfo]);\n\n const registerCapture = useCallback(\n (capture: CardCapture, preflight: CardCapturePreflight) => {\n const submit: PaymentSubmission = (transaction) =>\n capture(async (card) => {\n const sendPayments = latest.current.$actions?.payment?.sendPayments;\n if (!sendPayments) {\n console.error('[CardEntry] the payment action namespace is not injected');\n return [MISSING_GATEWAY_ACTION_ERROR];\n }\n const { draft } = latest.current.selection;\n return sendPayments({\n transaction,\n card: {\n kind: 'new',\n ...card,\n document: draft.document ?? undefined,\n cardLabel: draft.cardLabel ?? undefined,\n saveCard: draft.saveCard ?? undefined,\n },\n });\n });\n const unregister = register('new-card', submit, preflight);\n activeCaptures.current += 1;\n dispatchAddPaymentInfo();\n return () => {\n activeCaptures.current -= 1;\n unregister();\n };\n },\n [register, dispatchAddPaymentInfo],\n );\n\n const {\n methods,\n placing,\n selectMethod,\n selectNewCard,\n setDraftBin,\n draft,\n cardPaymentCollapsed,\n cardModeActive,\n selectedMethodId,\n selectionOutOfScope,\n selectedMethod,\n } = selection;\n // T191 (FR-13, Decision 8): classified with the engine's own `isCardMethod`, so the card form's\n // refusal and the collapse can never disagree about a method.\n const selectionNonCard = selectedMethod !== null && !isCardMethod(selectedMethod);\n\n const value = useMemo<CardCaptureContextValue>(\n () => ({\n networks: methods,\n busy: placing,\n clearOn: 'success',\n registerCapture,\n selection: {\n selectMethod,\n selectNewCard,\n setDraftBin,\n path: draft.path,\n bin: draft.bin,\n collapsed: cardPaymentCollapsed,\n cardModeActive,\n selectedMethodId,\n selectionOutOfScope,\n selectionNonCard,\n },\n }),\n [\n methods,\n placing,\n registerCapture,\n selectMethod,\n selectNewCard,\n setDraftBin,\n draft.path,\n draft.bin,\n cardPaymentCollapsed,\n cardModeActive,\n selectedMethodId,\n selectionOutOfScope,\n selectionNonCard,\n ],\n );\n\n return <CardCaptureContext value={value}>{children}</CardCaptureContext>;\n}\n"],"mappings":";;;;;;;;;AA2BA,SAAS,cAAc,WAAyE;CAC9F,IAAI,cAAc,0BAA0B,OAAO;CACnD,IAAI,cAAc,yBAAyB,OAAO;AAEpD;;AAGA,MAAM,+BAAiD;CACrD,MAAM;CACN,SAAS;AACX;AASA,SAAgB,2BAA2B,EAAE,WAAW,MAAM,UAAU,YAA6C;CACnH,MAAM,EAAE,aAAa,qBAAqB;CAG1C,MAAM,SAAS,OAAO;EAAE;EAAW;CAAS,CAAC;CAC7C,sBAAsB;EACpB,OAAO,UAAU;GAAE;GAAW;EAAS;CACzC,CAAC;CAED,MAAM,QAAQ,MAAM,SAAS;CAC7B,MAAM,WAAW,OAAO,KAAK;CAC7B,MAAM,iBAAiB,OAAO,CAAC;CAC/B,MAAM,sBAAsB,OAAO,KAAK;CAKxC,MAAM,yBAAyB,kBAAkB;EAC/C,MAAM,eAAe,SAAS;EAC9B,IAAI,oBAAoB,WAAW,eAAe,YAAY,KAAK,CAAC,cAAc;EAClF,MAAM,QAAQ,OAAO,QAAQ,UAAU,WAAW;EAClD,IAAI,CAAC,OAAO;EACZ,MAAM,EAAE,SAAS,qBAAqB,OAAO,QAAQ;EACrD,MAAM,cAAc,cAAc,QAAQ,MAAM,WAAW,OAAO,OAAO,gBAAgB,CAAC,EAAE,SAAS;EACrG,MAAM;GACJ,MAAM;GACN,OAAO;IAAE,QAAQ,aAAa;IAAQ,cAAc,aAAa;GAAa;GAG9E,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;EACvC,CAAC;EACD,oBAAoB,UAAU;CAChC,GAAG,CAAC,CAAC;CAGL,gBAAgB;EACd,SAAS,UAAU;EACnB,uBAAuB;CACzB,GAAG;EAAC;EAAO;EAAU;CAAsB,CAAC;CAE5C,MAAM,kBAAkB,aACrB,SAAsB,cAAoC;EACzD,MAAM,UAA6B,gBACjC,QAAQ,OAAO,SAAS;GACtB,MAAM,eAAe,OAAO,QAAQ,UAAU,SAAS;GACvD,IAAI,CAAC,cAAc;IACjB,QAAQ,MAAM,0DAA0D;IACxE,OAAO,CAAC,4BAA4B;GACtC;GACA,MAAM,EAAE,UAAU,OAAO,QAAQ;GACjC,OAAO,aAAa;IAClB;IACA,MAAM;KACJ,MAAM;KACN,GAAG;KACH,UAAU,MAAM,YAAY,KAAA;KAC5B,WAAW,MAAM,aAAa,KAAA;KAC9B,UAAU,MAAM,YAAY,KAAA;IAC9B;GACF,CAAC;EACH,CAAC;EACH,MAAM,aAAa,SAAS,YAAY,QAAQ,SAAS;EACzD,eAAe,WAAW;EAC1B,uBAAuB;EACvB,aAAa;GACX,eAAe,WAAW;GAC1B,WAAW;EACb;CACF,GACA,CAAC,UAAU,sBAAsB,CACnC;CAEA,MAAM,EACJ,SACA,SACA,cACA,eACA,aACA,OACA,sBACA,gBACA,kBACA,qBACA,mBACE;CAGJ,MAAM,mBAAmB,mBAAmB,QAAQ,CAAC,aAAa,cAAc;CAEhF,MAAM,QAAQ,eACL;EACL,UAAU;EACV,MAAM;EACN,SAAS;EACT;EACA,WAAW;GACT;GACA;GACA;GACA,MAAM,MAAM;GACZ,KAAK,MAAM;GACX,WAAW;GACX;GACA;GACA;GACA;EACF;CACF,IACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA,MAAM;EACN,MAAM;EACN;EACA;EACA;EACA;EACA;CACF,CACF;CAEA,OAAO,oBAAC,oBAAD;EAA2B;EAAQ;CAA6B,CAAA;AACzE"}
|
|
1
|
+
{"version":3,"file":"payment-card-capture.js","names":[],"sources":["../../../src/matter/payment/payment-card-capture.tsx"],"sourcesContent":["'use client';\n\nimport { type ReactNode, useCallback, useEffect, useLayoutEffect, useMemo, useRef } from 'react';\nimport type { ComponentActions } from '../../sdk/actions/types.js';\nimport type { PaymentGatewayTransaction } from '../../sdk/payment/gateway.js';\nimport { PAYMENT_NETWORK_ERROR_CODE, type PaymentUserError } from '../../sdk/payment/operations.js';\nimport { type PaymentSubmission, usePaymentSubmission } from '../../sdk/payment/submission-registry.js';\nimport {\n type CapturedCard,\n type CardCapture,\n CardCaptureContext,\n type CardCaptureContextValue,\n type CardCaptureMissingMethodExplainer,\n type CardCapturePreflight,\n type CardCaptureResult,\n} from '../card-entry/card-capture.js';\nimport { resolveCardholderDocument } from './cardholder-document-rule.js';\nimport { isCardMethod, type PaymentMethodSelection } from './use-payment-method-selection.js';\n\n/**\n * The checkout's `card-capture` provider (specs/sfs-3457-card-entry-card-capture-context.md),\n * rendered by both payment roots inside their `PaymentSubmissionProvider`. It hands `CardEntry` the\n * scoped methods and the selection facts, registers its capture as the `new-card` submission, folds\n * the draft's non-sensitive values into the card, and sends it through `sendPayments`. It also owns\n * `add_payment_info`, which needs the cart total `CardEntry` no longer reads.\n */\n\nexport type PaymentCartData = {\n total?: { amount: number; currencyCode: string } | null;\n} | null;\n\n/** The `add_payment_info` payment type for a card group; `undefined` for any other group (T140). */\nfunction paymentTypeOf(groupName: string | undefined): 'Credit Card' | 'Debit Card' | undefined {\n if (groupName === 'creditCardPaymentGroup') return 'Credit Card';\n if (groupName === 'debitCardPaymentGroup') return 'Debit Card';\n return undefined;\n}\n\n/** Mirrors `usePaymentActions`' own infrastructure-failure code for the same underlying meaning. */\nconst MISSING_GATEWAY_ACTION_ERROR: PaymentUserError = {\n code: PAYMENT_NETWORK_ERROR_CODE,\n message: 'Unable to complete the request. Please try again.',\n};\n\ntype LatestCaptureFacts = Readonly<{ selection: PaymentMethodSelection; $actions: ComponentActions | undefined }>;\n\n/**\n * Folds the draft's non-sensitive values into the captured card and sends it through `sendPayments`.\n * `facts` is `latest.current` read at submission time, never a value a closure captured earlier.\n */\nasync function sendNewCard(\n { selection, $actions }: LatestCaptureFacts,\n transaction: PaymentGatewayTransaction,\n card: CapturedCard,\n): Promise<CardCaptureResult> {\n const sendPayments = $actions?.payment?.sendPayments;\n if (!sendPayments) {\n console.error('[CardEntry] the payment action namespace is not injected');\n // Nothing was sent: no action to send it with (T112).\n return { reachedGateway: false, userErrors: [MISSING_GATEWAY_ACTION_ERROR] };\n }\n const { draft, allMethods, persistedMethodId, countryDocumentType } = selection;\n // T42 (Decision 4): the draft document is posted only while the rule applies — the same unscoped\n // persisted method the submit gate reads, under the store's country — never a stale value.\n const documentRule = resolveCardholderDocument({\n method: allMethods.find((method) => method.id === persistedMethodId) ?? null,\n countryDocumentType,\n });\n return sendPayments({\n transaction,\n card: {\n kind: 'new',\n ...card,\n document: documentRule ? (draft.document ?? undefined) : undefined,\n cardLabel: draft.cardLabel ?? undefined,\n saveCard: draft.saveCard ?? undefined,\n },\n });\n}\n\ntype PaymentCardCaptureProviderProps = Readonly<{\n selection: PaymentMethodSelection;\n cart: PaymentCartData | undefined;\n $actions: ComponentActions | undefined;\n children: ReactNode;\n}>;\n\nexport function PaymentCardCaptureProvider({ selection, cart, $actions, children }: PaymentCardCaptureProviderProps) {\n const { register } = usePaymentSubmission();\n // Read at submission and analytics time, never captured by a closure: the place-order sequence must\n // fold the draft as it stands then, and a keystroke must not re-render the section.\n const latest = useRef({ selection, $actions });\n useLayoutEffect(() => {\n latest.current = { selection, $actions };\n });\n\n const total = cart?.total ?? null;\n const totalRef = useRef(total);\n const activeCaptures = useRef(0);\n const analyticsDispatched = useRef(false);\n\n // `add_payment_info` (T2), once per root, when a card capture is mounted and the cart total has\n // resolved. T140, Decision 5: `paymentType` comes from whatever is selected when it fires, and the key\n // is absent otherwise; a later selection never re-fires it.\n const dispatchAddPaymentInfo = useCallback(() => {\n const currentTotal = totalRef.current;\n if (analyticsDispatched.current || activeCaptures.current === 0 || !currentTotal) return;\n const track = latest.current.$actions?.analytics?.track;\n if (!track) return;\n const { methods, selectedMethodId } = latest.current.selection;\n const paymentType = paymentTypeOf(methods.find((method) => method.id === selectedMethodId)?.groupName);\n track({\n name: 'add_payment_info',\n value: { amount: currentTotal.amount, currencyCode: currentTotal.currencyCode },\n // The key itself must be absent when nothing resolves to a known card kind — never a present\n // key holding `undefined` (toEcommercePayload's own doc comment carries the rest of this rule).\n ...(paymentType ? { paymentType } : {}),\n });\n analyticsDispatched.current = true;\n }, []);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: `$actions` re-runs the dispatch when the analytics namespace arrives after the total; the dispatch reads it through `latest`.\n useEffect(() => {\n totalRef.current = total;\n dispatchAddPaymentInfo();\n }, [total, $actions, dispatchAddPaymentInfo]);\n\n const registerCapture = useCallback(\n (\n capture: CardCapture,\n preflight: CardCapturePreflight,\n explainMissingMethod?: CardCaptureMissingMethodExplainer,\n ) => {\n const submit: PaymentSubmission = (transaction) =>\n capture((card) => sendNewCard(latest.current, transaction, card));\n const unregister = register('new-card', submit, preflight, explainMissingMethod);\n activeCaptures.current += 1;\n dispatchAddPaymentInfo();\n return () => {\n activeCaptures.current -= 1;\n unregister();\n };\n },\n [register, dispatchAddPaymentInfo],\n );\n\n const {\n methods,\n placing,\n attempt,\n selectMethod,\n selectNewCard,\n setDraftBin,\n draft,\n cardPaymentCollapsed,\n cardModeActive,\n selectedMethodId,\n selectionOutOfScope,\n selectedMethod,\n } = selection;\n // T202: `sent` and `unresolved` are the two phases in which `placeOrder` only resumes (the callback leg), so\n // a card typed there would never be submitted and never cleared. The form takes no input until the attempt\n // is freed. Read from the attempt on every render; nothing here writes it.\n const locked = attempt?.phase === 'sent' || attempt?.phase === 'unresolved';\n // T191 (FR-13, Decision 8): classified with the engine's own `isCardMethod`, so the card form's\n // refusal and the collapse can never disagree about a method.\n const selectionNonCard = selectedMethod !== null && !isCardMethod(selectedMethod);\n\n const value = useMemo<CardCaptureContextValue>(\n () => ({\n networks: methods,\n busy: placing || locked,\n // T202: the card POST has settled by any route once `send` returns, so nothing the form holds is needed\n // again (a refusal raised before `send` never reaches the clear).\n clearOn: 'any-outcome',\n registerCapture,\n selection: {\n selectMethod,\n selectNewCard,\n setDraftBin,\n path: draft.path,\n bin: draft.bin,\n collapsed: cardPaymentCollapsed,\n cardModeActive,\n selectedMethodId,\n selectionOutOfScope,\n selectionNonCard,\n },\n }),\n [\n methods,\n placing,\n locked,\n registerCapture,\n selectMethod,\n selectNewCard,\n setDraftBin,\n draft.path,\n draft.bin,\n cardPaymentCollapsed,\n cardModeActive,\n selectedMethodId,\n selectionOutOfScope,\n selectionNonCard,\n ],\n );\n\n return <CardCaptureContext value={value}>{children}</CardCaptureContext>;\n}\n"],"mappings":";;;;;;;;;;AAgCA,SAAS,cAAc,WAAyE;CAC9F,IAAI,cAAc,0BAA0B,OAAO;CACnD,IAAI,cAAc,yBAAyB,OAAO;AAEpD;;AAGA,MAAM,+BAAiD;CACrD,MAAM;CACN,SAAS;AACX;;;;;AAQA,eAAe,YACb,EAAE,WAAW,YACb,aACA,MAC4B;CAC5B,MAAM,eAAe,UAAU,SAAS;CACxC,IAAI,CAAC,cAAc;EACjB,QAAQ,MAAM,0DAA0D;EAExE,OAAO;GAAE,gBAAgB;GAAO,YAAY,CAAC,4BAA4B;EAAE;CAC7E;CACA,MAAM,EAAE,OAAO,YAAY,mBAAmB,wBAAwB;CAGtE,MAAM,eAAe,0BAA0B;EAC7C,QAAQ,WAAW,MAAM,WAAW,OAAO,OAAO,iBAAiB,KAAK;EACxE;CACF,CAAC;CACD,OAAO,aAAa;EAClB;EACA,MAAM;GACJ,MAAM;GACN,GAAG;GACH,UAAU,eAAgB,MAAM,YAAY,KAAA,IAAa,KAAA;GACzD,WAAW,MAAM,aAAa,KAAA;GAC9B,UAAU,MAAM,YAAY,KAAA;EAC9B;CACF,CAAC;AACH;AASA,SAAgB,2BAA2B,EAAE,WAAW,MAAM,UAAU,YAA6C;CACnH,MAAM,EAAE,aAAa,qBAAqB;CAG1C,MAAM,SAAS,OAAO;EAAE;EAAW;CAAS,CAAC;CAC7C,sBAAsB;EACpB,OAAO,UAAU;GAAE;GAAW;EAAS;CACzC,CAAC;CAED,MAAM,QAAQ,MAAM,SAAS;CAC7B,MAAM,WAAW,OAAO,KAAK;CAC7B,MAAM,iBAAiB,OAAO,CAAC;CAC/B,MAAM,sBAAsB,OAAO,KAAK;CAKxC,MAAM,yBAAyB,kBAAkB;EAC/C,MAAM,eAAe,SAAS;EAC9B,IAAI,oBAAoB,WAAW,eAAe,YAAY,KAAK,CAAC,cAAc;EAClF,MAAM,QAAQ,OAAO,QAAQ,UAAU,WAAW;EAClD,IAAI,CAAC,OAAO;EACZ,MAAM,EAAE,SAAS,qBAAqB,OAAO,QAAQ;EACrD,MAAM,cAAc,cAAc,QAAQ,MAAM,WAAW,OAAO,OAAO,gBAAgB,CAAC,EAAE,SAAS;EACrG,MAAM;GACJ,MAAM;GACN,OAAO;IAAE,QAAQ,aAAa;IAAQ,cAAc,aAAa;GAAa;GAG9E,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;EACvC,CAAC;EACD,oBAAoB,UAAU;CAChC,GAAG,CAAC,CAAC;CAGL,gBAAgB;EACd,SAAS,UAAU;EACnB,uBAAuB;CACzB,GAAG;EAAC;EAAO;EAAU;CAAsB,CAAC;CAE5C,MAAM,kBAAkB,aAEpB,SACA,WACA,yBACG;EACH,MAAM,UAA6B,gBACjC,SAAS,SAAS,YAAY,OAAO,SAAS,aAAa,IAAI,CAAC;EAClE,MAAM,aAAa,SAAS,YAAY,QAAQ,WAAW,oBAAoB;EAC/E,eAAe,WAAW;EAC1B,uBAAuB;EACvB,aAAa;GACX,eAAe,WAAW;GAC1B,WAAW;EACb;CACF,GACA,CAAC,UAAU,sBAAsB,CACnC;CAEA,MAAM,EACJ,SACA,SACA,SACA,cACA,eACA,aACA,OACA,sBACA,gBACA,kBACA,qBACA,mBACE;CAIJ,MAAM,SAAS,SAAS,UAAU,UAAU,SAAS,UAAU;CAG/D,MAAM,mBAAmB,mBAAmB,QAAQ,CAAC,aAAa,cAAc;CAEhF,MAAM,QAAQ,eACL;EACL,UAAU;EACV,MAAM,WAAW;EAGjB,SAAS;EACT;EACA,WAAW;GACT;GACA;GACA;GACA,MAAM,MAAM;GACZ,KAAK,MAAM;GACX,WAAW;GACX;GACA;GACA;GACA;EACF;CACF,IACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA,MAAM;EACN,MAAM;EACN;EACA;EACA;EACA;EACA;CACF,CACF;CAEA,OAAO,oBAAC,oBAAD;EAA2B;EAAQ;CAA6B,CAAA;AACzE"}
|
|
@@ -40,6 +40,17 @@ const PaymentSectionControllerDefinition = defineComponent({
|
|
|
40
40
|
selectedMethodId
|
|
41
41
|
selectedAccountId
|
|
42
42
|
selectedBin
|
|
43
|
+
storeCountryCode
|
|
44
|
+
countries {
|
|
45
|
+
__typename
|
|
46
|
+
countryCode
|
|
47
|
+
documents {
|
|
48
|
+
__typename
|
|
49
|
+
type
|
|
50
|
+
displayable
|
|
51
|
+
required
|
|
52
|
+
}
|
|
53
|
+
}
|
|
43
54
|
}
|
|
44
55
|
cart {
|
|
45
56
|
__typename
|
|
@@ -58,6 +69,7 @@ const PaymentSectionControllerDefinition = defineComponent({
|
|
|
58
69
|
analytics: ["track"]
|
|
59
70
|
},
|
|
60
71
|
providesContext: ["payment", "card-capture"],
|
|
72
|
+
hardened: true,
|
|
61
73
|
editor: {
|
|
62
74
|
label: "Payment Section Controller",
|
|
63
75
|
category: "commerce"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payment-controller.js","names":[],"sources":["../../../src/matter/payment/payment-controller.tsx"],"sourcesContent":["'use client';\n\nimport { defineComponent } from '@vtex/fs-core';\nimport { cloneElement, isValidElement, type ReactNode, useMemo, useState } from 'react';\nimport { useActionsOverride } from '../../sdk/actions/actions-override-context.js';\nimport type { ComponentActions } from '../../sdk/actions/types.js';\nimport { useDataOverride } from '../../sdk/data/data-override-context.js';\nimport { PaymentSubmissionProvider } from '../../sdk/payment/submission-registry.js';\nimport {\n DEFAULT_METHOD_GROUP,\n PaymentContext,\n type PaymentContextValue,\n type PaymentSectionRootData,\n} from './payment.js';\nimport { PaymentCardCaptureProvider } from './payment-card-capture.js';\nimport { usePaymentMethodSelection } from './use-payment-method-selection.js';\n\n/**\n * The collapsed payment section (centered modal / slide-in panel) as a state-only controller\n * (specs/payment-section-root.md, T5; docs/features/credit-card/rfc.md § D1). The page composes a raw\n * `DialogRoot` or `DrawerRoot` and each of its particles (`DialogTrigger` / `DialogBackdrop` /\n * `DialogPopup` …) directly as `page.json` nodes, so every part — including the portaled backdrop and\n * popup a descendant selector could not reach — is a swatch-addressable node with zero Tailwind baked\n * into the package, exactly as `DeliveryOptionsController` established.\n *\n * `PaymentSectionController` renders no markup: it runs the shared `usePaymentMethodSelection` engine,\n * holds the open state, provides the same `payment` context `PaymentSectionRoot` does (ADR-0009 matches\n * by contract identifier, so every leaf composes under either with no edit), then injects\n * `open` / `onOpenChange` into its single overlay-`Root` child via `cloneElement` — the same mechanism\n * as `CartOpenOnAdd` and `ShippingAddressSavedAddressDrawerController`.\n *\n * It diverges from `DeliveryOptionsController` in one deliberate way: a successful method selection\n * does **not** close the surface. Picking a delivery option completes that interaction; picking a\n * payment method is the first step of several — the shopper still types a card, picks an installment,\n * and places the order. Closing is therefore the composition's call, through the context's `setOpen`\n * (T14 on a placed order) or a `DrawerClose` / `DialogClose` particle.\n *\n * The trigger holds a static label (`Text`): no component echoes the current choice there, and none is\n * shipped here — `payment.md` documents the same composition.\n */\n\n// Repeats `PaymentSectionData`'s selection set verbatim under its own name. Two definitions cannot\n// share one fragment name in a page query, and the native catalog builder resolves\n// `defineComponent({ fragment })` statically — a value imported from another module is silently\n// dropped from the built catalog. `delivery-options` duplicates for the same reason;\n// `payment.test.tsx` asserts the two sets stay field-for-field identical.\nconst fragment = /* GraphQL */ `\n fragment PaymentSectionControllerData on Query {\n payment {\n __typename\n id\n methods {\n __typename\n id\n name\n groupName\n validator {\n __typename\n numberMask\n numberRegex\n cvvMask\n cvvRegex\n cvvRequired\n expirationRequired\n holderNameRequired\n billingAddressRequired\n documentDisplayable\n documentRequired\n }\n }\n selectedMethodId\n selectedAccountId\n selectedBin\n }\n cart {\n __typename\n id\n total {\n __typename\n amount\n currencyCode\n }\n }\n }\n`;\n\n// The minimal open-state shape the controller injects into its overlay-Root child; both `DialogRoot`\n// and `DrawerRoot` accept it.\ntype OverlayOpenProps = {\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n};\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\nexport type PaymentSectionControllerProps = {\n /**\n * Scopes the method list to a **set** of `PaymentMethod.groupName` values — a method is in scope\n * when its `groupName` is a member (T140, FR-1, Decision 1). A single string is still accepted and\n * scopes to exactly that one group. An empty string scopes nothing.\n */\n group?: string | readonly string[];\n /** Keyed `{ payment, cart }` forwarded by the reactive runtime (arity-2 fragment, ADR-0015). */\n $data?: PaymentSectionRootData;\n /** Compiler-injected action surface; carries `payment.setMethod`, `payment.sendPayments`, and `analytics.track`. */\n $actions?: ComponentActions;\n /** The single overlay `Root` to control — a `DialogRoot` (modal) or `DrawerRoot` (slide-in). */\n children?: ReactNode;\n};\n\n// ---------------------------------------------------------------------------\n// Definition\n// ---------------------------------------------------------------------------\n\nexport const PaymentSectionControllerDefinition = defineComponent<PaymentSectionControllerProps>({\n name: 'PaymentSectionController',\n importPath: '@vtex/faststore/components',\n component: PaymentSectionController,\n fragment,\n fetchStrategy: 'reactive',\n actions: { payment: ['setMethod', 'sendPayments'], analytics: ['track'] },\n providesContext: ['payment', 'card-capture'],\n editor: { label: 'Payment Section Controller', category: 'commerce' },\n schema: {\n // Literal, not `DEFAULT_METHOD_GROUP` — see the same note on `PaymentSectionRootDefinition`.\n // T140, Decision 2/OQ-6: same widened shape as `PaymentSectionRootDefinition` — see its own note.\n group: {\n type: 'array',\n default: ['creditCardPaymentGroup', 'debitCardPaymentGroup'],\n label: 'Payment method group',\n },\n },\n guideline:\n \"State-only controller for a collapsed payment section: wrap a single DialogRoot (centered modal) or DrawerRoot (slide-in) child and it becomes controlled. Renders no markup and bakes no styling — compose the overlay particles (DialogTrigger/DialogPortal/DialogBackdrop/DialogPopup or the Drawer equivalents) directly as page nodes, put a static label (Text) inside the trigger — no component echoes the current choice there, and put PaymentMethodList plus the payment leaves (CardEntry, Installments, SavedCards, PlaceOrder, …) inside the popup. Provides the same 'payment' and 'card-capture' contexts as PaymentSectionRoot, so every leaf composes under either with no change. Unlike the delivery-options controller it does NOT close on a successful selection — picking a method is mid-flow — so close it from a DrawerClose/DialogClose particle or from the leaf that finishes the flow. See payment.md.\",\n // The convention-based `<file-stem>.md` (`payment-controller.md`) does not exist — this component's\n // doc is `payment.md`, shared with PaymentSectionRoot/PaymentMethodList (T25/FR-8).\n docPath: './payment.md',\n});\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\nexport function PaymentSectionController({\n group = DEFAULT_METHOD_GROUP,\n $data: $dataProp,\n $actions: $actionsProp,\n children,\n}: Readonly<PaymentSectionControllerProps>) {\n const $data = useDataOverride($dataProp);\n const $actions = useActionsOverride($actionsProp);\n const selection = usePaymentMethodSelection({ group, $data: $data?.payment ?? null, $actions });\n const [open, setOpen] = useState(false);\n const payment = useMemo<PaymentContextValue>(() => ({ ...selection, open, setOpen }), [selection, open]);\n\n if (!isValidElement<OverlayOpenProps>(children)) {\n return children;\n }\n\n return (\n <PaymentContext value={payment}>\n <PaymentSubmissionProvider path={selection.draft.path}>\n <PaymentCardCaptureProvider selection={selection} cart={$data?.cart} $actions={$actions}>\n {cloneElement(children, { open, onOpenChange: setOpen })}\n </PaymentCardCaptureProvider>\n </PaymentSubmissionProvider>\n </PaymentContext>\n );\n}\n"],"mappings":";;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"payment-controller.js","names":[],"sources":["../../../src/matter/payment/payment-controller.tsx"],"sourcesContent":["'use client';\n\nimport { defineComponent } from '@vtex/fs-core';\nimport { cloneElement, isValidElement, type ReactNode, useMemo, useState } from 'react';\nimport { useActionsOverride } from '../../sdk/actions/actions-override-context.js';\nimport type { ComponentActions } from '../../sdk/actions/types.js';\nimport { useDataOverride } from '../../sdk/data/data-override-context.js';\nimport { PaymentSubmissionProvider } from '../../sdk/payment/submission-registry.js';\nimport {\n DEFAULT_METHOD_GROUP,\n PaymentContext,\n type PaymentContextValue,\n type PaymentSectionRootData,\n} from './payment.js';\nimport { PaymentCardCaptureProvider } from './payment-card-capture.js';\nimport { usePaymentMethodSelection } from './use-payment-method-selection.js';\n\n/**\n * The collapsed payment section (centered modal / slide-in panel) as a state-only controller\n * (specs/payment-section-root.md, T5; docs/features/credit-card/rfc.md § D1). The page composes a raw\n * `DialogRoot` or `DrawerRoot` and each of its particles (`DialogTrigger` / `DialogBackdrop` /\n * `DialogPopup` …) directly as `page.json` nodes, so every part — including the portaled backdrop and\n * popup a descendant selector could not reach — is a swatch-addressable node with zero Tailwind baked\n * into the package, exactly as `DeliveryOptionsController` established.\n *\n * `PaymentSectionController` renders no markup: it runs the shared `usePaymentMethodSelection` engine,\n * holds the open state, provides the same `payment` context `PaymentSectionRoot` does (ADR-0009 matches\n * by contract identifier, so every leaf composes under either with no edit), then injects\n * `open` / `onOpenChange` into its single overlay-`Root` child via `cloneElement` — the same mechanism\n * as `CartOpenOnAdd` and `ShippingAddressSavedAddressDrawerController`.\n *\n * It diverges from `DeliveryOptionsController` in one deliberate way: a successful method selection\n * does **not** close the surface. Picking a delivery option completes that interaction; picking a\n * payment method is the first step of several — the shopper still types a card, picks an installment,\n * and places the order. Closing is therefore the composition's call, through the context's `setOpen`\n * (T14 on a placed order) or a `DrawerClose` / `DialogClose` particle.\n *\n * The trigger holds a static label (`Text`): no component echoes the current choice there, and none is\n * shipped here — `payment.md` documents the same composition.\n */\n\n// Repeats `PaymentSectionData`'s selection set verbatim under its own name. Two definitions cannot\n// share one fragment name in a page query, and the native catalog builder resolves\n// `defineComponent({ fragment })` statically — a value imported from another module is silently\n// dropped from the built catalog. `delivery-options` duplicates for the same reason;\n// `payment.test.tsx` asserts the two sets stay field-for-field identical.\nconst fragment = /* GraphQL */ `\n fragment PaymentSectionControllerData on Query {\n payment {\n __typename\n id\n methods {\n __typename\n id\n name\n groupName\n validator {\n __typename\n numberMask\n numberRegex\n cvvMask\n cvvRegex\n cvvRequired\n expirationRequired\n holderNameRequired\n billingAddressRequired\n documentDisplayable\n documentRequired\n }\n }\n selectedMethodId\n selectedAccountId\n selectedBin\n storeCountryCode\n countries {\n __typename\n countryCode\n documents {\n __typename\n type\n displayable\n required\n }\n }\n }\n cart {\n __typename\n id\n total {\n __typename\n amount\n currencyCode\n }\n }\n }\n`;\n\n// The minimal open-state shape the controller injects into its overlay-Root child; both `DialogRoot`\n// and `DrawerRoot` accept it.\ntype OverlayOpenProps = {\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n};\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\nexport type PaymentSectionControllerProps = {\n /**\n * Scopes the method list to a **set** of `PaymentMethod.groupName` values — a method is in scope\n * when its `groupName` is a member (T140, FR-1, Decision 1). A single string is still accepted and\n * scopes to exactly that one group. An empty string scopes nothing.\n */\n group?: string | readonly string[];\n /** Keyed `{ payment, cart }` forwarded by the reactive runtime (arity-2 fragment, ADR-0015). */\n $data?: PaymentSectionRootData;\n /** Compiler-injected action surface; carries `payment.setMethod`, `payment.sendPayments`, and `analytics.track`. */\n $actions?: ComponentActions;\n /** The single overlay `Root` to control — a `DialogRoot` (modal) or `DrawerRoot` (slide-in). */\n children?: ReactNode;\n};\n\n// ---------------------------------------------------------------------------\n// Definition\n// ---------------------------------------------------------------------------\n\nexport const PaymentSectionControllerDefinition = defineComponent<PaymentSectionControllerProps>({\n name: 'PaymentSectionController',\n importPath: '@vtex/faststore/components',\n component: PaymentSectionController,\n fragment,\n fetchStrategy: 'reactive',\n actions: { payment: ['setMethod', 'sendPayments'], analytics: ['track'] },\n providesContext: ['payment', 'card-capture'],\n hardened: true,\n editor: { label: 'Payment Section Controller', category: 'commerce' },\n schema: {\n // Literal, not `DEFAULT_METHOD_GROUP` — see the same note on `PaymentSectionRootDefinition`.\n // T140, Decision 2/OQ-6: same widened shape as `PaymentSectionRootDefinition` — see its own note.\n group: {\n type: 'array',\n default: ['creditCardPaymentGroup', 'debitCardPaymentGroup'],\n label: 'Payment method group',\n },\n },\n guideline:\n \"State-only controller for a collapsed payment section: wrap a single DialogRoot (centered modal) or DrawerRoot (slide-in) child and it becomes controlled. Renders no markup and bakes no styling — compose the overlay particles (DialogTrigger/DialogPortal/DialogBackdrop/DialogPopup or the Drawer equivalents) directly as page nodes, put a static label (Text) inside the trigger — no component echoes the current choice there, and put PaymentMethodList plus the payment leaves (CardEntry, Installments, SavedCards, PlaceOrder, …) inside the popup. Provides the same 'payment' and 'card-capture' contexts as PaymentSectionRoot, so every leaf composes under either with no change. Unlike the delivery-options controller it does NOT close on a successful selection — picking a method is mid-flow — so close it from a DrawerClose/DialogClose particle or from the leaf that finishes the flow. See payment.md.\",\n // The convention-based `<file-stem>.md` (`payment-controller.md`) does not exist — this component's\n // doc is `payment.md`, shared with PaymentSectionRoot/PaymentMethodList (T25/FR-8).\n docPath: './payment.md',\n});\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\nexport function PaymentSectionController({\n group = DEFAULT_METHOD_GROUP,\n $data: $dataProp,\n $actions: $actionsProp,\n children,\n}: Readonly<PaymentSectionControllerProps>) {\n const $data = useDataOverride($dataProp);\n const $actions = useActionsOverride($actionsProp);\n const selection = usePaymentMethodSelection({ group, $data: $data?.payment ?? null, $actions });\n const [open, setOpen] = useState(false);\n const payment = useMemo<PaymentContextValue>(() => ({ ...selection, open, setOpen }), [selection, open]);\n\n if (!isValidElement<OverlayOpenProps>(children)) {\n return children;\n }\n\n return (\n <PaymentContext value={payment}>\n <PaymentSubmissionProvider path={selection.draft.path}>\n <PaymentCardCaptureProvider selection={selection} cart={$data?.cart} $actions={$actions}>\n {cloneElement(children, { open, onOpenChange: setOpen })}\n </PaymentCardCaptureProvider>\n </PaymentSubmissionProvider>\n </PaymentContext>\n );\n}\n"],"mappings":";;;;;;;;;;;AA+HA,MAAa,qCAAqC,gBAA+C;CAC/F,MAAM;CACN,YAAY;CACZ,WAAW;CACX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CACA,eAAe;CACf,SAAS;EAAE,SAAS,CAAC,aAAa,cAAc;EAAG,WAAW,CAAC,OAAO;CAAE;CACxE,iBAAiB,CAAC,WAAW,cAAc;CAC3C,UAAU;CACV,QAAQ;EAAE,OAAO;EAA8B,UAAU;CAAW;CACpE,QAAQ,EAGN,OAAO;EACL,MAAM;EACN,SAAS,CAAC,0BAA0B,uBAAuB;EAC3D,OAAO;CACT,EACF;CACA,WACE;CAGF,SAAS;AACX,CAAC;AAMD,SAAgB,yBAAyB,EACvC,QAAQ,sBACR,OAAO,WACP,UAAU,cACV,YAC0C;CAC1C,MAAM,QAAQ,gBAAgB,SAAS;CACvC,MAAM,WAAW,mBAAmB,YAAY;CAChD,MAAM,YAAY,0BAA0B;EAAE;EAAO,OAAO,OAAO,WAAW;EAAM;CAAS,CAAC;CAC9F,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CACtC,MAAM,UAAU,eAAoC;EAAE,GAAG;EAAW;EAAM;CAAQ,IAAI,CAAC,WAAW,IAAI,CAAC;CAEvG,IAAI,CAAC,eAAiC,QAAQ,GAC5C,OAAO;CAGT,OACE,oBAAC,gBAAD;EAAgB,OAAO;EACrB,UAAA,oBAAC,2BAAD;GAA2B,MAAM,UAAU,MAAM;GAC/C,UAAA,oBAAC,4BAAD;IAAuC;IAAW,MAAM,OAAO;IAAgB;IAC5E,UAAA,aAAa,UAAU;KAAE;KAAM,cAAc;IAAQ,CAAC;GAC7B,CAAA;EACH,CAAA;CACb,CAAA;AAEpB"}
|