@vtex/faststore 0.0.10 → 0.0.11
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 +42 -0
- package/README.md +0 -1
- package/dist/actions.json +6 -1
- package/dist/catalog.json +789 -1701
- package/dist/cli/index.d.ts +66 -28
- package/dist/cli/index.js +7371 -512
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/server-runtime.js +41 -60
- package/dist/cli/server-runtime.js.map +1 -1
- package/dist/client.d.ts +3 -3
- package/dist/client.js +2 -2
- package/dist/components.d.ts +63 -57
- package/dist/components.js +60 -54
- package/dist/content-types.json +5785 -754
- package/dist/core/dist/define-component.d.ts +1 -1
- package/dist/core/dist/define-content-type.d.ts +50 -2
- package/dist/core/dist/define-content-type.js +107 -3
- package/dist/core/dist/define-content-type.js.map +1 -1
- package/dist/core/dist/index.d.ts +2 -2
- package/dist/docs/access-code-field.md +1 -1
- package/dist/docs/access-code-sign-in.md +126 -77
- package/dist/docs/account-address-book.md +210 -95
- package/dist/docs/account-menu.md +14 -15
- package/dist/docs/account-saved-cards.md +44 -39
- package/dist/docs/alert-dialog.md +3 -1
- package/dist/docs/avatar.md +4 -2
- package/dist/docs/billing-address.md +99 -30
- package/dist/docs/binding-switcher.md +5 -2
- package/dist/docs/buy-button.md +7 -8
- package/dist/docs/card-entry.md +39 -26
- package/dist/docs/card-summary.md +18 -8
- package/dist/docs/cardholder-document.md +5 -3
- package/dist/docs/carousel.md +5 -4
- package/dist/docs/cart-destination.md +39 -26
- package/dist/docs/cart-item.md +29 -14
- package/dist/docs/cart-totalizer.md +7 -5
- package/dist/docs/cart.md +135 -41
- package/dist/docs/challenge-return.md +135 -0
- package/dist/docs/client-preferences-fieldset.md +10 -5
- package/dist/docs/client-preferences.md +31 -8
- package/dist/docs/client-profile-fieldset.md +20 -6
- package/dist/docs/client-profile.md +12 -3
- package/dist/docs/copy-text.md +9 -7
- package/dist/docs/document-field.md +1 -1
- package/dist/docs/email-field.md +2 -1
- package/dist/docs/email-identification.md +12 -2
- package/dist/docs/footer-copyright.md +4 -2
- package/dist/docs/form.md +54 -18
- package/dist/docs/free-shipping-progress.md +6 -5
- package/dist/docs/identity-edit.md +8 -2
- package/dist/docs/identity-summary.md +18 -5
- package/dist/docs/installments.md +46 -32
- package/dist/docs/my-account-profile.md +16 -11
- package/dist/docs/navigation-link.md +5 -3
- package/dist/docs/order-cancel.md +3 -1
- package/dist/docs/order-delivery-address.md +7 -5
- package/dist/docs/order-delivery-group.md +1 -3
- package/dist/docs/order-details-back.md +1 -1
- package/dist/docs/order-details-header.md +1 -4
- package/dist/docs/order-invoice-download.md +60 -0
- package/dist/docs/order-list-row.md +1 -1
- package/dist/docs/order-list-search.md +13 -20
- package/dist/docs/order-list-views.md +11 -17
- package/dist/docs/order-list.md +12 -5
- package/dist/docs/order-payment.md +9 -7
- package/dist/docs/order-placed-date.md +1 -1
- package/dist/docs/order-placed-payment-summary.md +28 -15
- package/dist/docs/order-placed.md +49 -14
- package/dist/docs/order-progress.md +1 -1
- package/dist/docs/order-status-badge.md +20 -9
- package/dist/docs/order-summary.md +2 -2
- package/dist/docs/order-tracking-link.md +58 -0
- package/dist/docs/payment-method-badges.md +30 -4
- package/dist/docs/payment-methods.md +1 -1
- package/dist/docs/payment.md +36 -17
- package/dist/docs/phone-field.md +4 -4
- package/dist/docs/place-order.md +84 -36
- package/dist/docs/postal-code-field.md +3 -1
- package/dist/docs/pricing.md +21 -23
- package/dist/docs/product-gallery.md +19 -20
- package/dist/docs/product-information.md +13 -9
- package/dist/docs/product-list.md +7 -6
- package/dist/docs/product-shelf.md +0 -1
- package/dist/docs/promotion.md +4 -2
- package/dist/docs/region.md +23 -15
- package/dist/docs/save-card.md +7 -6
- package/dist/docs/saved-cards.md +65 -36
- package/dist/docs/shipping-address.md +57 -21
- package/dist/docs/shipping-simulator.md +53 -15
- package/dist/docs/sign-in-disclosure.md +176 -0
- package/dist/docs/sign-in-form.md +78 -47
- package/dist/docs/sign-in-redirect.md +4 -2
- package/dist/docs/sign-in.md +173 -0
- package/dist/docs/toast.md +15 -4
- package/dist/docs/variant-selector.md +15 -11
- package/dist/graphql/types.d.ts +4 -14
- package/dist/index.d.ts +2 -2
- package/dist/internal/client.d.ts +1 -3
- package/dist/internal/client.js +1 -1
- package/dist/internal/server.d.ts +7 -4
- package/dist/internal/server.js +7 -4
- package/dist/matter/access-code-sign-in/access-code-sign-in.d.ts +250 -66
- package/dist/matter/access-code-sign-in/access-code-sign-in.js +459 -188
- package/dist/matter/access-code-sign-in/access-code-sign-in.js.map +1 -1
- package/dist/matter/account-address-book/account-address-book-delete.d.ts +78 -40
- package/dist/matter/account-address-book/account-address-book-delete.js +86 -50
- package/dist/matter/account-address-book/account-address-book-delete.js.map +1 -1
- package/dist/matter/account-address-book/account-address-book-deliverability.d.ts +21 -4
- package/dist/matter/account-address-book/account-address-book-deliverability.js +45 -17
- package/dist/matter/account-address-book/account-address-book-deliverability.js.map +1 -1
- package/dist/matter/account-address-book/account-address-book-form-parts.d.ts +74 -19
- package/dist/matter/account-address-book/account-address-book-form-parts.js +77 -26
- package/dist/matter/account-address-book/account-address-book-form-parts.js.map +1 -1
- package/dist/matter/account-address-book/account-address-book-profile-notice.d.ts +27 -6
- package/dist/matter/account-address-book/account-address-book-profile-notice.js +55 -28
- package/dist/matter/account-address-book/account-address-book-profile-notice.js.map +1 -1
- package/dist/matter/account-address-book/account-address-book.d.ts +67 -14
- package/dist/matter/account-address-book/account-address-book.js +74 -33
- package/dist/matter/account-address-book/account-address-book.js.map +1 -1
- package/dist/matter/account-address-book/account-address-country-switch.js +3 -3
- package/dist/matter/account-address-book/account-address-country-switch.js.map +1 -1
- package/dist/matter/account-address-book/account-address-country.d.ts +66 -20
- package/dist/matter/account-address-book/account-address-country.js +83 -49
- package/dist/matter/account-address-book/account-address-country.js.map +1 -1
- package/dist/matter/account-address-book/account-address-form-context.d.ts +8 -4
- package/dist/matter/account-address-book/account-address-form-context.js.map +1 -1
- package/dist/matter/account-address-book/account-address-form.d.ts +468 -45
- package/dist/matter/account-address-book/account-address-form.js +518 -155
- package/dist/matter/account-address-book/account-address-form.js.map +1 -1
- package/dist/matter/account-address-book/account-address-record.d.ts +27 -6
- package/dist/matter/account-address-book/account-address-record.js +32 -17
- package/dist/matter/account-address-book/account-address-record.js.map +1 -1
- package/dist/matter/account-menu/account-menu.d.ts +34 -17
- package/dist/matter/account-menu/account-menu.js +46 -54
- package/dist/matter/account-menu/account-menu.js.map +1 -1
- package/dist/matter/account-menu-identity/account-menu-identity.js +1 -1
- package/dist/matter/account-saved-cards/account-saved-cards.d.ts +108 -28
- package/dist/matter/account-saved-cards/account-saved-cards.js +177 -122
- package/dist/matter/account-saved-cards/account-saved-cards.js.map +1 -1
- package/dist/matter/billing-address/billing-address.d.ts +156 -74
- package/dist/matter/billing-address/billing-address.js +227 -156
- package/dist/matter/billing-address/billing-address.js.map +1 -1
- package/dist/matter/breadcrumb/breadcrumb.d.ts +21 -3
- package/dist/matter/breadcrumb/breadcrumb.js +24 -9
- package/dist/matter/breadcrumb/breadcrumb.js.map +1 -1
- package/dist/matter/buy-button/buy-button.d.ts +8 -11
- package/dist/matter/buy-button/buy-button.js +10 -19
- package/dist/matter/buy-button/buy-button.js.map +1 -1
- package/dist/matter/card-entry/card-capture.js +12 -4
- package/dist/matter/card-entry/card-capture.js.map +1 -1
- package/dist/matter/card-entry/card-entry.d.ts +123 -32
- package/dist/matter/card-entry/card-entry.js +348 -221
- package/dist/matter/card-entry/card-entry.js.map +1 -1
- package/dist/matter/cart/cart-namespace.d.ts +7 -1
- package/dist/matter/cart/cart-namespace.js +7 -1
- package/dist/matter/cart/cart-namespace.js.map +1 -1
- package/dist/matter/cart/cart.d.ts +402 -61
- package/dist/matter/cart/cart.js +624 -153
- package/dist/matter/cart/cart.js.map +1 -1
- package/dist/matter/cart-destination/cart-destination.d.ts +30 -19
- package/dist/matter/cart-destination/cart-destination.js +160 -70
- package/dist/matter/cart-destination/cart-destination.js.map +1 -1
- package/dist/matter/cart-item/cart-item.d.ts +144 -17
- package/dist/matter/cart-item/cart-item.js +166 -49
- package/dist/matter/cart-item/cart-item.js.map +1 -1
- package/dist/matter/cart-item-compositions/cart-item-compositions.js +1 -1
- package/dist/matter/cart-item-compositions/cart-item-compositions.js.map +1 -1
- package/dist/matter/cart-item-customizations/cart-item-customizations.js +1 -1
- package/dist/matter/cart-item-customizations/cart-item-customizations.js.map +1 -1
- package/dist/matter/cart-item-discounts/cart-item-discounts.js +1 -1
- package/dist/matter/cart-item-discounts/cart-item-discounts.js.map +1 -1
- package/dist/matter/cart-item-seller-info/cart-item-seller-info.js +1 -1
- package/dist/matter/cart-item-seller-info/cart-item-seller-info.js.map +1 -1
- package/dist/matter/cart-item-variations/cart-item-variations.js +1 -1
- package/dist/matter/cart-item-variations/cart-item-variations.js.map +1 -1
- package/dist/matter/cart-totalizer/cart-totalizer.d.ts +43 -9
- package/dist/matter/cart-totalizer/cart-totalizer.js +46 -17
- package/dist/matter/cart-totalizer/cart-totalizer.js.map +1 -1
- package/dist/matter/challenge-return/challenge-return.d.ts +62 -0
- package/dist/matter/challenge-return/challenge-return.js +241 -0
- package/dist/matter/challenge-return/challenge-return.js.map +1 -0
- package/dist/matter/client-preferences/client-preferences-fieldset.d.ts +86 -17
- package/dist/matter/client-preferences/client-preferences-fieldset.js +126 -54
- package/dist/matter/client-preferences/client-preferences-fieldset.js.map +1 -1
- package/dist/matter/client-preferences/client-preferences.d.ts +50 -7
- package/dist/matter/client-preferences/client-preferences.js +84 -15
- package/dist/matter/client-preferences/client-preferences.js.map +1 -1
- package/dist/matter/client-profile/client-profile.d.ts +44 -9
- package/dist/matter/client-profile/client-profile.js +64 -24
- package/dist/matter/client-profile/client-profile.js.map +1 -1
- package/dist/matter/client-profile-form/client-profile-fieldset.d.ts +119 -22
- package/dist/matter/client-profile-form/client-profile-fieldset.js +161 -73
- package/dist/matter/client-profile-form/client-profile-fieldset.js.map +1 -1
- package/dist/matter/delivery-options/delivery-options-accordion.d.ts +49 -4
- package/dist/matter/delivery-options/delivery-options-accordion.js +67 -14
- package/dist/matter/delivery-options/delivery-options-accordion.js.map +1 -1
- package/dist/matter/delivery-options/delivery-options-controller.d.ts +69 -9
- package/dist/matter/delivery-options/delivery-options-controller.js +80 -14
- package/dist/matter/delivery-options/delivery-options-controller.js.map +1 -1
- package/dist/matter/delivery-options/delivery-options.d.ts +37 -2
- package/dist/matter/delivery-options/delivery-options.js +75 -12
- package/dist/matter/delivery-options/delivery-options.js.map +1 -1
- package/dist/matter/delivery-options/use-delivery-option-selection.d.ts +1 -0
- package/dist/matter/delivery-options/use-delivery-option-selection.js +1 -1
- package/dist/matter/delivery-options/use-delivery-option-selection.js.map +1 -1
- package/dist/matter/email-identification/email-identification.d.ts +25 -3
- package/dist/matter/email-identification/email-identification.js +49 -12
- package/dist/matter/email-identification/email-identification.js.map +1 -1
- package/dist/matter/free-shipping-progress/free-shipping-progress.d.ts +79 -7
- package/dist/matter/free-shipping-progress/free-shipping-progress.js +77 -20
- package/dist/matter/free-shipping-progress/free-shipping-progress.js.map +1 -1
- package/dist/matter/identity-edit/identity-edit.d.ts +52 -10
- package/dist/matter/identity-edit/identity-edit.js +47 -19
- package/dist/matter/identity-edit/identity-edit.js.map +1 -1
- package/dist/matter/identity-summary/identity-summary.d.ts +76 -22
- package/dist/matter/identity-summary/identity-summary.js +95 -45
- package/dist/matter/identity-summary/identity-summary.js.map +1 -1
- package/dist/matter/installments/installments-select.d.ts +98 -16
- package/dist/matter/installments/installments-select.js +156 -48
- package/dist/matter/installments/installments-select.js.map +1 -1
- package/dist/matter/installments/installments.d.ts +96 -16
- package/dist/matter/installments/installments.js +115 -40
- package/dist/matter/installments/installments.js.map +1 -1
- package/dist/matter/installments/use-installments-selection.d.ts +1 -0
- package/dist/matter/installments/use-installments-selection.js +8 -3
- package/dist/matter/installments/use-installments-selection.js.map +1 -1
- package/dist/matter/my-account-profile/my-account-profile.d.ts +358 -103
- package/dist/matter/my-account-profile/my-account-profile.js +370 -174
- package/dist/matter/my-account-profile/my-account-profile.js.map +1 -1
- package/dist/matter/order-cancel/order-cancel.d.ts +65 -19
- package/dist/matter/order-cancel/order-cancel.js +118 -51
- package/dist/matter/order-cancel/order-cancel.js.map +1 -1
- package/dist/matter/order-delivery-address/order-delivery-address.d.ts +8 -18
- package/dist/matter/order-delivery-address/order-delivery-address.js +14 -23
- package/dist/matter/order-delivery-address/order-delivery-address.js.map +1 -1
- package/dist/matter/order-delivery-group/order-delivery-group.d.ts +40 -24
- package/dist/matter/order-delivery-group/order-delivery-group.js +64 -74
- package/dist/matter/order-delivery-group/order-delivery-group.js.map +1 -1
- package/dist/matter/order-details-header/order-details-header.d.ts +32 -15
- package/dist/matter/order-details-header/order-details-header.js +66 -58
- package/dist/matter/order-details-header/order-details-header.js.map +1 -1
- package/dist/matter/order-invoice-download/order-invoice-download.d.ts +78 -0
- package/dist/matter/order-invoice-download/order-invoice-download.js +173 -0
- package/dist/matter/order-invoice-download/order-invoice-download.js.map +1 -0
- package/dist/matter/order-list/order-list.d.ts +164 -19
- package/dist/matter/order-list/order-list.js +229 -87
- package/dist/matter/order-list/order-list.js.map +1 -1
- package/dist/matter/order-list-row/order-list-row.d.ts +6 -1
- package/dist/matter/order-list-row/order-list-row.js +3 -2
- package/dist/matter/order-list-row/order-list-row.js.map +1 -1
- package/dist/matter/order-list-search/order-list-search.d.ts +18 -26
- package/dist/matter/order-list-search/order-list-search.js +30 -69
- package/dist/matter/order-list-search/order-list-search.js.map +1 -1
- package/dist/matter/order-list-views/order-list-views.d.ts +15 -22
- package/dist/matter/order-list-views/order-list-views.js +22 -68
- package/dist/matter/order-list-views/order-list-views.js.map +1 -1
- package/dist/matter/order-payment/order-payment.d.ts +33 -10
- package/dist/matter/order-payment/order-payment.js +44 -39
- package/dist/matter/order-payment/order-payment.js.map +1 -1
- package/dist/matter/order-placed/order-placed-deliveries.d.ts +144 -12
- package/dist/matter/order-placed/order-placed-deliveries.js +115 -40
- package/dist/matter/order-placed/order-placed-deliveries.js.map +1 -1
- package/dist/matter/order-placed/order-placed.d.ts +198 -31
- package/dist/matter/order-placed/order-placed.js +230 -139
- package/dist/matter/order-placed/order-placed.js.map +1 -1
- package/dist/matter/order-placed-date/order-placed-date.d.ts +5 -8
- package/dist/matter/order-placed-date/order-placed-date.js +7 -8
- package/dist/matter/order-placed-date/order-placed-date.js.map +1 -1
- package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.d.ts +90 -17
- package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js +93 -117
- package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js.map +1 -1
- package/dist/matter/order-progress/order-progress.d.ts +19 -8
- package/dist/matter/order-progress/order-progress.js +37 -45
- package/dist/matter/order-progress/order-progress.js.map +1 -1
- package/dist/matter/order-summary/order-summary.d.ts +19 -9
- package/dist/matter/order-summary/order-summary.js +38 -44
- package/dist/matter/order-summary/order-summary.js.map +1 -1
- package/dist/matter/order-tracking-link/order-tracking-link.d.ts +43 -0
- package/dist/matter/order-tracking-link/order-tracking-link.js +107 -0
- package/dist/matter/order-tracking-link/order-tracking-link.js.map +1 -0
- package/dist/matter/payment/payment-card-capture.js +17 -10
- package/dist/matter/payment/payment-card-capture.js.map +1 -1
- package/dist/matter/payment/payment-controller.d.ts +4 -2
- package/dist/matter/payment/payment-controller.js +30 -9
- package/dist/matter/payment/payment-controller.js.map +1 -1
- package/dist/matter/payment/payment-method-badges.js +1 -1
- package/dist/matter/payment/payment.d.ts +69 -19
- package/dist/matter/payment/payment.js +101 -35
- package/dist/matter/payment/payment.js.map +1 -1
- package/dist/matter/payment/use-payment-method-selection.d.ts +25 -4
- package/dist/matter/payment/use-payment-method-selection.js +94 -32
- package/dist/matter/payment/use-payment-method-selection.js.map +1 -1
- package/dist/matter/payment/use-payment-submit-gate.d.ts +14 -3
- package/dist/matter/payment/use-payment-submit-gate.js +47 -8
- package/dist/matter/payment/use-payment-submit-gate.js.map +1 -1
- package/dist/matter/place-order/place-order.d.ts +171 -57
- package/dist/matter/place-order/place-order.js +376 -185
- package/dist/matter/place-order/place-order.js.map +1 -1
- package/dist/matter/pricing/pricing.d.ts +152 -13
- package/dist/matter/pricing/pricing.js +153 -52
- package/dist/matter/pricing/pricing.js.map +1 -1
- package/dist/matter/product-information/product-information.d.ts +27 -4
- package/dist/matter/product-information/product-information.js +32 -15
- package/dist/matter/product-information/product-information.js.map +1 -1
- package/dist/matter/product-list/product-list.d.ts +24 -6
- package/dist/matter/product-list/product-list.js +32 -26
- package/dist/matter/product-list/product-list.js.map +1 -1
- package/dist/matter/product-shelf/product-shelf.d.ts +1 -3
- package/dist/matter/product-shelf/product-shelf.js +2 -15
- package/dist/matter/product-shelf/product-shelf.js.map +1 -1
- package/dist/matter/region/region.d.ts +33 -16
- package/dist/matter/region/region.js +59 -52
- package/dist/matter/region/region.js.map +1 -1
- package/dist/matter/save-card/save-card.d.ts +43 -8
- package/dist/matter/save-card/save-card.js +61 -23
- package/dist/matter/save-card/save-card.js.map +1 -1
- package/dist/matter/saved-cards/saved-cards.d.ts +113 -21
- package/dist/matter/saved-cards/saved-cards.js +349 -77
- package/dist/matter/saved-cards/saved-cards.js.map +1 -1
- package/dist/matter/shipping-address/address-payload.js +25 -0
- package/dist/matter/shipping-address/address-payload.js.map +1 -0
- package/dist/matter/shipping-address/country-descriptors.js +71 -71
- package/dist/matter/shipping-address/country-descriptors.js.map +1 -1
- package/dist/matter/shipping-address/library-country-descriptors.js +136 -0
- package/dist/matter/shipping-address/library-country-descriptors.js.map +1 -0
- package/dist/matter/shipping-address/shipping-address.d.ts +312 -45
- package/dist/matter/shipping-address/shipping-address.js +443 -188
- package/dist/matter/shipping-address/shipping-address.js.map +1 -1
- package/dist/matter/shipping-simulator/shipping-simulator.d.ts +250 -24
- package/dist/matter/shipping-simulator/shipping-simulator.js +257 -51
- package/dist/matter/shipping-simulator/shipping-simulator.js.map +1 -1
- package/dist/matter/sign-in/sign-in.d.ts +108 -0
- package/dist/matter/sign-in/sign-in.js +285 -0
- package/dist/matter/sign-in/sign-in.js.map +1 -0
- package/dist/matter/sign-in-disclosure/sign-in-disclosure.d.ts +81 -0
- package/dist/matter/sign-in-disclosure/sign-in-disclosure.js +232 -0
- package/dist/matter/sign-in-disclosure/sign-in-disclosure.js.map +1 -0
- package/dist/matter/sign-in-form/sign-in-form.d.ts +93 -62
- package/dist/matter/sign-in-form/sign-in-form.js +134 -144
- package/dist/matter/sign-in-form/sign-in-form.js.map +1 -1
- package/dist/particles/binding-switcher/binding-switcher.d.ts +29 -8
- package/dist/particles/binding-switcher/binding-switcher.js +37 -26
- package/dist/particles/binding-switcher/binding-switcher.js.map +1 -1
- package/dist/particles/card-summary/card-summary.d.ts +38 -8
- package/dist/particles/card-summary/card-summary.js +55 -22
- package/dist/particles/card-summary/card-summary.js.map +1 -1
- package/dist/particles/carousel/carousel.d.ts +99 -11
- package/dist/particles/carousel/carousel.js +103 -35
- package/dist/particles/carousel/carousel.js.map +1 -1
- package/dist/particles/copy-text/copy-text.js +5 -15
- package/dist/particles/copy-text/copy-text.js.map +1 -1
- package/dist/particles/dialog/dialog.d.ts +14 -6
- package/dist/particles/dialog/dialog.js +6 -3
- package/dist/particles/dialog/dialog.js.map +1 -1
- package/dist/particles/drawer/drawer.js +1 -1
- package/dist/particles/drawer/drawer.js.map +1 -1
- package/dist/particles/email-field/email-field.d.ts +2 -1
- package/dist/particles/email-field/email-field.js +2 -1
- package/dist/particles/email-field/email-field.js.map +1 -1
- package/dist/particles/footer-link-group/footer-link-group.js +1 -0
- package/dist/particles/footer-link-group/footer-link-group.js.map +1 -1
- package/dist/particles/form/form.d.ts +85 -13
- package/dist/particles/form/form.js +91 -42
- package/dist/particles/form/form.js.map +1 -1
- package/dist/particles/gallery/gallery.d.ts +129 -12
- package/dist/particles/gallery/gallery.js +121 -34
- package/dist/particles/gallery/gallery.js.map +1 -1
- package/dist/particles/order-details-back/order-details-back.d.ts +5 -3
- package/dist/particles/order-details-back/order-details-back.js +8 -10
- package/dist/particles/order-details-back/order-details-back.js.map +1 -1
- package/dist/particles/order-status-badge/order-status-badge.d.ts +3 -3
- package/dist/particles/order-status-badge/order-status-badge.js +4 -20
- package/dist/particles/order-status-badge/order-status-badge.js.map +1 -1
- package/dist/particles/password-field/password-field.d.ts +1 -1
- package/dist/particles/password-field/password-field.js +2 -4
- package/dist/particles/password-field/password-field.js.map +1 -1
- package/dist/particles/phone-field/phone-field.d.ts +4 -4
- package/dist/particles/phone-field/phone-field.js +8 -11
- package/dist/particles/phone-field/phone-field.js.map +1 -1
- package/dist/particles/spinner/spinner.d.ts +24 -4
- package/dist/particles/spinner/spinner.js +25 -9
- package/dist/particles/spinner/spinner.js.map +1 -1
- package/dist/particles/switch/switch.d.ts +4 -1
- package/dist/particles/switch/switch.js +3 -1
- package/dist/particles/switch/switch.js.map +1 -1
- package/dist/particles/toast/toast.d.ts +29 -3
- package/dist/particles/toast/toast.js +34 -10
- package/dist/particles/toast/toast.js.map +1 -1
- package/dist/schema.graphql +164 -56
- package/dist/sdk/address/address-fields.js +4 -4
- package/dist/sdk/address/address-fields.js.map +1 -1
- package/dist/sdk/address/constants.js +1 -6
- package/dist/sdk/address/constants.js.map +1 -1
- package/dist/sdk/address/messages.js +44 -44
- package/dist/sdk/address/messages.js.map +1 -1
- package/dist/sdk/address/postal-code.js +15 -2
- package/dist/sdk/address/postal-code.js.map +1 -1
- package/dist/sdk/address/types.d.ts +5 -3
- package/dist/sdk/address/validate-address.js +3 -3
- package/dist/sdk/address/validate-address.js.map +1 -1
- package/dist/sdk/analytics/use-analytics-actions.d.ts +1 -1
- package/dist/sdk/analytics/use-analytics-actions.js.map +1 -1
- package/dist/sdk/cart/use-cart-actions.js.map +1 -1
- package/dist/sdk/data/index.js +2 -2
- package/dist/sdk/data/reactive-list-item-data-provider.js +2 -2
- package/dist/sdk/generated/gql.js +1 -1
- package/dist/sdk/generated/gql.js.map +1 -1
- package/dist/sdk/generated/graphql.d.ts +20 -5
- package/dist/sdk/generated/graphql.js +6 -0
- package/dist/sdk/generated/graphql.js.map +1 -1
- package/dist/sdk/i18n/format-error-code.js +23 -0
- package/dist/sdk/i18n/format-error-code.js.map +1 -0
- package/dist/sdk/i18n/message-formatter.d.ts +22 -0
- package/dist/sdk/i18n/message-formatter.js +140 -0
- package/dist/sdk/i18n/message-formatter.js.map +1 -0
- package/dist/sdk/i18n/use-message-formatter.d.ts +8 -0
- package/dist/sdk/i18n/use-message-formatter.js +18 -0
- package/dist/sdk/i18n/use-message-formatter.js.map +1 -0
- package/dist/sdk/identity/use-identity-actions.js.map +1 -1
- package/dist/sdk/navigation/redirect.d.ts +2 -0
- package/dist/sdk/navigation/redirect.js +19 -1
- package/dist/sdk/navigation/redirect.js.map +1 -1
- package/dist/sdk/navigation/types.d.ts +13 -0
- package/dist/sdk/payment/bin-format.js +20 -0
- package/dist/sdk/payment/bin-format.js.map +1 -0
- package/dist/sdk/payment/challenge-return.js +37 -0
- package/dist/sdk/payment/challenge-return.js.map +1 -0
- package/dist/sdk/payment/confirmation-last-four.js +39 -0
- package/dist/sdk/payment/confirmation-last-four.js.map +1 -0
- package/dist/sdk/payment/gateway.d.ts +1 -1
- package/dist/sdk/payment/gateway.js +8 -2
- package/dist/sdk/payment/gateway.js.map +1 -1
- package/dist/sdk/payment/operations.d.ts +1 -0
- package/dist/sdk/payment/operations.js +28 -6
- package/dist/sdk/payment/operations.js.map +1 -1
- package/dist/sdk/payment/resumed-purchase.d.ts +1 -0
- package/dist/sdk/payment/resumed-purchase.js +119 -0
- package/dist/sdk/payment/resumed-purchase.js.map +1 -0
- package/dist/sdk/payment/security-code-mask.js +16 -23
- package/dist/sdk/payment/security-code-mask.js.map +1 -1
- package/dist/sdk/payment/submission-registry.js +6 -2
- package/dist/sdk/payment/submission-registry.js.map +1 -1
- package/dist/sdk/payment/use-payment-actions.d.ts +18 -3
- package/dist/sdk/payment/use-payment-actions.js +23 -3
- package/dist/sdk/payment/use-payment-actions.js.map +1 -1
- package/dist/sdk/payment/use-place-order.d.ts +10 -2
- package/dist/sdk/payment/use-place-order.js +138 -76
- package/dist/sdk/payment/use-place-order.js.map +1 -1
- package/dist/sdk/provider/storefront-provider.d.ts +1 -7
- package/dist/sdk/provider/storefront-provider.js +4 -11
- package/dist/sdk/provider/storefront-provider.js.map +1 -1
- package/dist/sdk/seo/entity-landing.d.ts +24 -0
- package/dist/sdk/seo/entity-landing.js +30 -0
- package/dist/sdk/seo/entity-landing.js.map +1 -0
- package/dist/sdk/seo/page-alternates.d.ts +3 -2
- package/dist/sdk/seo/page-alternates.js +4 -2
- package/dist/sdk/seo/page-alternates.js.map +1 -1
- package/dist/sdk/seo/search-landing.d.ts +42 -0
- package/dist/sdk/seo/search-landing.js +85 -0
- package/dist/sdk/seo/search-landing.js.map +1 -0
- package/dist/sdk/session/mock-session.d.ts +9 -0
- package/dist/sdk/session/mock-session.js +31 -0
- package/dist/sdk/session/mock-session.js.map +1 -0
- package/dist/sdk/session/read-server-session.d.ts +3 -0
- package/dist/sdk/session/read-server-session.js +5 -0
- package/dist/sdk/session/read-server-session.js.map +1 -1
- package/dist/sdk/session/return-path-segment.d.ts +10 -0
- package/dist/sdk/session/return-path-segment.js +15 -0
- package/dist/sdk/session/return-path-segment.js.map +1 -0
- package/dist/sdk/session/use-session-actions.js.map +1 -1
- package/dist/sdk/shipping/use-cart-shipping-simulation.js.map +1 -1
- package/dist/sdk/shipping/use-shipping-actions.js.map +1 -1
- package/dist/sdk/shipping/use-shipping-simulation.js.map +1 -1
- package/dist/utils/safe-href.d.ts +2 -0
- package/package.json +4 -3
- package/skills/storefront-asset/SKILL.md +2 -2
- package/skills/storefront-asset/references/api-side.md +27 -14
- package/skills/storefront-asset/references/findings.md +5 -2
- package/src/styles/tailwind.css +8 -0
- package/dist/matter/shipping-address/country-descriptors.d.ts +0 -1
- package/dist/message-locales.json +0 -7
- package/dist/sdk/i18n/client.d.ts +0 -4
- package/dist/sdk/i18n/client.js +0 -4
- package/dist/sdk/i18n/locales.d.ts +0 -8
- package/dist/sdk/i18n/locales.js +0 -57
- package/dist/sdk/i18n/locales.js.map +0 -1
- package/dist/sdk/i18n/messages/en-US.js +0 -183
- package/dist/sdk/i18n/messages/en-US.js.map +0 -1
- package/dist/sdk/i18n/messages/en-US.json +0 -178
- package/dist/sdk/i18n/messages/en-US.json.d.ts +0 -182
- package/dist/sdk/i18n/messages/es-ES.js +0 -183
- package/dist/sdk/i18n/messages/es-ES.js.map +0 -1
- package/dist/sdk/i18n/messages/es-ES.json +0 -178
- package/dist/sdk/i18n/messages/pt-BR.js +0 -183
- package/dist/sdk/i18n/messages/pt-BR.js.map +0 -1
- package/dist/sdk/i18n/messages/pt-BR.json +0 -178
- package/dist/sdk/i18n/provider.d.ts +0 -1
- package/dist/sdk/i18n/provider.js +0 -30
- package/dist/sdk/i18n/provider.js.map +0 -1
- package/dist/sdk/i18n/server.d.ts +0 -28
- package/dist/sdk/i18n/server.js +0 -59
- package/dist/sdk/i18n/server.js.map +0 -1
- package/dist/utils/resolve-authored-copy.js +0 -18
- package/dist/utils/resolve-authored-copy.js.map +0 -1
- package/dist/utils/substitute-template.js +0 -33
- package/dist/utils/substitute-template.js.map +0 -1
|
@@ -2,39 +2,39 @@
|
|
|
2
2
|
const POSTAL_CODE_PLACEHOLDER_PREFIX = "country-forms.address.postalCode.placeholder.";
|
|
3
3
|
const POSTAL_CODE_ERROR_PREFIX = "country-forms.validation.postalCode.";
|
|
4
4
|
/** The library's label key for a field, mapped by meaning: `state.label.COL` and `department.label` agree. */
|
|
5
|
-
const
|
|
6
|
-
"country-forms.address.postalCode.label": "
|
|
7
|
-
"country-forms.address.postalCode.label.GBR": "
|
|
8
|
-
"country-forms.address.street.label": "
|
|
9
|
-
"country-forms.address.number.label": "
|
|
10
|
-
"country-forms.address.complement.label": "
|
|
11
|
-
"country-forms.address.neighborhood.label": "
|
|
12
|
-
"country-forms.address.neighborhood.label.CHL": "
|
|
13
|
-
"country-forms.address.neighborhood.label.PER": "
|
|
14
|
-
"country-forms.address.city.label": "
|
|
15
|
-
"country-forms.address.city.label.ECU": "
|
|
16
|
-
"country-forms.address.city.label.GBR": "
|
|
17
|
-
"country-forms.address.city.label.COL": "
|
|
18
|
-
"country-forms.address.city.label.PER": "
|
|
19
|
-
"country-forms.address.state.label": "
|
|
20
|
-
"country-forms.address.state.label.CHL": "
|
|
21
|
-
"country-forms.address.state.label.COL": "
|
|
22
|
-
"country-forms.address.state.label.PER": "
|
|
23
|
-
"country-forms.address.state.label.ECU": "
|
|
24
|
-
"country-forms.address.state.label.ITA": "
|
|
25
|
-
"country-forms.address.state.label.GBR": "
|
|
26
|
-
"country-forms.address.state.label.IRL": "
|
|
27
|
-
"country-forms.address.department.label": "
|
|
5
|
+
const LABEL_KEYS = {
|
|
6
|
+
"country-forms.address.postalCode.label": "postalCode",
|
|
7
|
+
"country-forms.address.postalCode.label.GBR": "postcode",
|
|
8
|
+
"country-forms.address.street.label": "street",
|
|
9
|
+
"country-forms.address.number.label": "number",
|
|
10
|
+
"country-forms.address.complement.label": "complement",
|
|
11
|
+
"country-forms.address.neighborhood.label": "neighborhood",
|
|
12
|
+
"country-forms.address.neighborhood.label.CHL": "commune",
|
|
13
|
+
"country-forms.address.neighborhood.label.PER": "district",
|
|
14
|
+
"country-forms.address.city.label": "city",
|
|
15
|
+
"country-forms.address.city.label.ECU": "city",
|
|
16
|
+
"country-forms.address.city.label.GBR": "town",
|
|
17
|
+
"country-forms.address.city.label.COL": "municipality",
|
|
18
|
+
"country-forms.address.city.label.PER": "province",
|
|
19
|
+
"country-forms.address.state.label": "state",
|
|
20
|
+
"country-forms.address.state.label.CHL": "region",
|
|
21
|
+
"country-forms.address.state.label.COL": "department",
|
|
22
|
+
"country-forms.address.state.label.PER": "department",
|
|
23
|
+
"country-forms.address.state.label.ECU": "province",
|
|
24
|
+
"country-forms.address.state.label.ITA": "province",
|
|
25
|
+
"country-forms.address.state.label.GBR": "county",
|
|
26
|
+
"country-forms.address.state.label.IRL": "county",
|
|
27
|
+
"country-forms.address.department.label": "department"
|
|
28
28
|
};
|
|
29
29
|
/** The label of a field whose library key this module does not know. */
|
|
30
|
-
const
|
|
31
|
-
postalCode: "
|
|
32
|
-
street: "
|
|
33
|
-
number: "
|
|
34
|
-
complement: "
|
|
35
|
-
neighborhood: "
|
|
36
|
-
state: "
|
|
37
|
-
city: "
|
|
30
|
+
const FIELD_LABEL_KEYS = {
|
|
31
|
+
postalCode: "postalCode",
|
|
32
|
+
street: "street",
|
|
33
|
+
number: "number",
|
|
34
|
+
complement: "complement",
|
|
35
|
+
neighborhood: "neighborhood",
|
|
36
|
+
state: "state",
|
|
37
|
+
city: "city"
|
|
38
38
|
};
|
|
39
39
|
const STREET_PLACEHOLDER_KEY = "country-forms.address.street.placeholder";
|
|
40
40
|
/** Examples in the stored, masked form. The library's own placeholders, one per country. */
|
|
@@ -55,28 +55,28 @@ const POSTAL_CODE_EXAMPLES = {
|
|
|
55
55
|
PER: "15074",
|
|
56
56
|
USA: "10001-1234"
|
|
57
57
|
};
|
|
58
|
-
function
|
|
59
|
-
if (country === "BRA" && field === "postalCode") return "
|
|
60
|
-
return
|
|
58
|
+
function resolveLabelKey(key, field, country) {
|
|
59
|
+
if (country === "BRA" && field === "postalCode") return "cep";
|
|
60
|
+
return LABEL_KEYS[key] ?? FIELD_LABEL_KEYS[field];
|
|
61
61
|
}
|
|
62
62
|
function resolvePlaceholder(key, country) {
|
|
63
63
|
if (key === "country-forms.address.street.placeholder") return {
|
|
64
|
-
|
|
64
|
+
key: "street",
|
|
65
65
|
values: {}
|
|
66
66
|
};
|
|
67
67
|
const example = POSTAL_CODE_EXAMPLES[country];
|
|
68
68
|
if (key?.startsWith(POSTAL_CODE_PLACEHOLDER_PREFIX) && example !== void 0) return {
|
|
69
|
-
|
|
69
|
+
key: "postalCode",
|
|
70
70
|
values: { example }
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
|
-
function error(code,
|
|
73
|
+
function error(code, message, values) {
|
|
74
74
|
return values === void 0 ? {
|
|
75
75
|
code,
|
|
76
|
-
|
|
76
|
+
message
|
|
77
77
|
} : {
|
|
78
78
|
code,
|
|
79
|
-
|
|
79
|
+
message,
|
|
80
80
|
values
|
|
81
81
|
};
|
|
82
82
|
}
|
|
@@ -85,13 +85,13 @@ function error(code, messageId, values) {
|
|
|
85
85
|
* know is `invalid`, so a newer library never produces an error the form cannot word.
|
|
86
86
|
*/
|
|
87
87
|
function resolveLibraryError(key, { country, maxLength }) {
|
|
88
|
-
if (key === "country-forms.validation.required") return error("required", "
|
|
89
|
-
if (key === "country-forms.validation.maxLength" && maxLength !== void 0) return error("tooLong", "
|
|
88
|
+
if (key === "country-forms.validation.required") return error("required", "required");
|
|
89
|
+
if (key === "country-forms.validation.maxLength" && maxLength !== void 0) return error("tooLong", "tooLong", { maxLength });
|
|
90
90
|
const example = POSTAL_CODE_EXAMPLES[country];
|
|
91
|
-
if (key.startsWith(POSTAL_CODE_ERROR_PREFIX) && example !== void 0) return error("invalid", country === "BRA" ? "
|
|
92
|
-
return error("invalid", "
|
|
91
|
+
if (key.startsWith(POSTAL_CODE_ERROR_PREFIX) && example !== void 0) return error("invalid", country === "BRA" ? "cep" : "postalCode", { example });
|
|
92
|
+
return error("invalid", "invalid");
|
|
93
93
|
}
|
|
94
94
|
//#endregion
|
|
95
|
-
export {
|
|
95
|
+
export { LABEL_KEYS, POSTAL_CODE_EXAMPLES, STREET_PLACEHOLDER_KEY, resolveLabelKey, resolveLibraryError, resolvePlaceholder };
|
|
96
96
|
|
|
97
97
|
//# sourceMappingURL=messages.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.js","names":[],"sources":["../../../src/sdk/address/messages.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"messages.js","names":[],"sources":["../../../src/sdk/address/messages.ts"],"sourcesContent":["import type {\n AddressErrorCode,\n AddressErrorMessage,\n AddressFieldError,\n AddressLabelKey,\n AddressPlaceholderKey,\n CountryFieldName,\n} from './types.js';\n\nconst POSTAL_CODE_PLACEHOLDER_PREFIX = 'country-forms.address.postalCode.placeholder.';\nconst POSTAL_CODE_ERROR_PREFIX = 'country-forms.validation.postalCode.';\n\n/** The library's label key for a field, mapped by meaning: `state.label.COL` and `department.label` agree. */\nexport const LABEL_KEYS: Readonly<Record<string, AddressLabelKey>> = {\n 'country-forms.address.postalCode.label': 'postalCode',\n 'country-forms.address.postalCode.label.GBR': 'postcode',\n 'country-forms.address.street.label': 'street',\n 'country-forms.address.number.label': 'number',\n 'country-forms.address.complement.label': 'complement',\n 'country-forms.address.neighborhood.label': 'neighborhood',\n 'country-forms.address.neighborhood.label.CHL': 'commune',\n 'country-forms.address.neighborhood.label.PER': 'district',\n 'country-forms.address.city.label': 'city',\n 'country-forms.address.city.label.ECU': 'city',\n 'country-forms.address.city.label.GBR': 'town',\n 'country-forms.address.city.label.COL': 'municipality',\n 'country-forms.address.city.label.PER': 'province',\n 'country-forms.address.state.label': 'state',\n 'country-forms.address.state.label.CHL': 'region',\n 'country-forms.address.state.label.COL': 'department',\n 'country-forms.address.state.label.PER': 'department',\n 'country-forms.address.state.label.ECU': 'province',\n 'country-forms.address.state.label.ITA': 'province',\n 'country-forms.address.state.label.GBR': 'county',\n 'country-forms.address.state.label.IRL': 'county',\n 'country-forms.address.department.label': 'department',\n};\n\n/** The label of a field whose library key this module does not know. */\nconst FIELD_LABEL_KEYS: Readonly<Record<CountryFieldName, AddressLabelKey>> = {\n postalCode: 'postalCode',\n street: 'street',\n number: 'number',\n complement: 'complement',\n neighborhood: 'neighborhood',\n state: 'state',\n city: 'city',\n};\n\nexport const STREET_PLACEHOLDER_KEY = 'country-forms.address.street.placeholder';\n\n/** Examples in the stored, masked form. The library's own placeholders, one per country. */\nexport const POSTAL_CODE_EXAMPLES: Readonly<Record<string, string>> = {\n ARG: 'C1425ABC',\n BRA: '01310-100',\n CAN: 'K1A 0A9',\n CHL: '8320000',\n COL: '110111',\n DEU: '10115',\n ECU: '170150',\n ESP: '28001',\n FRA: '75001',\n GBR: 'SW1A 1AA',\n IRL: 'D02 AF30',\n ITA: '00118',\n MEX: '06600',\n PER: '15074',\n USA: '10001-1234',\n};\n\nexport function resolveLabelKey(key: string, field: CountryFieldName, country: string): AddressLabelKey {\n if (country === 'BRA' && field === 'postalCode') {\n return 'cep';\n }\n return LABEL_KEYS[key] ?? FIELD_LABEL_KEYS[field];\n}\n\nexport function resolvePlaceholder(\n key: string | undefined,\n country: string,\n): Readonly<{ key: AddressPlaceholderKey; values: Readonly<Record<string, string>> }> | undefined {\n if (key === STREET_PLACEHOLDER_KEY) {\n return { key: 'street', values: {} };\n }\n const example = POSTAL_CODE_EXAMPLES[country];\n if (key?.startsWith(POSTAL_CODE_PLACEHOLDER_PREFIX) && example !== undefined) {\n return { key: 'postalCode', values: { example } };\n }\n return undefined;\n}\n\nfunction error(code: AddressErrorCode, message: AddressErrorMessage, values?: Record<string, string | number>) {\n return values === undefined ? { code, message } : { code, message, values };\n}\n\n/**\n * Turns the message key the library returned for a field into an error. A key this module does not\n * know is `invalid`, so a newer library never produces an error the form cannot word.\n */\nexport function resolveLibraryError(\n key: string,\n { country, maxLength }: Readonly<{ country: string; maxLength?: number }>,\n): AddressFieldError {\n if (key === 'country-forms.validation.required') {\n return error('required', 'required');\n }\n if (key === 'country-forms.validation.maxLength' && maxLength !== undefined) {\n return error('tooLong', 'tooLong', { maxLength });\n }\n const example = POSTAL_CODE_EXAMPLES[country];\n if (key.startsWith(POSTAL_CODE_ERROR_PREFIX) && example !== undefined) {\n return error('invalid', country === 'BRA' ? 'cep' : 'postalCode', { example });\n }\n return error('invalid', 'invalid');\n}\n"],"mappings":";AASA,MAAM,iCAAiC;AACvC,MAAM,2BAA2B;;AAGjC,MAAa,aAAwD;CACnE,0CAA0C;CAC1C,8CAA8C;CAC9C,sCAAsC;CACtC,sCAAsC;CACtC,0CAA0C;CAC1C,4CAA4C;CAC5C,gDAAgD;CAChD,gDAAgD;CAChD,oCAAoC;CACpC,wCAAwC;CACxC,wCAAwC;CACxC,wCAAwC;CACxC,wCAAwC;CACxC,qCAAqC;CACrC,yCAAyC;CACzC,yCAAyC;CACzC,yCAAyC;CACzC,yCAAyC;CACzC,yCAAyC;CACzC,yCAAyC;CACzC,yCAAyC;CACzC,0CAA0C;AAC5C;;AAGA,MAAM,mBAAwE;CAC5E,YAAY;CACZ,QAAQ;CACR,QAAQ;CACR,YAAY;CACZ,cAAc;CACd,OAAO;CACP,MAAM;AACR;AAEA,MAAa,yBAAyB;;AAGtC,MAAa,uBAAyD;CACpE,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;AACP;AAEA,SAAgB,gBAAgB,KAAa,OAAyB,SAAkC;CACtG,IAAI,YAAY,SAAS,UAAU,cACjC,OAAO;CAET,OAAO,WAAW,QAAQ,iBAAiB;AAC7C;AAEA,SAAgB,mBACd,KACA,SACgG;CAChG,IAAI,QAAA,4CACF,OAAO;EAAE,KAAK;EAAU,QAAQ,CAAC;CAAE;CAErC,MAAM,UAAU,qBAAqB;CACrC,IAAI,KAAK,WAAW,8BAA8B,KAAK,YAAY,KAAA,GACjE,OAAO;EAAE,KAAK;EAAc,QAAQ,EAAE,QAAQ;CAAE;AAGpD;AAEA,SAAS,MAAM,MAAwB,SAA8B,QAA0C;CAC7G,OAAO,WAAW,KAAA,IAAY;EAAE;EAAM;CAAQ,IAAI;EAAE;EAAM;EAAS;CAAO;AAC5E;;;;;AAMA,SAAgB,oBACd,KACA,EAAE,SAAS,aACQ;CACnB,IAAI,QAAQ,qCACV,OAAO,MAAM,YAAY,UAAU;CAErC,IAAI,QAAQ,wCAAwC,cAAc,KAAA,GAChE,OAAO,MAAM,WAAW,WAAW,EAAE,UAAU,CAAC;CAElD,MAAM,UAAU,qBAAqB;CACrC,IAAI,IAAI,WAAW,wBAAwB,KAAK,YAAY,KAAA,GAC1D,OAAO,MAAM,WAAW,YAAY,QAAQ,QAAQ,cAAc,EAAE,QAAQ,CAAC;CAE/E,OAAO,MAAM,WAAW,SAAS;AACnC"}
|
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
import { POSTAL_CODE_LOOKUP_COUNTRIES } from "./constants.js";
|
|
2
|
-
import "@vtex/country-forms";
|
|
2
|
+
import { formatValue, resolveFieldFormatRef, resolveFieldUnformatRef, unformatValue } from "@vtex/country-forms";
|
|
3
3
|
//#region src/sdk/address/postal-code.ts
|
|
4
|
+
/**
|
|
5
|
+
* The stored form of a postal code: the country's masked form, such as `01001-000`, `20500-0003`, or
|
|
6
|
+
* `SW1A 1AA`. The library accepts most codes with or without the mask but refuses an unmasked US
|
|
7
|
+
* ZIP+4, so the masked form is the one every country accepts. A country with no mask stores the
|
|
8
|
+
* trimmed value. Apply it to a value that passed `validateAddress`.
|
|
9
|
+
*/
|
|
10
|
+
function normalizePostalCode(value, rules) {
|
|
11
|
+
const trimmed = value.trim();
|
|
12
|
+
const field = rules.schema.fields.find(({ name }) => name === "postalCode");
|
|
13
|
+
if (!field) return trimmed;
|
|
14
|
+
const values = { postalCode: trimmed };
|
|
15
|
+
return formatValue(resolveFieldFormatRef(field, values), unformatValue(resolveFieldUnformatRef(field, values), trimmed));
|
|
16
|
+
}
|
|
4
17
|
/** Whether the form offers to fill the address from the postal code for this country. */
|
|
5
18
|
function hasPostalCodeLookup(country) {
|
|
6
19
|
return POSTAL_CODE_LOOKUP_COUNTRIES.includes(country.trim().toUpperCase());
|
|
7
20
|
}
|
|
8
21
|
//#endregion
|
|
9
|
-
export { hasPostalCodeLookup };
|
|
22
|
+
export { hasPostalCodeLookup, normalizePostalCode };
|
|
10
23
|
|
|
11
24
|
//# sourceMappingURL=postal-code.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postal-code.js","names":[],"sources":["../../../src/sdk/address/postal-code.ts"],"sourcesContent":["import { formatValue, resolveFieldFormatRef, resolveFieldUnformatRef, unformatValue } from '@vtex/country-forms';\nimport { POSTAL_CODE_LOOKUP_COUNTRIES } from './constants.js';\nimport type { CountryRules } from './types.js';\n\n/**\n * The stored form of a postal code: the country's masked form, such as `01001-000`, `20500-0003`, or\n * `SW1A 1AA`. The library accepts most codes with or without the mask but refuses an unmasked US\n * ZIP+4, so the masked form is the one every country accepts. A country with no mask stores the\n * trimmed value. Apply it to a value that passed `validateAddress`.\n */\nexport function normalizePostalCode(value: string, rules: CountryRules): string {\n const trimmed = value.trim();\n const field = rules.schema.fields.find(({ name }) => name === 'postalCode');\n if (!field) {\n return trimmed;\n }\n const values = { postalCode: trimmed };\n return formatValue(\n resolveFieldFormatRef(field, values),\n unformatValue(resolveFieldUnformatRef(field, values), trimmed),\n );\n}\n\n/** Whether the form offers to fill the address from the postal code for this country. */\nexport function hasPostalCodeLookup(country: string): boolean {\n return POSTAL_CODE_LOOKUP_COUNTRIES.includes(country.trim().toUpperCase());\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"postal-code.js","names":[],"sources":["../../../src/sdk/address/postal-code.ts"],"sourcesContent":["import { formatValue, resolveFieldFormatRef, resolveFieldUnformatRef, unformatValue } from '@vtex/country-forms';\nimport { POSTAL_CODE_LOOKUP_COUNTRIES } from './constants.js';\nimport type { CountryRules } from './types.js';\n\n/**\n * The stored form of a postal code: the country's masked form, such as `01001-000`, `20500-0003`, or\n * `SW1A 1AA`. The library accepts most codes with or without the mask but refuses an unmasked US\n * ZIP+4, so the masked form is the one every country accepts. A country with no mask stores the\n * trimmed value. Apply it to a value that passed `validateAddress`.\n */\nexport function normalizePostalCode(value: string, rules: CountryRules): string {\n const trimmed = value.trim();\n const field = rules.schema.fields.find(({ name }) => name === 'postalCode');\n if (!field) {\n return trimmed;\n }\n const values = { postalCode: trimmed };\n return formatValue(\n resolveFieldFormatRef(field, values),\n unformatValue(resolveFieldUnformatRef(field, values), trimmed),\n );\n}\n\n/** Whether the form offers to fill the address from the postal code for this country. */\nexport function hasPostalCodeLookup(country: string): boolean {\n return POSTAL_CODE_LOOKUP_COUNTRIES.includes(country.trim().toUpperCase());\n}\n"],"mappings":";;;;;;;;;AAUA,SAAgB,oBAAoB,OAAe,OAA6B;CAC9E,MAAM,UAAU,MAAM,KAAK;CAC3B,MAAM,QAAQ,MAAM,OAAO,OAAO,MAAM,EAAE,WAAW,SAAS,YAAY;CAC1E,IAAI,CAAC,OACH,OAAO;CAET,MAAM,SAAS,EAAE,YAAY,QAAQ;CACrC,OAAO,YACL,sBAAsB,OAAO,MAAM,GACnC,cAAc,wBAAwB,OAAO,MAAM,GAAG,OAAO,CAC/D;AACF;;AAGA,SAAgB,oBAAoB,SAA0B;CAC5D,OAAO,6BAA6B,SAAS,QAAQ,KAAK,CAAC,CAAC,YAAY,CAAC;AAC3E"}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { MessageId } from "../i18n/locales.js";
|
|
2
|
-
import "../i18n/client.js";
|
|
3
1
|
import { FormSchema } from "@vtex/country-forms";
|
|
4
2
|
//#region src/sdk/address/types.d.ts
|
|
5
3
|
/** The seven fields `@vtex/country-forms` address schemas declare, spelled as on `CustomerAddress`. */
|
|
@@ -8,9 +6,13 @@ export type CountryFieldName = 'postalCode' | 'street' | 'number' | 'complement'
|
|
|
8
6
|
export type AccountFieldName = 'recipientName' | 'reference' | 'name';
|
|
9
7
|
export type AddressFieldName = CountryFieldName | AccountFieldName;
|
|
10
8
|
export type AddressErrorCode = 'required' | 'invalid' | 'tooLong';
|
|
9
|
+
/** Which message words an error. `cep` and `postalCode` are invalid postal codes, worded with an example. */
|
|
10
|
+
export type AddressErrorMessage = 'required' | 'invalid' | 'tooLong' | 'cep' | 'postalCode';
|
|
11
|
+
/** Which label names a country field, by meaning: a country can call its `city` a `town` or a `province`. */
|
|
12
|
+
export type AddressLabelKey = 'cep' | 'city' | 'commune' | 'complement' | 'county' | 'department' | 'district' | 'municipality' | 'neighborhood' | 'number' | 'postalCode' | 'postcode' | 'province' | 'region' | 'state' | 'street' | 'town';
|
|
11
13
|
export type AddressFieldError = Readonly<{
|
|
12
14
|
code: AddressErrorCode;
|
|
13
|
-
|
|
15
|
+
message: AddressErrorMessage;
|
|
14
16
|
/** The values the message interpolates, such as `{ maxLength: 750 }` or `{ example: '01310-100' }`. */
|
|
15
17
|
values?: Readonly<Record<string, string | number>>;
|
|
16
18
|
}>;
|
|
@@ -5,11 +5,11 @@ import { createFormState, getVisibleFields, resolveFieldOptions, validate } from
|
|
|
5
5
|
//#region src/sdk/address/validate-address.ts
|
|
6
6
|
const REQUIRED = {
|
|
7
7
|
code: "required",
|
|
8
|
-
|
|
8
|
+
message: "required"
|
|
9
9
|
};
|
|
10
10
|
const INVALID = {
|
|
11
11
|
code: "invalid",
|
|
12
|
-
|
|
12
|
+
message: "invalid"
|
|
13
13
|
};
|
|
14
14
|
function isAddressField(name) {
|
|
15
15
|
return Object.hasOwn(ACCOUNT_MAX_LENGTH, name);
|
|
@@ -50,7 +50,7 @@ function validateAddress(values, rules) {
|
|
|
50
50
|
const maxLength = ACCOUNT_MAX_LENGTH[name];
|
|
51
51
|
if (!errors[name] && (values[name] ?? "").length > maxLength) errors[name] = {
|
|
52
52
|
code: "tooLong",
|
|
53
|
-
|
|
53
|
+
message: "tooLong",
|
|
54
54
|
values: { maxLength }
|
|
55
55
|
};
|
|
56
56
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate-address.js","names":[],"sources":["../../../src/sdk/address/validate-address.ts"],"sourcesContent":["import {\n createFormState,\n type FieldDefinition,\n type FormValues,\n getVisibleFields,\n resolveFieldOptions,\n validate,\n} from '@vtex/country-forms';\nimport { ACCOUNT_MAX_LENGTH } from './constants.js';\nimport { resolveLibraryError } from './messages.js';\nimport { declaredMaxLength, toFormValues } from './schema.js';\nimport type { AddressErrors, AddressFieldError, AddressFieldName, AddressValues, CountryRules } from './types.js';\n\nconst REQUIRED: AddressFieldError = { code: 'required',
|
|
1
|
+
{"version":3,"file":"validate-address.js","names":[],"sources":["../../../src/sdk/address/validate-address.ts"],"sourcesContent":["import {\n createFormState,\n type FieldDefinition,\n type FormValues,\n getVisibleFields,\n resolveFieldOptions,\n validate,\n} from '@vtex/country-forms';\nimport { ACCOUNT_MAX_LENGTH } from './constants.js';\nimport { resolveLibraryError } from './messages.js';\nimport { declaredMaxLength, toFormValues } from './schema.js';\nimport type { AddressErrors, AddressFieldError, AddressFieldName, AddressValues, CountryRules } from './types.js';\n\nconst REQUIRED: AddressFieldError = { code: 'required', message: 'required' };\nconst INVALID: AddressFieldError = { code: 'invalid', message: 'invalid' };\n\nfunction isAddressField(name: string): name is AddressFieldName {\n return Object.hasOwn(ACCOUNT_MAX_LENGTH, name);\n}\n\nfunction isOutsideOptions(field: FieldDefinition, values: FormValues, fields: readonly FieldDefinition[]): boolean {\n const value = values[field.name] ?? '';\n if (field.type !== 'select' || value === '') {\n return false;\n }\n\n // A dependent list exists only for a valid controller; the controller carries its own error.\n const controller = fields.find(({ name }) => name === field.dependsOn);\n if (controller && ((values[controller.name] ?? '') === '' || isOutsideOptions(controller, values, fields))) {\n return false;\n }\n\n return !(resolveFieldOptions(field, values) ?? []).some((option) => option.value === value);\n}\n\n/**\n * Checks a draft or a stored address against its country's rules and the account's own rules, and\n * returns at most one error per field. A field's first error wins, in this order: the library's,\n * a select value outside its options, then the account's maximum length.\n *\n * The account's rules cover what the library does not: `recipientName` must not be blank,\n * `reference` and the address name may be empty, every free-text field has a maximum length, and a\n * select's value must be one of the options the library resolves. Keys outside the ten address\n * fields are ignored, so a merged record can carry `geoCoordinate` as it is.\n */\nexport function validateAddress(values: AddressValues, rules: CountryRules): AddressErrors {\n const text = toFormValues(values);\n const fields = getVisibleFields(rules.schema, text);\n const errors: Partial<Record<AddressFieldName, AddressFieldError>> = {};\n\n const declared = new Map(rules.schema.fields.map((field) => [field.name, field]));\n const libraryErrors = validate(createFormState(rules.schema, text), rules.schema);\n for (const [name, key] of Object.entries(libraryErrors)) {\n const field = declared.get(name);\n if (isAddressField(name) && field) {\n errors[name] = resolveLibraryError(key, { country: rules.country, maxLength: declaredMaxLength(field) });\n }\n }\n\n for (const field of fields) {\n if (isAddressField(field.name) && !errors[field.name] && isOutsideOptions(field, text, fields)) {\n errors[field.name] = INVALID;\n }\n }\n\n if ((values.recipientName ?? '').trim() === '' && !errors.recipientName) {\n errors.recipientName = REQUIRED;\n }\n\n for (const name of Object.keys(ACCOUNT_MAX_LENGTH).filter(isAddressField)) {\n const maxLength = ACCOUNT_MAX_LENGTH[name];\n if (!errors[name] && (values[name] ?? '').length > maxLength) {\n errors[name] = { code: 'tooLong', message: 'tooLong', values: { maxLength } };\n }\n }\n\n return errors;\n}\n"],"mappings":";;;;;AAaA,MAAM,WAA8B;CAAE,MAAM;CAAY,SAAS;AAAW;AAC5E,MAAM,UAA6B;CAAE,MAAM;CAAW,SAAS;AAAU;AAEzE,SAAS,eAAe,MAAwC;CAC9D,OAAO,OAAO,OAAO,oBAAoB,IAAI;AAC/C;AAEA,SAAS,iBAAiB,OAAwB,QAAoB,QAA6C;CACjH,MAAM,QAAQ,OAAO,MAAM,SAAS;CACpC,IAAI,MAAM,SAAS,YAAY,UAAU,IACvC,OAAO;CAIT,MAAM,aAAa,OAAO,MAAM,EAAE,WAAW,SAAS,MAAM,SAAS;CACrE,IAAI,gBAAgB,OAAO,WAAW,SAAS,QAAQ,MAAM,iBAAiB,YAAY,QAAQ,MAAM,IACtG,OAAO;CAGT,OAAO,EAAE,oBAAoB,OAAO,MAAM,KAAK,CAAC,EAAA,CAAG,MAAM,WAAW,OAAO,UAAU,KAAK;AAC5F;;;;;;;;;;;AAYA,SAAgB,gBAAgB,QAAuB,OAAoC;CACzF,MAAM,OAAO,aAAa,MAAM;CAChC,MAAM,SAAS,iBAAiB,MAAM,QAAQ,IAAI;CAClD,MAAM,SAA+D,CAAC;CAEtE,MAAM,WAAW,IAAI,IAAI,MAAM,OAAO,OAAO,KAAK,UAAU,CAAC,MAAM,MAAM,KAAK,CAAC,CAAC;CAChF,MAAM,gBAAgB,SAAS,gBAAgB,MAAM,QAAQ,IAAI,GAAG,MAAM,MAAM;CAChF,KAAK,MAAM,CAAC,MAAM,QAAQ,OAAO,QAAQ,aAAa,GAAG;EACvD,MAAM,QAAQ,SAAS,IAAI,IAAI;EAC/B,IAAI,eAAe,IAAI,KAAK,OAC1B,OAAO,QAAQ,oBAAoB,KAAK;GAAE,SAAS,MAAM;GAAS,WAAW,kBAAkB,KAAK;EAAE,CAAC;CAE3G;CAEA,KAAK,MAAM,SAAS,QAClB,IAAI,eAAe,MAAM,IAAI,KAAK,CAAC,OAAO,MAAM,SAAS,iBAAiB,OAAO,MAAM,MAAM,GAC3F,OAAO,MAAM,QAAQ;CAIzB,KAAK,OAAO,iBAAiB,GAAA,CAAI,KAAK,MAAM,MAAM,CAAC,OAAO,eACxD,OAAO,gBAAgB;CAGzB,KAAK,MAAM,QAAQ,OAAO,KAAK,kBAAkB,CAAC,CAAC,OAAO,cAAc,GAAG;EACzE,MAAM,YAAY,mBAAmB;EACrC,IAAI,CAAC,OAAO,UAAU,OAAO,SAAS,GAAA,CAAI,SAAS,WACjD,OAAO,QAAQ;GAAE,MAAM;GAAW,SAAS;GAAW,QAAQ,EAAE,UAAU;EAAE;CAEhF;CAEA,OAAO;AACT"}
|
|
@@ -33,7 +33,7 @@ export type AddPaymentInfoEvent = Readonly<{
|
|
|
33
33
|
name: 'add_payment_info';
|
|
34
34
|
value: AnalyticsMoney;
|
|
35
35
|
/**
|
|
36
|
-
* Derived from the selected method's `
|
|
36
|
+
* Derived from the selected method's `PaymentMethod.type` at the moment this fires (T140, Decision 5).
|
|
37
37
|
* Optional because the event fires on the cart total, before a method is necessarily selected —
|
|
38
38
|
* omitted rather than a guessed literal, so a downstream consumer never reads a false payment kind.
|
|
39
39
|
* `toEcommercePayload` below drops the corresponding key entirely when this is absent.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-analytics-actions.js","names":[],"sources":["../../../src/sdk/analytics/use-analytics-actions.ts"],"sourcesContent":["'use client';\n\nimport { defineActions } from '@vtex/fs-core';\nimport { useCallback, useMemo, useRef } from 'react';\nimport { loggableErrorName } from '../../utils/loggable-error-name.js';\nimport {\n type AnalyticsDestination,\n DEFAULT_ANALYTICS_DESTINATION,\n resolveAnalyticsDestination,\n useAnalyticsDestination,\n} from './analytics-destination.js';\n\n/**\n * The `analytics` action namespace (specs/analytics-events.md) — a dispatcher-flavor namespace\n * (docs/storefront-core/adr-0010-actions-own-the-write-side.md; docs/storefront-core/rfc-actions.md\n * § \"Three binding flavors\") that pushes the two standard payment analytics events,\n * `add_payment_info` and `purchase`, to a `window` array — `window.dataLayer` by default, the\n * GTM/GA4-recognizable event convention. It never touches the Apollo cache, never issues a GraphQL\n * operation, and never throws: a broken tag-manager script can never block payment submission or\n * order placement.\n *\n * The destination array is configurable at build time\n * (specs/make-the-analytics-destination-configurable-for.md; T120) — see\n * `./analytics-destination.js` for the resolution precedence, validation, and the\n * `AnalyticsDestinationProvider`. The pushed entry's shape is a data *contract* (a well-known\n * browser-global array shape), not a *provider* — no vendor SDK, no server call. A future\n * platform/foundation epic may replace this sink with a real `AnalyticsContext`; the\n * `track(event: AnalyticsEvent): void` signature and `AnalyticsActions` type are the stable public\n * contract every call site depends on until then (US-4).\n */\n\nexport type AnalyticsMoney = Readonly<{\n amount: number;\n currencyCode: string;\n}>;\n\nexport type AnalyticsLineItem = Readonly<{\n sku: string;\n name: string;\n price: AnalyticsMoney;\n quantity: number;\n}>;\n\n/** Dispatched by T7's CardEntry, before opening the transaction. */\nexport type AddPaymentInfoEvent = Readonly<{\n name: 'add_payment_info';\n value: AnalyticsMoney;\n /**\n * Derived from the selected method's `groupName` at the moment this fires (T140, Decision 5).\n * Optional because the event fires on the cart total, before a method is necessarily selected —\n * omitted rather than a guessed literal, so a downstream consumer never reads a false payment kind.\n * `toEcommercePayload` below drops the corresponding key entirely when this is absent.\n */\n paymentType?: 'Credit Card' | 'Debit Card';\n items?: readonly AnalyticsLineItem[];\n}>;\n\n/** Dispatched by T13's usePlaceOrder, after a successful gateway callback. */\nexport type PurchaseEvent = Readonly<{\n name: 'purchase';\n transactionId: string;\n value: AnalyticsMoney;\n items?: readonly AnalyticsLineItem[];\n}>;\n\nexport type AnalyticsEvent = AddPaymentInfoEvent | PurchaseEvent;\n\nexport type AnalyticsActions = Readonly<{\n /** Push a standard analytics event to window.dataLayer. Fire-and-forget; never throws. */\n track: (event: AnalyticsEvent) => void;\n}>;\n\n/** The shape pushed onto window.dataLayer — GTM/GA4's own event convention. */\nexport type AnalyticsDataLayerEvent = Readonly<{\n event: 'add_payment_info' | 'purchase';\n ecommerce: Record<string, unknown>;\n}>;\n\nfunction toEcommerceItems(items: readonly AnalyticsLineItem[] | undefined) {\n return (items ?? []).map((item) => ({\n item_id: item.sku,\n item_name: item.name,\n price: item.price.amount,\n quantity: item.quantity,\n }));\n}\n\nfunction toEcommercePayload(event: AnalyticsEvent): Record<string, unknown> {\n if (event.name === 'add_payment_info') {\n return {\n currency: event.value.currencyCode,\n value: event.value.amount,\n // T140, Decision 5: the key itself must be absent when `paymentType` is, not merely `undefined`\n // — `pushToDataLayer` pushes this object as-is with no serialization step to strip it, and\n // `'payment_type' in ecommerce` would otherwise still report true.\n ...(event.paymentType !== undefined ? { payment_type: event.paymentType } : {}),\n items: toEcommerceItems(event.items),\n };\n }\n return {\n transaction_id: event.transactionId,\n currency: event.value.currencyCode,\n value: event.value.amount,\n items: toEcommerceItems(event.items),\n };\n}\n\n// `Reflect.get`/`Reflect.set` below match `storefront-provider.tsx`'s existing pattern for a\n// dynamic `window` key — they are not a security mechanism. `Reflect.set(target, k, v)` invokes\n// an inherited setter and creates no own property, exactly like `window[k] = v` would; it adds no\n// hardening on its own. What actually blocks prototype pollution is\n// `isValidAnalyticsDestination`'s denylist and identifier pattern, checked by the caller before\n// `destination` ever reaches this function, plus the non-array guard immediately below.\n//\n// The cast below, not a `declare global` augmentation of `Window`, is what keeps this typed: a\n// global augmentation here would ship inside this package's own `.d.ts` output and hand every\n// consumer's `window.dataLayer` this package's narrow event union, wrong for a store that also\n// pushes its own GTM events (packages/components/scripts/dist-type-boundary.test.ts). `destination`\n// is a runtime string anyway — `Window` has nothing to look up a dynamic key against — so the local\n// cast is also the only type-safe option, not merely the non-leaking one.\nfunction pushToDataLayer(event: AnalyticsEvent, destination: AnalyticsDestination): void {\n if (typeof window === 'undefined') return;\n\n let layer = Reflect.get(window, destination) as AnalyticsDataLayerEvent[] | undefined;\n if (layer === undefined) {\n layer = [];\n Reflect.set(window, destination, layer);\n } else if (!Array.isArray(layer)) {\n console.error(`[analytics.track] window.${destination} already exists and is not an array; the event was dropped`);\n return;\n }\n\n layer.push({ event: event.name, ecommerce: toEcommercePayload(event) });\n}\n\n/**\n * The `analytics` namespace hook. Registered with the first-party action registry via\n * `analyticsActions` below; the compiler-emitted `AnalyticsActionProvider` calls it and threads\n * the narrowed methods into each consumer's `$actions.analytics`. Dispatcher flavor: no\n * `useMutation`, no cache read or write (ADR-0010). Fire-and-forget — `track` never throws, so a\n * broken tag-manager script can never block payment submission or order placement.\n */\nexport function useAnalyticsActions(): AnalyticsActions {\n const override = useAnalyticsDestination();\n // Scoped to this hook instance, not the module: \"logs once\" means once per mounted\n // `useAnalyticsActions()`, so two independent call sites each still get their own first warning.\n const hasLoggedRejectionRef = useRef(false);\n\n const track = useCallback<AnalyticsActions['track']>(\n (event) => {\n // The SSR guard runs before any destination resolution is attempted — not just before the\n // write. Preserved from the pre-T120 behaviour (US-3, \"SSR — no destination resolution\n // attempted at all\").\n if (typeof window === 'undefined') return;\n let destination: AnalyticsDestination = DEFAULT_ANALYTICS_DESTINATION;\n try {\n destination = resolveAnalyticsDestination({\n override,\n hasLoggedRejection: hasLoggedRejectionRef,\n });\n pushToDataLayer(event, destination);\n } catch (error) {\n console.error(`[analytics.track] window.${destination} push failed`, loggableErrorName(error));\n }\n },\n [override],\n );\n\n return useMemo(() => ({ track }), [track]);\n}\n\n/**\n * Declares the `analytics` action namespace — the single source of truth for its method/payload\n * metadata, runtime provider, and `use` hook (mirrors `cartActions`, `shippingActions`). The\n * native catalog builder (`scripts/build-catalog.mjs`) statically reads this call to emit\n * `actions.json`; at runtime `AnalyticsActionProvider` calls `useAnalyticsActions` directly.\n *\n * The `payload` below is a flattened, best-effort scalar approximation of `AnalyticsEvent` for\n * catalog/docs tooling: `ActionPayloadField.type` supports only scalar primitives and cannot\n * express a discriminated union or a nested `items` array. The TS `AnalyticsEvent` union above is\n * the source of truth for the real call shape.\n */\nexport const analyticsActions = defineActions({\n namespace: 'analytics',\n description:\n 'Dispatcher-flavor namespace that pushes standard add_payment_info / purchase events to window.dataLayer. Never touches the Apollo cache.',\n provider: { name: 'AnalyticsActionProvider', importPath: '@vtex/faststore/internal/client' },\n methods: {\n track: {\n description:\n 'Push a standard analytics event (add_payment_info | purchase) to window.dataLayer. Fire-and-forget; never throws.',\n payload: [\n { name: 'name', type: 'string' },\n { name: 'currencyCode', type: 'string' },\n { name: 'amount', type: 'number' },\n { name: 'paymentType', type: 'string', optional: true },\n { name: 'transactionId', type: 'string', optional: true },\n ],\n },\n },\n use: useAnalyticsActions,\n});\n"],"mappings":";;;;;;;AA8EA,SAAS,iBAAiB,OAAiD;CACzE,QAAQ,SAAS,CAAC,EAAA,CAAG,KAAK,UAAU;EAClC,SAAS,KAAK;EACd,WAAW,KAAK;EAChB,OAAO,KAAK,MAAM;EAClB,UAAU,KAAK;CACjB,EAAE;AACJ;AAEA,SAAS,mBAAmB,OAAgD;CAC1E,IAAI,MAAM,SAAS,oBACjB,OAAO;EACL,UAAU,MAAM,MAAM;EACtB,OAAO,MAAM,MAAM;EAInB,GAAI,MAAM,gBAAgB,KAAA,IAAY,EAAE,cAAc,MAAM,YAAY,IAAI,CAAC;EAC7E,OAAO,iBAAiB,MAAM,KAAK;CACrC;CAEF,OAAO;EACL,gBAAgB,MAAM;EACtB,UAAU,MAAM,MAAM;EACtB,OAAO,MAAM,MAAM;EACnB,OAAO,iBAAiB,MAAM,KAAK;CACrC;AACF;AAeA,SAAS,gBAAgB,OAAuB,aAAyC;CACvF,IAAI,OAAO,WAAW,aAAa;CAEnC,IAAI,QAAQ,QAAQ,IAAI,QAAQ,WAAW;CAC3C,IAAI,UAAU,KAAA,GAAW;EACvB,QAAQ,CAAC;EACT,QAAQ,IAAI,QAAQ,aAAa,KAAK;CACxC,OAAO,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;EAChC,QAAQ,MAAM,4BAA4B,YAAY,2DAA2D;EACjH;CACF;CAEA,MAAM,KAAK;EAAE,OAAO,MAAM;EAAM,WAAW,mBAAmB,KAAK;CAAE,CAAC;AACxE;;;;;;;;AASA,SAAgB,sBAAwC;CACtD,MAAM,WAAW,wBAAwB;CAGzC,MAAM,wBAAwB,OAAO,KAAK;CAE1C,MAAM,QAAQ,aACX,UAAU;EAIT,IAAI,OAAO,WAAW,aAAa;EACnC,IAAI,cAAoC;EACxC,IAAI;GACF,cAAc,4BAA4B;IACxC;IACA,oBAAoB;GACtB,CAAC;GACD,gBAAgB,OAAO,WAAW;EACpC,SAAS,OAAO;GACd,QAAQ,MAAM,4BAA4B,YAAY,eAAe,kBAAkB,KAAK,CAAC;EAC/F;CACF,GACA,CAAC,QAAQ,CACX;CAEA,OAAO,eAAe,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC;AAC3C;AAagC,cAAc;CAC5C,WAAW;CACX,aACE;CACF,UAAU;EAAE,MAAM;EAA2B,YAAY;CAAkC;CAC3F,SAAS,EACP,OAAO;EACL,aACE;EACF,SAAS;GACP;IAAE,MAAM;IAAQ,MAAM;GAAS;GAC/B;IAAE,MAAM;IAAgB,MAAM;GAAS;GACvC;IAAE,MAAM;IAAU,MAAM;GAAS;GACjC;IAAE,MAAM;IAAe,MAAM;IAAU,UAAU;GAAK;GACtD;IAAE,MAAM;IAAiB,MAAM;IAAU,UAAU;GAAK;EAC1D;CACF,EACF;CACA,KAAK;AACP,CAAC"}
|
|
1
|
+
{"version":3,"file":"use-analytics-actions.js","names":[],"sources":["../../../src/sdk/analytics/use-analytics-actions.ts"],"sourcesContent":["'use client';\n\nimport { defineActions } from '@vtex/fs-core';\nimport { useCallback, useMemo, useRef } from 'react';\nimport { loggableErrorName } from '../../utils/loggable-error-name.js';\nimport {\n type AnalyticsDestination,\n DEFAULT_ANALYTICS_DESTINATION,\n resolveAnalyticsDestination,\n useAnalyticsDestination,\n} from './analytics-destination.js';\n\n/**\n * The `analytics` action namespace (specs/analytics-events.md) — a dispatcher-flavor namespace\n * (docs/storefront-core/adr-0010-actions-own-the-write-side.md; docs/storefront-core/rfc-actions.md\n * § \"Three binding flavors\") that pushes the two standard payment analytics events,\n * `add_payment_info` and `purchase`, to a `window` array — `window.dataLayer` by default, the\n * GTM/GA4-recognizable event convention. It never touches the Apollo cache, never issues a GraphQL\n * operation, and never throws: a broken tag-manager script can never block payment submission or\n * order placement.\n *\n * The destination array is configurable at build time\n * (specs/make-the-analytics-destination-configurable-for.md; T120) — see\n * `./analytics-destination.js` for the resolution precedence, validation, and the\n * `AnalyticsDestinationProvider`. The pushed entry's shape is a data *contract* (a well-known\n * browser-global array shape), not a *provider* — no vendor SDK, no server call. A future\n * platform/foundation epic may replace this sink with a real `AnalyticsContext`; the\n * `track(event: AnalyticsEvent): void` signature and `AnalyticsActions` type are the stable public\n * contract every call site depends on until then (US-4).\n */\n\nexport type AnalyticsMoney = Readonly<{\n amount: number;\n currencyCode: string;\n}>;\n\nexport type AnalyticsLineItem = Readonly<{\n sku: string;\n name: string;\n price: AnalyticsMoney;\n quantity: number;\n}>;\n\n/** Dispatched by T7's CardEntry, before opening the transaction. */\nexport type AddPaymentInfoEvent = Readonly<{\n name: 'add_payment_info';\n value: AnalyticsMoney;\n /**\n * Derived from the selected method's `PaymentMethod.type` at the moment this fires (T140, Decision 5).\n * Optional because the event fires on the cart total, before a method is necessarily selected —\n * omitted rather than a guessed literal, so a downstream consumer never reads a false payment kind.\n * `toEcommercePayload` below drops the corresponding key entirely when this is absent.\n */\n paymentType?: 'Credit Card' | 'Debit Card';\n items?: readonly AnalyticsLineItem[];\n}>;\n\n/** Dispatched by T13's usePlaceOrder, after a successful gateway callback. */\nexport type PurchaseEvent = Readonly<{\n name: 'purchase';\n transactionId: string;\n value: AnalyticsMoney;\n items?: readonly AnalyticsLineItem[];\n}>;\n\nexport type AnalyticsEvent = AddPaymentInfoEvent | PurchaseEvent;\n\nexport type AnalyticsActions = Readonly<{\n /** Push a standard analytics event to window.dataLayer. Fire-and-forget; never throws. */\n track: (event: AnalyticsEvent) => void;\n}>;\n\n/** The shape pushed onto window.dataLayer — GTM/GA4's own event convention. */\nexport type AnalyticsDataLayerEvent = Readonly<{\n event: 'add_payment_info' | 'purchase';\n ecommerce: Record<string, unknown>;\n}>;\n\nfunction toEcommerceItems(items: readonly AnalyticsLineItem[] | undefined) {\n return (items ?? []).map((item) => ({\n item_id: item.sku,\n item_name: item.name,\n price: item.price.amount,\n quantity: item.quantity,\n }));\n}\n\nfunction toEcommercePayload(event: AnalyticsEvent): Record<string, unknown> {\n if (event.name === 'add_payment_info') {\n return {\n currency: event.value.currencyCode,\n value: event.value.amount,\n // T140, Decision 5: the key itself must be absent when `paymentType` is, not merely `undefined`\n // — `pushToDataLayer` pushes this object as-is with no serialization step to strip it, and\n // `'payment_type' in ecommerce` would otherwise still report true.\n ...(event.paymentType !== undefined ? { payment_type: event.paymentType } : {}),\n items: toEcommerceItems(event.items),\n };\n }\n return {\n transaction_id: event.transactionId,\n currency: event.value.currencyCode,\n value: event.value.amount,\n items: toEcommerceItems(event.items),\n };\n}\n\n// `Reflect.get`/`Reflect.set` below match `storefront-provider.tsx`'s existing pattern for a\n// dynamic `window` key — they are not a security mechanism. `Reflect.set(target, k, v)` invokes\n// an inherited setter and creates no own property, exactly like `window[k] = v` would; it adds no\n// hardening on its own. What actually blocks prototype pollution is\n// `isValidAnalyticsDestination`'s denylist and identifier pattern, checked by the caller before\n// `destination` ever reaches this function, plus the non-array guard immediately below.\n//\n// The cast below, not a `declare global` augmentation of `Window`, is what keeps this typed: a\n// global augmentation here would ship inside this package's own `.d.ts` output and hand every\n// consumer's `window.dataLayer` this package's narrow event union, wrong for a store that also\n// pushes its own GTM events (packages/components/scripts/dist-type-boundary.test.ts). `destination`\n// is a runtime string anyway — `Window` has nothing to look up a dynamic key against — so the local\n// cast is also the only type-safe option, not merely the non-leaking one.\nfunction pushToDataLayer(event: AnalyticsEvent, destination: AnalyticsDestination): void {\n if (typeof window === 'undefined') return;\n\n let layer = Reflect.get(window, destination) as AnalyticsDataLayerEvent[] | undefined;\n if (layer === undefined) {\n layer = [];\n Reflect.set(window, destination, layer);\n } else if (!Array.isArray(layer)) {\n console.error(`[analytics.track] window.${destination} already exists and is not an array; the event was dropped`);\n return;\n }\n\n layer.push({ event: event.name, ecommerce: toEcommercePayload(event) });\n}\n\n/**\n * The `analytics` namespace hook. Registered with the first-party action registry via\n * `analyticsActions` below; the compiler-emitted `AnalyticsActionProvider` calls it and threads\n * the narrowed methods into each consumer's `$actions.analytics`. Dispatcher flavor: no\n * `useMutation`, no cache read or write (ADR-0010). Fire-and-forget — `track` never throws, so a\n * broken tag-manager script can never block payment submission or order placement.\n */\nexport function useAnalyticsActions(): AnalyticsActions {\n const override = useAnalyticsDestination();\n // Scoped to this hook instance, not the module: \"logs once\" means once per mounted\n // `useAnalyticsActions()`, so two independent call sites each still get their own first warning.\n const hasLoggedRejectionRef = useRef(false);\n\n const track = useCallback<AnalyticsActions['track']>(\n (event) => {\n // The SSR guard runs before any destination resolution is attempted — not just before the\n // write. Preserved from the pre-T120 behaviour (US-3, \"SSR — no destination resolution\n // attempted at all\").\n if (typeof window === 'undefined') return;\n let destination: AnalyticsDestination = DEFAULT_ANALYTICS_DESTINATION;\n try {\n destination = resolveAnalyticsDestination({\n override,\n hasLoggedRejection: hasLoggedRejectionRef,\n });\n pushToDataLayer(event, destination);\n } catch (error) {\n console.error(`[analytics.track] window.${destination} push failed`, loggableErrorName(error));\n }\n },\n [override],\n );\n\n return useMemo(() => ({ track }), [track]);\n}\n\n/**\n * Declares the `analytics` action namespace — the single source of truth for its method/payload\n * metadata, runtime provider, and `use` hook (mirrors `cartActions`, `shippingActions`). The\n * native catalog builder (`scripts/build-catalog.mjs`) statically reads this call to emit\n * `actions.json`; at runtime `AnalyticsActionProvider` calls `useAnalyticsActions` directly.\n *\n * The `payload` below is a flattened, best-effort scalar approximation of `AnalyticsEvent` for\n * catalog/docs tooling: `ActionPayloadField.type` supports only scalar primitives and cannot\n * express a discriminated union or a nested `items` array. The TS `AnalyticsEvent` union above is\n * the source of truth for the real call shape.\n */\nexport const analyticsActions = defineActions({\n namespace: 'analytics',\n description:\n 'Dispatcher-flavor namespace that pushes standard add_payment_info / purchase events to window.dataLayer. Never touches the Apollo cache.',\n provider: { name: 'AnalyticsActionProvider', importPath: '@vtex/faststore/internal/client' },\n methods: {\n track: {\n description:\n 'Push a standard analytics event (add_payment_info | purchase) to window.dataLayer. Fire-and-forget; never throws.',\n payload: [\n { name: 'name', type: 'string' },\n { name: 'currencyCode', type: 'string' },\n { name: 'amount', type: 'number' },\n { name: 'paymentType', type: 'string', optional: true },\n { name: 'transactionId', type: 'string', optional: true },\n ],\n },\n },\n use: useAnalyticsActions,\n});\n"],"mappings":";;;;;;;AA8EA,SAAS,iBAAiB,OAAiD;CACzE,QAAQ,SAAS,CAAC,EAAA,CAAG,KAAK,UAAU;EAClC,SAAS,KAAK;EACd,WAAW,KAAK;EAChB,OAAO,KAAK,MAAM;EAClB,UAAU,KAAK;CACjB,EAAE;AACJ;AAEA,SAAS,mBAAmB,OAAgD;CAC1E,IAAI,MAAM,SAAS,oBACjB,OAAO;EACL,UAAU,MAAM,MAAM;EACtB,OAAO,MAAM,MAAM;EAInB,GAAI,MAAM,gBAAgB,KAAA,IAAY,EAAE,cAAc,MAAM,YAAY,IAAI,CAAC;EAC7E,OAAO,iBAAiB,MAAM,KAAK;CACrC;CAEF,OAAO;EACL,gBAAgB,MAAM;EACtB,UAAU,MAAM,MAAM;EACtB,OAAO,MAAM,MAAM;EACnB,OAAO,iBAAiB,MAAM,KAAK;CACrC;AACF;AAeA,SAAS,gBAAgB,OAAuB,aAAyC;CACvF,IAAI,OAAO,WAAW,aAAa;CAEnC,IAAI,QAAQ,QAAQ,IAAI,QAAQ,WAAW;CAC3C,IAAI,UAAU,KAAA,GAAW;EACvB,QAAQ,CAAC;EACT,QAAQ,IAAI,QAAQ,aAAa,KAAK;CACxC,OAAO,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;EAChC,QAAQ,MAAM,4BAA4B,YAAY,2DAA2D;EACjH;CACF;CAEA,MAAM,KAAK;EAAE,OAAO,MAAM;EAAM,WAAW,mBAAmB,KAAK;CAAE,CAAC;AACxE;;;;;;;;AASA,SAAgB,sBAAwC;CACtD,MAAM,WAAW,wBAAwB;CAGzC,MAAM,wBAAwB,OAAO,KAAK;CAE1C,MAAM,QAAQ,aACX,UAAU;EAIT,IAAI,OAAO,WAAW,aAAa;EACnC,IAAI,cAAoC;EACxC,IAAI;GACF,cAAc,4BAA4B;IACxC;IACA,oBAAoB;GACtB,CAAC;GACD,gBAAgB,OAAO,WAAW;EACpC,SAAS,OAAO;GACd,QAAQ,MAAM,4BAA4B,YAAY,eAAe,kBAAkB,KAAK,CAAC;EAC/F;CACF,GACA,CAAC,QAAQ,CACX;CAEA,OAAO,eAAe,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC;AAC3C;AAagC,cAAc;CAC5C,WAAW;CACX,aACE;CACF,UAAU;EAAE,MAAM;EAA2B,YAAY;CAAkC;CAC3F,SAAS,EACP,OAAO;EACL,aACE;EACF,SAAS;GACP;IAAE,MAAM;IAAQ,MAAM;GAAS;GAC/B;IAAE,MAAM;IAAgB,MAAM;GAAS;GACvC;IAAE,MAAM;IAAU,MAAM;GAAS;GACjC;IAAE,MAAM;IAAe,MAAM;IAAU,UAAU;GAAK;GACtD;IAAE,MAAM;IAAiB,MAAM;IAAU,UAAU;GAAK;EAC1D;CACF,EACF;CACA,KAAK;AACP,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-cart-actions.js","names":[],"sources":["../../../src/sdk/cart/use-cart-actions.ts"],"sourcesContent":["'use client';\n\nimport type { ApolloClient } from '@apollo/client';\nimport { useApolloClient, useMutation } from '@apollo/client/react';\nimport { defineActions } from '@vtex/fs-core';\nimport { useCallback, useMemo } from 'react';\nimport { loggableErrorName } from '../../utils/loggable-error-name.js';\nimport { cartCouponErrorsVar, cartLastAddVar, cartUserErrorsVar, orderFormIdVar } from '../state/cart.js';\nimport {\n CART_COUPON_APPLY,\n CART_COUPON_REMOVE,\n CART_ITEM_ADD,\n CART_ITEM_QUANTITY_DECREASE,\n CART_ITEM_QUANTITY_INCREASE,\n CART_ITEM_REMOVE,\n CART_ITEMS_REMOVE,\n CART_SALES_CHANNEL_SYNC,\n CART_VALIDATE,\n type CartEntity,\n CartFragment,\n type CartFreeShippingProgress,\n CartFreeShippingProgressFragment,\n type CartItemEntity,\n type CartUserError,\n} from './operations.js';\nimport {\n buildOptimisticDecrease,\n buildOptimisticIncrease,\n buildOptimisticRemove,\n buildOptimisticRemoveItems,\n} from './optimistic.js';\nimport { markAvailabilityFresh, trackCartWrite } from './write-gate.js';\n\n/**\n * The `cart` action namespace — the consolidated, context-free owner of every cart write\n * (docs/storefront-core/reference-free-particle-model.md § The cart write contract, docs/storefront-core/adr-0010-actions-own-the-write-side.md).\n *\n * It replaces `useCartMutations` + the mutation handlers `CartRoot` used to publish through\n * `CartDataContext`. A handler reads the current cart from the normalized Apollo cache (keyed by\n * `orderFormIdVar`), not from component props or React context, so any component anywhere in the\n * tree can dispatch a write through the compiler-injected `$actions.cart.*` prop — the cache is the\n * only meeting point between the read side and the write side (ADR-0010).\n *\n * `userErrors` from every call are published to `cartUserErrorsVar` (coupon writes to `cartCouponErrorsVar`)\n * so `CartError` and `CartCouponError` can surface them without a data context, and also returned to the\n * caller. Each write clears only its own channel as it starts (item writes `cartUserErrorsVar`, coupon\n * writes `cartCouponErrorsVar`), `validate` clears neither, and a CartRoot mount clears both; the mount\n * clear lives in `CartRoot`, because this hook mounts once per consumer element and cannot see a page mount.\n */\n\n/**\n * Thrown by the existing-line handlers (remove / quantity) when invoked before the cart resolves.\n * The first `addItem` mints the cart and hydrates `orderFormIdVar`; until then there is no cached\n * cart entity to read for the optimistic response.\n */\nexport class CartNotReadyError extends Error {\n constructor(message?: string) {\n super(message ?? 'CartNotReadyError: no cart in cache yet; add an item (or load the cart) before mutating a line.');\n this.name = 'CartNotReadyError';\n }\n}\n\nexport type AddItemPayload = Readonly<{\n variantId: string;\n quantity?: number;\n /** Seller global Node ID, e.g. base64(\"Seller:1\"). The server rejects raw ids with INVALID_SELLER_ID. */\n seller: string;\n}>;\n\n/** Existing-line payloads address the line by its opaque cart-item `id`; the handler reads the rest from cache. */\nexport type CartLinePayload = Readonly<{ id: string }>;\n\n/** Batch payloads address several lines by their opaque cart-item `id`s. */\nexport type CartLinesPayload = Readonly<{ ids: readonly string[] }>;\n\nexport type CartQuantityPayload = Readonly<{ id: string; by?: number }>;\n\n/** Coupon writes address the coupon by its `code`; the server resolves the cart from the cookie. */\nexport type CartCouponPayload = Readonly<{ code: string }>;\n\n/**\n * The `cart` namespace surface. Item writes return the resulting `userErrors` (empty on success)\n * and publish them to `cartUserErrorsVar`; coupon writes publish to the dedicated\n * `cartCouponErrorsVar` (docs/storefront-core/reference-free-particle-model.md § The cart write contract).\n */\nexport type CartActions = Readonly<{\n /** Add an item to the cart. Async (no optimistic response). Creates the cart on first add. */\n addItem: (payload: AddItemPayload) => Promise<readonly CartUserError[]>;\n /** Remove a line entirely. Optimistic. */\n removeItem: (payload: CartLinePayload) => Promise<readonly CartUserError[]>;\n /** Remove several lines in one mutation. Optimistic. Ids missing from the cache are skipped. */\n removeItems: (payload: CartLinesPayload) => Promise<readonly CartUserError[]>;\n /** Increase a line's quantity by N (default 1). Optimistic. */\n increaseQuantity: (payload: CartQuantityPayload) => Promise<readonly CartUserError[]>;\n /** Decrease a line's quantity by N (default 1). Optimistic. Removes the line when result <= 0. */\n decreaseQuantity: (payload: CartQuantityPayload) => Promise<readonly CartUserError[]>;\n /** Apply a coupon code. Async (no optimistic). Publishes userErrors to cartCouponErrorsVar. */\n applyCoupon: (payload: CartCouponPayload) => Promise<readonly CartUserError[]>;\n /** Remove a coupon code by code. Async (no optimistic). Publishes userErrors to cartCouponErrorsVar. */\n removeCoupon: (payload: CartCouponPayload) => Promise<readonly CartUserError[]>;\n /**\n * Re-check the active cart against the platform and adopt corrected availability. Async (no\n * optimistic), read-only upstream. Returns userErrors (empty on success) to its caller and stamps\n * the freshness window on success. Unlike the item writes it does NOT publish to\n * `cartUserErrorsVar` — a speculative open-time failure must raise no error banner (Decision 6).\n */\n validate: () => Promise<readonly CartUserError[]>;\n /**\n * Move the active cart onto the request's sales channel and reconcile its locale. Async (no\n * optimistic). Returns userErrors (empty on success) and stamps the freshness window on success.\n * Does not publish to `cartUserErrorsVar`: a background failure must raise no error banner.\n * Registers as an in-flight write so a stock check skips while it runs.\n */\n syncSalesChannel: () => Promise<readonly CartUserError[]>;\n}>;\n\nconst NETWORK_USER_ERROR: CartUserError = {\n code: 'NETWORK_ERROR',\n message: 'Unable to update cart. Please try again.',\n};\n\nfunction publish(errors: readonly CartUserError[]): readonly CartUserError[] {\n cartUserErrorsVar(errors);\n return errors;\n}\n\n/** Coupon-scoped publish — keeps coupon feedback off the shared item-error channel (AD-2). */\nfunction publishCoupon(errors: readonly CartUserError[]): readonly CartUserError[] {\n cartCouponErrorsVar(errors);\n return errors;\n}\n\n/**\n * Publish a write's outcome and, when it came back clean, stamp the availability freshness window —\n * a clean write's payload carries the platform's recomputed cart, which is what lets the\n * validate-on-open call skip (docs/storefront-core/reference-free-particle-model.md § The cart write contract). Used only on paths\n * where a mutation actually reached the server: a `userErrors` response carries `cart: null` and a\n * no-op (unknown line) issues no request, so neither refreshes availability.\n */\nfunction publishWrite(errors: readonly CartUserError[]): readonly CartUserError[] {\n if (errors.length === 0) markAvailabilityFresh();\n return publish(errors);\n}\n\n/** Coupon-channel counterpart of `publishWrite`. */\nfunction publishCouponWrite(errors: readonly CartUserError[]): readonly CartUserError[] {\n if (errors.length === 0) markAvailabilityFresh();\n return publishCoupon(errors);\n}\n\n/**\n * Backfill `orderFormIdVar` from a mutation's returned `cart.id` when local state is still cold.\n * A coupon op can be the first cart write (SSR cold / drawer closed on first load); without this the\n * later `requireLine` paths short-circuit on `orderFormIdVar() === null` and throw `CartNotReadyError`.\n * Mirrors the `addItem` first-add handoff.\n */\nfunction hydrateCartId(cartId: string | null): void {\n if (cartId && orderFormIdVar() === null) orderFormIdVar(cartId);\n}\n\n/**\n * Read the live cart entity from the normalized cache (ADR-0010), keyed by `orderFormIdVar`. Returns\n * null before the cart is minted/loaded. Module-level so it can be shared with the read-only callers\n * that live outside this hook — the pre-checkout gate re-reads the corrected cart this way after\n * `validate` resolves, because Apollo commits the mutation's cache write before the promise settles\n * (docs/storefront-core/reference-cart.md § Validation). The codegen `CartFragment` document embeds its\n * nested fragments, so it is a self-contained read.\n */\nexport function readCartFromCache(client: ApolloClient): CartEntity | null {\n const cartId = orderFormIdVar();\n if (!cartId) return null;\n const cacheId = client.cache.identify({ __typename: 'Cart', id: cartId });\n if (!cacheId) return null;\n return (\n client.cache.readFragment<CartEntity>({ id: cacheId, fragment: CartFragment, fragmentName: 'CartFragment' }) ?? null\n );\n}\n\ntype CartWithProgress = CartEntity & { freeShippingProgress: CartFreeShippingProgress };\n\n/**\n * The line writes carry the cached `freeShippingProgress` into their optimistic response. It lives\n * outside `CartFragment` (only the line writes select it), so a cart the page read did not select it\n * for, or one never fetched, reads as `null`. The progress is read through the optimistic layers: a\n * second line write started while a drop is pending must see the hidden prediction, not the cached\n * \"qualified\" value underneath it, or its own layer would put the bar back.\n */\nfunction readCartWithProgress(client: ApolloClient): CartWithProgress | null {\n const cart = readCartFromCache(client);\n if (!cart) return null;\n const data = client.cache.readFragment<{ freeShippingProgress: CartFreeShippingProgress }>({\n id: client.cache.identify({ __typename: 'Cart', id: cart.id }),\n fragment: CartFreeShippingProgressFragment,\n fragmentName: 'CartFreeShippingProgressFragment',\n optimistic: true,\n });\n return { ...cart, freeShippingProgress: data?.freeShippingProgress ?? null };\n}\n\n/**\n * The `cart` namespace hook. Registered with the first-party action registry via `cartActions`\n * below; the compiler-emitted `CartActionProvider` calls it and threads the narrowed methods into\n * each consumer's `$actions.cart`.\n */\nexport function useCartActions(): CartActions {\n const client = useApolloClient();\n\n const [addMutation] = useMutation(CART_ITEM_ADD);\n const [removeMutation] = useMutation(CART_ITEM_REMOVE);\n const [removeItemsMutation] = useMutation(CART_ITEMS_REMOVE);\n const [increaseMutation] = useMutation(CART_ITEM_QUANTITY_INCREASE);\n const [decreaseMutation] = useMutation(CART_ITEM_QUANTITY_DECREASE);\n const [applyCouponMutation] = useMutation(CART_COUPON_APPLY);\n const [removeCouponMutation] = useMutation(CART_COUPON_REMOVE);\n const [validateMutation] = useMutation(CART_VALIDATE);\n const [syncMutation] = useMutation(CART_SALES_CHANNEL_SYNC);\n\n const readCartForLineWrite = useCallback((): CartWithProgress | null => readCartWithProgress(client), [client]);\n\n const requireLine = useCallback(\n (id: string): { cart: CartWithProgress; line: CartItemEntity } | null => {\n const cart = readCartForLineWrite();\n if (!cart) throw new CartNotReadyError();\n const line = cart.items.find((item) => item.id === id);\n if (!line) return null;\n return { cart, line };\n },\n [readCartForLineWrite],\n );\n\n const addItem = useCallback<CartActions['addItem']>(\n async (payload) => {\n cartUserErrorsVar([]);\n try {\n const result = await trackCartWrite(\n addMutation({\n variables: {\n input: { variantId: payload.variantId, quantity: payload.quantity ?? 1, seller: payload.seller },\n },\n }),\n );\n // Very-first add: the server minted a cart from the empty transport context. Hydrate the\n // var so the existing-line handlers unlock without requiring a cart query.\n if (orderFormIdVar() === null) {\n const newId = result.data?.cartItemAdd?.cart?.id ?? null;\n if (newId) orderFormIdVar(newId);\n }\n const errors = result.data?.cartItemAdd?.userErrors ?? [];\n // Bump the add-success pulse only on the clean branch; the post-add behavior components\n // (CartOpenOnAdd / CartRedirectOnAdd) key their effect on it. The userErrors and\n // network-catch branches leave it untouched (docs/storefront-core/reference-free-particle-model.md § The cart write contract).\n if (errors.length === 0) cartLastAddVar(cartLastAddVar() + 1);\n return publishWrite(errors);\n } catch (error) {\n console.error('[cart.addItem] cartItemAdd failed', loggableErrorName(error));\n return publish([NETWORK_USER_ERROR]);\n }\n },\n [addMutation],\n );\n\n const removeItem = useCallback<CartActions['removeItem']>(\n async (payload) => {\n const found = requireLine(payload.id);\n if (!found) return publish([]);\n cartUserErrorsVar([]);\n try {\n const result = await trackCartWrite(\n removeMutation({\n variables: { input: { lineId: found.line.lineId } },\n optimisticResponse: buildOptimisticRemove(found.cart, found.line),\n }),\n );\n return publishWrite(result.data?.cartItemRemove?.userErrors ?? []);\n } catch (error) {\n console.error('[cart.removeItem] cartItemRemove failed', loggableErrorName(error));\n return publish([NETWORK_USER_ERROR]);\n }\n },\n [requireLine, removeMutation],\n );\n\n const removeItems = useCallback<CartActions['removeItems']>(\n async (payload) => {\n const cart = readCartForLineWrite();\n if (!cart) throw new CartNotReadyError();\n // Client-side tolerance mirroring removeItem's not-found no-op: ids without a cached line\n // are skipped, and a repeated id resolves to its one line. Each line is sent by its own\n // `lineId`: two lines of one SKU stay two entries.\n const lines = cart.items.filter((item) => payload.ids.includes(item.id));\n if (lines.length === 0) return publish([]);\n const lineIds = lines.map((line) => line.lineId);\n cartUserErrorsVar([]);\n try {\n const result = await trackCartWrite(\n removeItemsMutation({\n variables: { input: { lineIds } },\n optimisticResponse: buildOptimisticRemoveItems(cart, lines),\n }),\n );\n return publishWrite(result.data?.cartItemsRemove?.userErrors ?? []);\n } catch (error) {\n console.error('[cart.removeItems] cartItemsRemove failed', loggableErrorName(error));\n return publish([NETWORK_USER_ERROR]);\n }\n },\n [readCartForLineWrite, removeItemsMutation],\n );\n\n const increaseQuantity = useCallback<CartActions['increaseQuantity']>(\n async (payload) => {\n const by = payload.by ?? 1;\n const found = requireLine(payload.id);\n if (!found) return publish([]);\n cartUserErrorsVar([]);\n try {\n const result = await trackCartWrite(\n increaseMutation({\n variables: { input: { lineId: found.line.lineId, quantityToAdd: by } },\n optimisticResponse: buildOptimisticIncrease(found.cart, found.line, by),\n }),\n );\n return publishWrite(result.data?.cartItemQuantityIncrease?.userErrors ?? []);\n } catch (error) {\n console.error('[cart.increaseQuantity] cartItemQuantityIncrease failed', loggableErrorName(error));\n return publish([NETWORK_USER_ERROR]);\n }\n },\n [requireLine, increaseMutation],\n );\n\n const decreaseQuantity = useCallback<CartActions['decreaseQuantity']>(\n async (payload) => {\n const by = payload.by ?? 1;\n const found = requireLine(payload.id);\n if (!found) return publish([]);\n cartUserErrorsVar([]);\n try {\n const result = await trackCartWrite(\n decreaseMutation({\n variables: { input: { lineId: found.line.lineId, quantityToRemove: by } },\n optimisticResponse: buildOptimisticDecrease(found.cart, found.line, by),\n }),\n );\n return publishWrite(result.data?.cartItemQuantityDecrease?.userErrors ?? []);\n } catch (error) {\n console.error('[cart.decreaseQuantity] cartItemQuantityDecrease failed', loggableErrorName(error));\n return publish([NETWORK_USER_ERROR]);\n }\n },\n [requireLine, decreaseMutation],\n );\n\n // Coupons are cart-level: no `requireLine` gate (AD-9). No optimistic response and no client\n // rollback — totals and `isUnmatchedCondition` are server-computed and the server rolls back its\n // own single-coupon rejections; the returned cart (spreading the extended CartFragment)\n // self-updates the cache and every reactive subscriber (docs/storefront-core/reference-free-particle-model.md § The cart write contract).\n const applyCoupon = useCallback<CartActions['applyCoupon']>(\n async (payload) => {\n cartCouponErrorsVar([]);\n try {\n const result = await trackCartWrite(applyCouponMutation({ variables: { input: { code: payload.code } } }));\n hydrateCartId(result.data?.cartCouponApply?.cart?.id ?? null);\n return publishCouponWrite(result.data?.cartCouponApply?.userErrors ?? []);\n } catch (error) {\n console.error('[cart.applyCoupon] cartCouponApply failed', loggableErrorName(error));\n return publishCoupon([NETWORK_USER_ERROR]);\n }\n },\n [applyCouponMutation],\n );\n\n const removeCoupon = useCallback<CartActions['removeCoupon']>(\n async (payload) => {\n cartCouponErrorsVar([]);\n try {\n const result = await trackCartWrite(removeCouponMutation({ variables: { input: { code: payload.code } } }));\n hydrateCartId(result.data?.cartCouponRemove?.cart?.id ?? null);\n return publishCouponWrite(result.data?.cartCouponRemove?.userErrors ?? []);\n } catch (error) {\n console.error('[cart.removeCoupon] cartCouponRemove failed', loggableErrorName(error));\n return publishCoupon([NETWORK_USER_ERROR]);\n }\n },\n [removeCouponMutation],\n );\n\n // Read-only upstream (docs/storefront-core/reference-free-particle-model.md § The cart write contract): re-simulates the cart and returns it\n // with `variant.availability` corrected, spreading CartFragment so the guard, the per-line alert,\n // and the badge re-render off the cache. Deliberately unlike the item writes: it does NOT register\n // as an in-flight write (it would gate itself) and it does NOT publish to cartUserErrorsVar — the\n // open call is speculative and the pre-checkout call is fail-open, so a failure must raise no error\n // banner (Decision 6). It stamps the freshness window on success so open-on-add does not re-check.\n const validate = useCallback<CartActions['validate']>(async () => {\n try {\n const result = await validateMutation();\n // Hydrate as the coupon writes do: the corrected cart is now in the cache, and the pre-checkout\n // gate finds it by `orderFormIdVar`. Without this a cold var would leave the gate reading null\n // and passing a cart it never actually checked.\n hydrateCartId(result.data?.cartValidate?.cart?.id ?? null);\n const errors = result.data?.cartValidate?.userErrors ?? [];\n if (errors.length === 0) markAvailabilityFresh();\n return errors;\n } catch (error) {\n console.error('[cart.validate] cartValidate failed', loggableErrorName(error));\n return [NETWORK_USER_ERROR];\n }\n }, [validateMutation]);\n\n // Same outcome rules as `validate` (stamp freshness only when userErrors is empty, never publish),\n // except this write registers: a stock check must skip while the channel move is in flight.\n const syncSalesChannel = useCallback<CartActions['syncSalesChannel']>(async () => {\n try {\n const result = await trackCartWrite(syncMutation());\n hydrateCartId(result.data?.cartSalesChannelSync?.cart?.id ?? null);\n const errors = result.data?.cartSalesChannelSync?.userErrors ?? [];\n if (errors.length === 0) markAvailabilityFresh();\n return errors;\n } catch (error) {\n console.error('[cart.syncSalesChannel] cartSalesChannelSync failed', loggableErrorName(error));\n return [NETWORK_USER_ERROR];\n }\n }, [syncMutation]);\n\n return useMemo(\n () => ({\n addItem,\n removeItem,\n removeItems,\n increaseQuantity,\n decreaseQuantity,\n applyCoupon,\n removeCoupon,\n validate,\n syncSalesChannel,\n }),\n [\n addItem,\n removeItem,\n removeItems,\n increaseQuantity,\n decreaseQuantity,\n applyCoupon,\n removeCoupon,\n validate,\n syncSalesChannel,\n ],\n );\n}\n\n/**\n * Declares the `cart` action namespace — the single source of truth for its method/payload metadata,\n * runtime provider, and `use` hook (mirrors `defineComponent`). The native catalog builder\n * (`@vtex/faststore-catalog`'s `buildPackageCatalog`) statically reads this call to emit `actions.json`;\n * at runtime `CartActionProvider` calls `useCartActions` directly.\n */\nexport const cartActions = defineActions({\n namespace: 'cart',\n description: 'Mutation-backed writes against the current cart (consolidates useCartMutations / CartRoot).',\n provider: { name: 'CartActionProvider', importPath: '@vtex/faststore/internal/client' },\n methods: {\n addItem: {\n description: 'Add an item to the cart (async strategy). Creates the cart on first add.',\n payload: [\n { name: 'variantId', type: 'string' },\n { name: 'seller', type: 'string' },\n { name: 'quantity', type: 'number', optional: true },\n ],\n },\n removeItem: {\n description: 'Remove a line from the cart (optimistic strategy).',\n payload: [{ name: 'id', type: 'string' }],\n },\n removeItems: {\n description: 'Remove several lines from the cart in one call (optimistic strategy).',\n payload: [{ name: 'ids', type: 'string[]' }],\n },\n increaseQuantity: {\n description: \"Increase a line's quantity by N (default 1, optimistic strategy).\",\n payload: [\n { name: 'id', type: 'string' },\n { name: 'by', type: 'number', optional: true },\n ],\n },\n decreaseQuantity: {\n description: \"Decrease a line's quantity by N (default 1, optimistic). Removes the line at <= 0.\",\n payload: [\n { name: 'id', type: 'string' },\n { name: 'by', type: 'number', optional: true },\n ],\n },\n applyCoupon: {\n description: 'Apply a coupon code to the cart (async strategy). Server recomputes totals.',\n payload: [{ name: 'code', type: 'string' }],\n },\n removeCoupon: {\n description: 'Remove a coupon code from the cart (async strategy). Server recomputes totals.',\n payload: [{ name: 'code', type: 'string' }],\n },\n validate: {\n description:\n 'Re-check the active cart against the platform and adopt corrected availability (async, read-only upstream).',\n payload: [],\n },\n syncSalesChannel: {\n description: \"Moves the active cart onto the request's sales channel and reconciles its locale.\",\n payload: [],\n },\n },\n use: useCartActions,\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-cart-actions.js","names":[],"sources":["../../../src/sdk/cart/use-cart-actions.ts"],"sourcesContent":["'use client';\n\nimport type { ApolloClient } from '@apollo/client';\nimport { useApolloClient, useMutation } from '@apollo/client/react';\nimport { defineActions } from '@vtex/fs-core';\nimport { useCallback, useMemo } from 'react';\nimport { loggableErrorName } from '../../utils/loggable-error-name.js';\nimport { cartCouponErrorsVar, cartLastAddVar, cartUserErrorsVar, orderFormIdVar } from '../state/cart.js';\nimport {\n CART_COUPON_APPLY,\n CART_COUPON_REMOVE,\n CART_ITEM_ADD,\n CART_ITEM_QUANTITY_DECREASE,\n CART_ITEM_QUANTITY_INCREASE,\n CART_ITEM_REMOVE,\n CART_ITEMS_REMOVE,\n CART_SALES_CHANNEL_SYNC,\n CART_VALIDATE,\n type CartEntity,\n CartFragment,\n type CartFreeShippingProgress,\n CartFreeShippingProgressFragment,\n type CartItemEntity,\n type CartUserError,\n} from './operations.js';\nimport {\n buildOptimisticDecrease,\n buildOptimisticIncrease,\n buildOptimisticRemove,\n buildOptimisticRemoveItems,\n} from './optimistic.js';\nimport { markAvailabilityFresh, trackCartWrite } from './write-gate.js';\n\n/**\n * The `cart` action namespace — the consolidated, context-free owner of every cart write\n * (docs/storefront-core/reference-free-particle-model.md § The cart write contract, docs/storefront-core/adr-0010-actions-own-the-write-side.md).\n *\n * It replaces `useCartMutations` + the mutation handlers `CartRoot` used to publish through\n * `CartDataContext`. A handler reads the current cart from the normalized Apollo cache (keyed by\n * `orderFormIdVar`), not from component props or React context, so any component anywhere in the\n * tree can dispatch a write through the compiler-injected `$actions.cart.*` prop — the cache is the\n * only meeting point between the read side and the write side (ADR-0010).\n *\n * `userErrors` from every call are published to `cartUserErrorsVar` (coupon writes to `cartCouponErrorsVar`)\n * so `CartError` and `CartCouponError` can surface them without a data context, and also returned to the\n * caller. Each write clears only its own channel as it starts (item writes `cartUserErrorsVar`, coupon\n * writes `cartCouponErrorsVar`), `validate` clears neither, and a CartRoot mount clears both; the mount\n * clear lives in `CartRoot`, because this hook mounts once per consumer element and cannot see a page mount.\n */\n\n/**\n * Thrown by the existing-line handlers (remove / quantity) when invoked before the cart resolves.\n * The first `addItem` mints the cart and hydrates `orderFormIdVar`; until then there is no cached\n * cart entity to read for the optimistic response.\n */\nexport class CartNotReadyError extends Error {\n constructor(message?: string) {\n super(message ?? 'CartNotReadyError: no cart in cache yet; add an item (or load the cart) before mutating a line.');\n this.name = 'CartNotReadyError';\n }\n}\n\nexport type AddItemPayload = Readonly<{\n variantId: string;\n quantity?: number;\n /** Seller global Node ID, e.g. base64(\"Seller:1\"). The server rejects raw ids with INVALID_SELLER_ID. */\n seller: string;\n}>;\n\n/** Existing-line payloads address the line by its opaque cart-item `id`; the handler reads the rest from cache. */\nexport type CartLinePayload = Readonly<{ id: string }>;\n\n/** Batch payloads address several lines by their opaque cart-item `id`s. */\nexport type CartLinesPayload = Readonly<{ ids: readonly string[] }>;\n\nexport type CartQuantityPayload = Readonly<{ id: string; by?: number }>;\n\n/** Coupon writes address the coupon by its `code`; the server resolves the cart from the cookie. */\nexport type CartCouponPayload = Readonly<{ code: string }>;\n\n/**\n * The `cart` namespace surface. Item writes return the resulting `userErrors` (empty on success)\n * and publish them to `cartUserErrorsVar`; coupon writes publish to the dedicated\n * `cartCouponErrorsVar` (docs/storefront-core/reference-free-particle-model.md § The cart write contract).\n */\nexport type CartActions = Readonly<{\n /** Add an item to the cart. Async (no optimistic response). Creates the cart on first add. */\n addItem: (payload: AddItemPayload) => Promise<readonly CartUserError[]>;\n /** Remove a line entirely. Optimistic. */\n removeItem: (payload: CartLinePayload) => Promise<readonly CartUserError[]>;\n /** Remove several lines in one mutation. Optimistic. Ids missing from the cache are skipped. */\n removeItems: (payload: CartLinesPayload) => Promise<readonly CartUserError[]>;\n /** Increase a line's quantity by N (default 1). Optimistic. */\n increaseQuantity: (payload: CartQuantityPayload) => Promise<readonly CartUserError[]>;\n /** Decrease a line's quantity by N (default 1). Optimistic. Removes the line when result <= 0. */\n decreaseQuantity: (payload: CartQuantityPayload) => Promise<readonly CartUserError[]>;\n /** Apply a coupon code. Async (no optimistic). Publishes userErrors to cartCouponErrorsVar. */\n applyCoupon: (payload: CartCouponPayload) => Promise<readonly CartUserError[]>;\n /** Remove a coupon code by code. Async (no optimistic). Publishes userErrors to cartCouponErrorsVar. */\n removeCoupon: (payload: CartCouponPayload) => Promise<readonly CartUserError[]>;\n /**\n * Re-check the active cart against the platform and adopt corrected availability. Async (no\n * optimistic), read-only upstream. Returns userErrors (empty on success) to its caller and stamps\n * the freshness window on success. Unlike the item writes it does NOT publish to\n * `cartUserErrorsVar` — a speculative open-time failure must raise no error banner (Decision 6).\n */\n validate: () => Promise<readonly CartUserError[]>;\n /**\n * Move the active cart onto the request's sales channel and reconcile its locale. Async (no\n * optimistic). Returns userErrors (empty on success) and stamps the freshness window on success.\n * Does not publish to `cartUserErrorsVar`: a background failure must raise no error banner.\n * Registers as an in-flight write so a stock check skips while it runs.\n */\n syncSalesChannel: () => Promise<readonly CartUserError[]>;\n}>;\n\n// Diagnostic text for logs and callers: `CartError` and `CartCouponError` word this code from their own `$content`.\nconst NETWORK_USER_ERROR: CartUserError = {\n code: 'NETWORK_ERROR',\n message: 'Unable to update cart. Please try again.',\n};\n\nfunction publish(errors: readonly CartUserError[]): readonly CartUserError[] {\n cartUserErrorsVar(errors);\n return errors;\n}\n\n/** Coupon-scoped publish — keeps coupon feedback off the shared item-error channel (AD-2). */\nfunction publishCoupon(errors: readonly CartUserError[]): readonly CartUserError[] {\n cartCouponErrorsVar(errors);\n return errors;\n}\n\n/**\n * Publish a write's outcome and, when it came back clean, stamp the availability freshness window —\n * a clean write's payload carries the platform's recomputed cart, which is what lets the\n * validate-on-open call skip (docs/storefront-core/reference-free-particle-model.md § The cart write contract). Used only on paths\n * where a mutation actually reached the server: a `userErrors` response carries `cart: null` and a\n * no-op (unknown line) issues no request, so neither refreshes availability.\n */\nfunction publishWrite(errors: readonly CartUserError[]): readonly CartUserError[] {\n if (errors.length === 0) markAvailabilityFresh();\n return publish(errors);\n}\n\n/** Coupon-channel counterpart of `publishWrite`. */\nfunction publishCouponWrite(errors: readonly CartUserError[]): readonly CartUserError[] {\n if (errors.length === 0) markAvailabilityFresh();\n return publishCoupon(errors);\n}\n\n/**\n * Backfill `orderFormIdVar` from a mutation's returned `cart.id` when local state is still cold.\n * A coupon op can be the first cart write (SSR cold / drawer closed on first load); without this the\n * later `requireLine` paths short-circuit on `orderFormIdVar() === null` and throw `CartNotReadyError`.\n * Mirrors the `addItem` first-add handoff.\n */\nfunction hydrateCartId(cartId: string | null): void {\n if (cartId && orderFormIdVar() === null) orderFormIdVar(cartId);\n}\n\n/**\n * Read the live cart entity from the normalized cache (ADR-0010), keyed by `orderFormIdVar`. Returns\n * null before the cart is minted/loaded. Module-level so it can be shared with the read-only callers\n * that live outside this hook — the pre-checkout gate re-reads the corrected cart this way after\n * `validate` resolves, because Apollo commits the mutation's cache write before the promise settles\n * (docs/storefront-core/reference-cart.md § Validation). The codegen `CartFragment` document embeds its\n * nested fragments, so it is a self-contained read.\n */\nexport function readCartFromCache(client: ApolloClient): CartEntity | null {\n const cartId = orderFormIdVar();\n if (!cartId) return null;\n const cacheId = client.cache.identify({ __typename: 'Cart', id: cartId });\n if (!cacheId) return null;\n return (\n client.cache.readFragment<CartEntity>({ id: cacheId, fragment: CartFragment, fragmentName: 'CartFragment' }) ?? null\n );\n}\n\ntype CartWithProgress = CartEntity & { freeShippingProgress: CartFreeShippingProgress };\n\n/**\n * The line writes carry the cached `freeShippingProgress` into their optimistic response. It lives\n * outside `CartFragment` (only the line writes select it), so a cart the page read did not select it\n * for, or one never fetched, reads as `null`. The progress is read through the optimistic layers: a\n * second line write started while a drop is pending must see the hidden prediction, not the cached\n * \"qualified\" value underneath it, or its own layer would put the bar back.\n */\nfunction readCartWithProgress(client: ApolloClient): CartWithProgress | null {\n const cart = readCartFromCache(client);\n if (!cart) return null;\n const data = client.cache.readFragment<{ freeShippingProgress: CartFreeShippingProgress }>({\n id: client.cache.identify({ __typename: 'Cart', id: cart.id }),\n fragment: CartFreeShippingProgressFragment,\n fragmentName: 'CartFreeShippingProgressFragment',\n optimistic: true,\n });\n return { ...cart, freeShippingProgress: data?.freeShippingProgress ?? null };\n}\n\n/**\n * The `cart` namespace hook. Registered with the first-party action registry via `cartActions`\n * below; the compiler-emitted `CartActionProvider` calls it and threads the narrowed methods into\n * each consumer's `$actions.cart`.\n */\nexport function useCartActions(): CartActions {\n const client = useApolloClient();\n\n const [addMutation] = useMutation(CART_ITEM_ADD);\n const [removeMutation] = useMutation(CART_ITEM_REMOVE);\n const [removeItemsMutation] = useMutation(CART_ITEMS_REMOVE);\n const [increaseMutation] = useMutation(CART_ITEM_QUANTITY_INCREASE);\n const [decreaseMutation] = useMutation(CART_ITEM_QUANTITY_DECREASE);\n const [applyCouponMutation] = useMutation(CART_COUPON_APPLY);\n const [removeCouponMutation] = useMutation(CART_COUPON_REMOVE);\n const [validateMutation] = useMutation(CART_VALIDATE);\n const [syncMutation] = useMutation(CART_SALES_CHANNEL_SYNC);\n\n const readCartForLineWrite = useCallback((): CartWithProgress | null => readCartWithProgress(client), [client]);\n\n const requireLine = useCallback(\n (id: string): { cart: CartWithProgress; line: CartItemEntity } | null => {\n const cart = readCartForLineWrite();\n if (!cart) throw new CartNotReadyError();\n const line = cart.items.find((item) => item.id === id);\n if (!line) return null;\n return { cart, line };\n },\n [readCartForLineWrite],\n );\n\n const addItem = useCallback<CartActions['addItem']>(\n async (payload) => {\n cartUserErrorsVar([]);\n try {\n const result = await trackCartWrite(\n addMutation({\n variables: {\n input: { variantId: payload.variantId, quantity: payload.quantity ?? 1, seller: payload.seller },\n },\n }),\n );\n // Very-first add: the server minted a cart from the empty transport context. Hydrate the\n // var so the existing-line handlers unlock without requiring a cart query.\n if (orderFormIdVar() === null) {\n const newId = result.data?.cartItemAdd?.cart?.id ?? null;\n if (newId) orderFormIdVar(newId);\n }\n const errors = result.data?.cartItemAdd?.userErrors ?? [];\n // Bump the add-success pulse only on the clean branch; the post-add behavior components\n // (CartOpenOnAdd / CartRedirectOnAdd) key their effect on it. The userErrors and\n // network-catch branches leave it untouched (docs/storefront-core/reference-free-particle-model.md § The cart write contract).\n if (errors.length === 0) cartLastAddVar(cartLastAddVar() + 1);\n return publishWrite(errors);\n } catch (error) {\n console.error('[cart.addItem] cartItemAdd failed', loggableErrorName(error));\n return publish([NETWORK_USER_ERROR]);\n }\n },\n [addMutation],\n );\n\n const removeItem = useCallback<CartActions['removeItem']>(\n async (payload) => {\n const found = requireLine(payload.id);\n if (!found) return publish([]);\n cartUserErrorsVar([]);\n try {\n const result = await trackCartWrite(\n removeMutation({\n variables: { input: { lineId: found.line.lineId } },\n optimisticResponse: buildOptimisticRemove(found.cart, found.line),\n }),\n );\n return publishWrite(result.data?.cartItemRemove?.userErrors ?? []);\n } catch (error) {\n console.error('[cart.removeItem] cartItemRemove failed', loggableErrorName(error));\n return publish([NETWORK_USER_ERROR]);\n }\n },\n [requireLine, removeMutation],\n );\n\n const removeItems = useCallback<CartActions['removeItems']>(\n async (payload) => {\n const cart = readCartForLineWrite();\n if (!cart) throw new CartNotReadyError();\n // Client-side tolerance mirroring removeItem's not-found no-op: ids without a cached line\n // are skipped, and a repeated id resolves to its one line. Each line is sent by its own\n // `lineId`: two lines of one SKU stay two entries.\n const lines = cart.items.filter((item) => payload.ids.includes(item.id));\n if (lines.length === 0) return publish([]);\n const lineIds = lines.map((line) => line.lineId);\n cartUserErrorsVar([]);\n try {\n const result = await trackCartWrite(\n removeItemsMutation({\n variables: { input: { lineIds } },\n optimisticResponse: buildOptimisticRemoveItems(cart, lines),\n }),\n );\n return publishWrite(result.data?.cartItemsRemove?.userErrors ?? []);\n } catch (error) {\n console.error('[cart.removeItems] cartItemsRemove failed', loggableErrorName(error));\n return publish([NETWORK_USER_ERROR]);\n }\n },\n [readCartForLineWrite, removeItemsMutation],\n );\n\n const increaseQuantity = useCallback<CartActions['increaseQuantity']>(\n async (payload) => {\n const by = payload.by ?? 1;\n const found = requireLine(payload.id);\n if (!found) return publish([]);\n cartUserErrorsVar([]);\n try {\n const result = await trackCartWrite(\n increaseMutation({\n variables: { input: { lineId: found.line.lineId, quantityToAdd: by } },\n optimisticResponse: buildOptimisticIncrease(found.cart, found.line, by),\n }),\n );\n return publishWrite(result.data?.cartItemQuantityIncrease?.userErrors ?? []);\n } catch (error) {\n console.error('[cart.increaseQuantity] cartItemQuantityIncrease failed', loggableErrorName(error));\n return publish([NETWORK_USER_ERROR]);\n }\n },\n [requireLine, increaseMutation],\n );\n\n const decreaseQuantity = useCallback<CartActions['decreaseQuantity']>(\n async (payload) => {\n const by = payload.by ?? 1;\n const found = requireLine(payload.id);\n if (!found) return publish([]);\n cartUserErrorsVar([]);\n try {\n const result = await trackCartWrite(\n decreaseMutation({\n variables: { input: { lineId: found.line.lineId, quantityToRemove: by } },\n optimisticResponse: buildOptimisticDecrease(found.cart, found.line, by),\n }),\n );\n return publishWrite(result.data?.cartItemQuantityDecrease?.userErrors ?? []);\n } catch (error) {\n console.error('[cart.decreaseQuantity] cartItemQuantityDecrease failed', loggableErrorName(error));\n return publish([NETWORK_USER_ERROR]);\n }\n },\n [requireLine, decreaseMutation],\n );\n\n // Coupons are cart-level: no `requireLine` gate (AD-9). No optimistic response and no client\n // rollback — totals and `isUnmatchedCondition` are server-computed and the server rolls back its\n // own single-coupon rejections; the returned cart (spreading the extended CartFragment)\n // self-updates the cache and every reactive subscriber (docs/storefront-core/reference-free-particle-model.md § The cart write contract).\n const applyCoupon = useCallback<CartActions['applyCoupon']>(\n async (payload) => {\n cartCouponErrorsVar([]);\n try {\n const result = await trackCartWrite(applyCouponMutation({ variables: { input: { code: payload.code } } }));\n hydrateCartId(result.data?.cartCouponApply?.cart?.id ?? null);\n return publishCouponWrite(result.data?.cartCouponApply?.userErrors ?? []);\n } catch (error) {\n console.error('[cart.applyCoupon] cartCouponApply failed', loggableErrorName(error));\n return publishCoupon([NETWORK_USER_ERROR]);\n }\n },\n [applyCouponMutation],\n );\n\n const removeCoupon = useCallback<CartActions['removeCoupon']>(\n async (payload) => {\n cartCouponErrorsVar([]);\n try {\n const result = await trackCartWrite(removeCouponMutation({ variables: { input: { code: payload.code } } }));\n hydrateCartId(result.data?.cartCouponRemove?.cart?.id ?? null);\n return publishCouponWrite(result.data?.cartCouponRemove?.userErrors ?? []);\n } catch (error) {\n console.error('[cart.removeCoupon] cartCouponRemove failed', loggableErrorName(error));\n return publishCoupon([NETWORK_USER_ERROR]);\n }\n },\n [removeCouponMutation],\n );\n\n // Read-only upstream (docs/storefront-core/reference-free-particle-model.md § The cart write contract): re-simulates the cart and returns it\n // with `variant.availability` corrected, spreading CartFragment so the guard, the per-line alert,\n // and the badge re-render off the cache. Deliberately unlike the item writes: it does NOT register\n // as an in-flight write (it would gate itself) and it does NOT publish to cartUserErrorsVar — the\n // open call is speculative and the pre-checkout call is fail-open, so a failure must raise no error\n // banner (Decision 6). It stamps the freshness window on success so open-on-add does not re-check.\n const validate = useCallback<CartActions['validate']>(async () => {\n try {\n const result = await validateMutation();\n // Hydrate as the coupon writes do: the corrected cart is now in the cache, and the pre-checkout\n // gate finds it by `orderFormIdVar`. Without this a cold var would leave the gate reading null\n // and passing a cart it never actually checked.\n hydrateCartId(result.data?.cartValidate?.cart?.id ?? null);\n const errors = result.data?.cartValidate?.userErrors ?? [];\n if (errors.length === 0) markAvailabilityFresh();\n return errors;\n } catch (error) {\n console.error('[cart.validate] cartValidate failed', loggableErrorName(error));\n return [NETWORK_USER_ERROR];\n }\n }, [validateMutation]);\n\n // Same outcome rules as `validate` (stamp freshness only when userErrors is empty, never publish),\n // except this write registers: a stock check must skip while the channel move is in flight.\n const syncSalesChannel = useCallback<CartActions['syncSalesChannel']>(async () => {\n try {\n const result = await trackCartWrite(syncMutation());\n hydrateCartId(result.data?.cartSalesChannelSync?.cart?.id ?? null);\n const errors = result.data?.cartSalesChannelSync?.userErrors ?? [];\n if (errors.length === 0) markAvailabilityFresh();\n return errors;\n } catch (error) {\n console.error('[cart.syncSalesChannel] cartSalesChannelSync failed', loggableErrorName(error));\n return [NETWORK_USER_ERROR];\n }\n }, [syncMutation]);\n\n return useMemo(\n () => ({\n addItem,\n removeItem,\n removeItems,\n increaseQuantity,\n decreaseQuantity,\n applyCoupon,\n removeCoupon,\n validate,\n syncSalesChannel,\n }),\n [\n addItem,\n removeItem,\n removeItems,\n increaseQuantity,\n decreaseQuantity,\n applyCoupon,\n removeCoupon,\n validate,\n syncSalesChannel,\n ],\n );\n}\n\n/**\n * Declares the `cart` action namespace — the single source of truth for its method/payload metadata,\n * runtime provider, and `use` hook (mirrors `defineComponent`). The native catalog builder\n * (`@vtex/faststore-catalog`'s `buildPackageCatalog`) statically reads this call to emit `actions.json`;\n * at runtime `CartActionProvider` calls `useCartActions` directly.\n */\nexport const cartActions = defineActions({\n namespace: 'cart',\n description: 'Mutation-backed writes against the current cart (consolidates useCartMutations / CartRoot).',\n provider: { name: 'CartActionProvider', importPath: '@vtex/faststore/internal/client' },\n methods: {\n addItem: {\n description: 'Add an item to the cart (async strategy). Creates the cart on first add.',\n payload: [\n { name: 'variantId', type: 'string' },\n { name: 'seller', type: 'string' },\n { name: 'quantity', type: 'number', optional: true },\n ],\n },\n removeItem: {\n description: 'Remove a line from the cart (optimistic strategy).',\n payload: [{ name: 'id', type: 'string' }],\n },\n removeItems: {\n description: 'Remove several lines from the cart in one call (optimistic strategy).',\n payload: [{ name: 'ids', type: 'string[]' }],\n },\n increaseQuantity: {\n description: \"Increase a line's quantity by N (default 1, optimistic strategy).\",\n payload: [\n { name: 'id', type: 'string' },\n { name: 'by', type: 'number', optional: true },\n ],\n },\n decreaseQuantity: {\n description: \"Decrease a line's quantity by N (default 1, optimistic). Removes the line at <= 0.\",\n payload: [\n { name: 'id', type: 'string' },\n { name: 'by', type: 'number', optional: true },\n ],\n },\n applyCoupon: {\n description: 'Apply a coupon code to the cart (async strategy). Server recomputes totals.',\n payload: [{ name: 'code', type: 'string' }],\n },\n removeCoupon: {\n description: 'Remove a coupon code from the cart (async strategy). Server recomputes totals.',\n payload: [{ name: 'code', type: 'string' }],\n },\n validate: {\n description:\n 'Re-check the active cart against the platform and adopt corrected availability (async, read-only upstream).',\n payload: [],\n },\n syncSalesChannel: {\n description: \"Moves the active cart onto the request's sales channel and reconciles its locale.\",\n payload: [],\n },\n },\n use: useCartActions,\n});\n"],"mappings":"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"}
|
package/dist/sdk/data/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DataOverrideContext, useDataOverride } from "./data-override-context.js";
|
|
2
|
-
import { ListItemRefContext, useListItemRef } from "./list-item-ref-context.js";
|
|
3
|
-
import { PageReactiveDataRoot, ReactiveRootContext } from "./page-reactive-data-root.js";
|
|
4
2
|
import "./entity-resolution-context.js";
|
|
3
|
+
import { PageReactiveDataRoot, ReactiveRootContext } from "./page-reactive-data-root.js";
|
|
4
|
+
import { ListItemRefContext, useListItemRef } from "./list-item-ref-context.js";
|
|
5
5
|
import { HotDataProvider } from "./hot-data-provider.js";
|
|
6
6
|
import { MultipleReactiveDataProvider } from "./multiple-reactive-data-provider.js";
|
|
7
7
|
import { ReactiveDataProvider } from "./reactive-data-provider.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { DataOverrideContext } from "./data-override-context.js";
|
|
3
|
-
import { useListItemRef } from "./list-item-ref-context.js";
|
|
4
|
-
import { ReactiveRootContext } from "./page-reactive-data-root.js";
|
|
5
3
|
import { EntityResolutionContext } from "./entity-resolution-context.js";
|
|
4
|
+
import { ReactiveRootContext } from "./page-reactive-data-root.js";
|
|
5
|
+
import { useListItemRef } from "./list-item-ref-context.js";
|
|
6
6
|
import { useApolloClient, useFragment } from "@apollo/client/react";
|
|
7
7
|
import { useContext } from "react";
|
|
8
8
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -42,7 +42,7 @@ const documents = {
|
|
|
42
42
|
"\n mutation CartValidate {\n cartValidate {\n __typename\n cart {\n ...CartFragment\n }\n userErrors {\n code\n message\n }\n }\n }\n": CartValidateDocument,
|
|
43
43
|
"\n mutation CartSalesChannelSync {\n cartSalesChannelSync {\n __typename\n cart {\n ...CartFragment\n }\n userErrors {\n code\n message\n }\n }\n }\n": CartSalesChannelSyncDocument,
|
|
44
44
|
"\n fragment RegionFragment on Region {\n __typename\n id\n postalCode\n city\n }\n": RegionFragmentFragmentDoc,
|
|
45
|
-
"\n query CatalogRouteAlternates($path: String!) {\n catalogRoute(input: { path: $path }) {\n variants {\n locale\n path\n }\n }\n }\n": CatalogRouteAlternatesDocument,
|
|
45
|
+
"\n query CatalogRouteAlternates($path: String!) {\n catalogRoute(input: { path: $path }) {\n id\n variants {\n locale\n path\n }\n }\n }\n": CatalogRouteAlternatesDocument,
|
|
46
46
|
"\n fragment SessionFragment on Session {\n __typename\n id\n loggedIn\n canEditData\n isIdentified\n }\n": SessionFragmentFragmentDoc,
|
|
47
47
|
"\n query ServerSessionRead {\n session {\n ...SessionFragment\n }\n }\n": ServerSessionReadDocument,
|
|
48
48
|
"\n query AccountSessionRevalidate {\n session {\n ...SessionFragment\n }\n }\n": AccountSessionRevalidateDocument,
|