@wix/agent-skills 1.20.1 → 1.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/wix-app/SKILL.md +71 -113
- package/skills/wix-app/references/APP_TOOLS.md +2 -1
- package/skills/wix-app/references/BACKEND_EVENT.md +3 -3
- package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +41 -152
- package/skills/wix-app/references/DASHBOARD_MODAL.md +4 -4
- package/skills/wix-app/references/DASHBOARD_PAGE.md +11 -25
- package/skills/wix-app/references/DATA_COLLECTION.md +16 -219
- package/skills/wix-app/references/SDK_MODULE_MAP.md +44 -0
- package/skills/wix-app/references/SITE_PLUGIN.md +36 -190
- package/skills/wix-app/references/app-tools/TOOLS.md +3 -1
- package/skills/wix-app/references/custom-element-widget/SETTINGS_PANEL.md +21 -0
- package/skills/wix-app/references/dashboard-page/DATA_SOURCES.md +182 -0
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE.md +97 -0
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_COLLECTION.md +184 -0
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_ROUTER.md +203 -0
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_SETTINGS.md +44 -0
- package/skills/wix-app/references/dashboard-page/ECOM_NAVIGATION.md +17 -0
- package/skills/wix-app/references/dashboard-page/QUERY_AND_PAGING.md +182 -0
- package/skills/wix-app/references/dashboard-page/TABLE_STATE.md +133 -0
- package/skills/wix-app/references/dashboard-page/UX_SUCCESS_MODEL.md +10 -5
- package/skills/wix-app/references/dashboard-plugin/SLOTS.md +4 -18
- package/skills/wix-app/references/data-collection/LIFECYCLE.md +68 -0
- package/skills/wix-app/references/data-collection/PERMISSIONS.md +47 -0
- package/skills/wix-app/references/data-collection/SCHEMA.md +181 -0
- package/skills/wix-app/references/data-collection/WIX_DATA.md +38 -66
- package/skills/wix-app/references/site-plugin/EXAMPLES.md +1 -1
- package/skills/wix-headless-fast/SKILL.md +144 -221
- package/skills/wix-headless-fast/cold-start/bootstrap.mjs +156 -0
- package/skills/wix-headless-fast/{entry/skill.md → cold-start/cold-start.md} +15 -15
- package/skills/wix-headless-fast/guides/existing-site.md +76 -0
- package/skills/wix-headless-fast/guides/reference-mode.md +97 -0
- package/skills/wix-headless-fast/install/AGENTS.md +35 -0
- package/skills/wix-headless-fast/install/agents-md.mjs +39 -0
- package/skills/wix-headless-fast/install/attach.mjs +161 -86
- package/skills/wix-headless-fast/install/deploy.mjs +21 -60
- package/skills/wix-headless-fast/install/lock.mjs +55 -0
- package/skills/wix-headless-fast/install/setup.mjs +259 -0
- package/skills/wix-headless-fast/install/templates.mjs +168 -0
- package/skills/wix-manage/references/ecommerce/pricing-promotions/ecom-pricing-create-coupon.md +10 -19
- package/skills/wix-manage/references/events/create-wix-event.md +5 -1
- package/skills/wix-manage/references/google-ads/google-ads-dashboard-navigation.md +27 -0
- package/skills/wix-manage/references/google-ads/manage-campaign-success-guide.md +83 -37
- package/skills/wix-headless-fast/install/fast-path.mjs +0 -181
- package/skills/wix-headless-fast/references/blog/INSTRUCTIONS.md +0 -301
- package/skills/wix-headless-fast/references/blog/app/components/blog/BlogFeedView.tsx +0 -136
- package/skills/wix-headless-fast/references/blog/app/components/blog/PostView.tsx +0 -112
- package/skills/wix-headless-fast/references/blog/app/components/blog/RichContent.tsx +0 -42
- package/skills/wix-headless-fast/references/blog/app/hooks/blog/useBlogFeed.ts +0 -31
- package/skills/wix-headless-fast/references/blog/app/hooks/blog/usePost.ts +0 -22
- package/skills/wix-headless-fast/references/blog/app/wix/blog/blog-feed-store.ts +0 -137
- package/skills/wix-headless-fast/references/blog/app/wix/blog/post-store.ts +0 -78
- package/skills/wix-headless-fast/references/blog/app/wix/blog/posts-core.ts +0 -117
- package/skills/wix-headless-fast/references/blog/app/wix/blog/posts.ts +0 -52
- package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy-core.ts +0 -47
- package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy.ts +0 -58
- package/skills/wix-headless-fast/references/blog/app/wix/blog/types.ts +0 -62
- package/skills/wix-headless-fast/references/blog/app-astro/layouts/SiteLayout.astro +0 -40
- package/skills/wix-headless-fast/references/blog/app-astro/pages/blog/[...slug].astro +0 -97
- package/skills/wix-headless-fast/references/blog/app-astro/pages/blog.astro +0 -24
- package/skills/wix-headless-fast/references/blog/lock/astro/package-lock.json +0 -16156
- package/skills/wix-headless-fast/references/blog/rest/posts.ts +0 -42
- package/skills/wix-headless-fast/references/blog/rest/taxonomy.ts +0 -62
- package/skills/wix-headless-fast/references/blog/seed/SEED.md +0 -81
- package/skills/wix-headless-fast/references/blog/seed/seed-blog.mjs +0 -287
- package/skills/wix-headless-fast/references/bookings/INSTRUCTIONS.md +0 -275
- package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServiceBookingView.tsx +0 -144
- package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServicesView.tsx +0 -119
- package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useBookingFlow.ts +0 -32
- package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useServices.ts +0 -23
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-core.ts +0 -218
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-flow-store.ts +0 -169
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking.ts +0 -121
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-core.ts +0 -92
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-store.ts +0 -90
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services.ts +0 -57
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/types.ts +0 -72
- package/skills/wix-headless-fast/references/bookings/app-astro/layouts/SiteLayout.astro +0 -40
- package/skills/wix-headless-fast/references/bookings/app-astro/pages/services/[slug].astro +0 -76
- package/skills/wix-headless-fast/references/bookings/app-astro/pages/services.astro +0 -22
- package/skills/wix-headless-fast/references/bookings/lock/astro/package-lock.json +0 -11962
- package/skills/wix-headless-fast/references/bookings/rest/booking.ts +0 -113
- package/skills/wix-headless-fast/references/bookings/rest/services.ts +0 -55
- package/skills/wix-headless-fast/references/bookings/seed/SEED.md +0 -71
- package/skills/wix-headless-fast/references/bookings/seed/seed-bookings.mjs +0 -302
- package/skills/wix-headless-fast/references/cms/INSTRUCTIONS.md +0 -353
- package/skills/wix-headless-fast/references/cms/app/hooks/cms/useCollection.ts +0 -50
- package/skills/wix-headless-fast/references/cms/app/hooks/cms/useItem.ts +0 -37
- package/skills/wix-headless-fast/references/cms/app/wix/cms/collection-store.ts +0 -158
- package/skills/wix-headless-fast/references/cms/app/wix/cms/item-store.ts +0 -93
- package/skills/wix-headless-fast/references/cms/app/wix/cms/items-core.ts +0 -177
- package/skills/wix-headless-fast/references/cms/app/wix/cms/items.ts +0 -123
- package/skills/wix-headless-fast/references/cms/app/wix/cms/types.ts +0 -75
- package/skills/wix-headless-fast/references/cms/app-astro/layouts/SiteLayout.astro +0 -41
- package/skills/wix-headless-fast/references/cms/lock/astro/package-lock.json +0 -11262
- package/skills/wix-headless-fast/references/cms/rest/items.ts +0 -125
- package/skills/wix-headless-fast/references/cms/seed/SEED.md +0 -112
- package/skills/wix-headless-fast/references/cms/seed/seed-cms.mjs +0 -324
- package/skills/wix-headless-fast/references/events/INSTRUCTIONS.md +0 -305
- package/skills/wix-headless-fast/references/events/app/components/events/EventConfirmationView.tsx +0 -66
- package/skills/wix-headless-fast/references/events/app/components/events/EventRegistrationView.tsx +0 -178
- package/skills/wix-headless-fast/references/events/app/components/events/EventsView.tsx +0 -118
- package/skills/wix-headless-fast/references/events/app/hooks/events/useEventRegistration.ts +0 -35
- package/skills/wix-headless-fast/references/events/app/hooks/events/useEvents.ts +0 -24
- package/skills/wix-headless-fast/references/events/app/wix/events/events-core.ts +0 -130
- package/skills/wix-headless-fast/references/events/app/wix/events/events-store.ts +0 -97
- package/skills/wix-headless-fast/references/events/app/wix/events/events.ts +0 -55
- package/skills/wix-headless-fast/references/events/app/wix/events/registration-core.ts +0 -113
- package/skills/wix-headless-fast/references/events/app/wix/events/registration-store.ts +0 -156
- package/skills/wix-headless-fast/references/events/app/wix/events/registration.ts +0 -97
- package/skills/wix-headless-fast/references/events/app/wix/events/types.ts +0 -61
- package/skills/wix-headless-fast/references/events/app-astro/layouts/SiteLayout.astro +0 -40
- package/skills/wix-headless-fast/references/events/app-astro/pages/event-confirmation.astro +0 -12
- package/skills/wix-headless-fast/references/events/app-astro/pages/events/[slug].astro +0 -80
- package/skills/wix-headless-fast/references/events/app-astro/pages/events.astro +0 -21
- package/skills/wix-headless-fast/references/events/lock/astro/package-lock.json +0 -11884
- package/skills/wix-headless-fast/references/events/rest/events.ts +0 -57
- package/skills/wix-headless-fast/references/events/rest/registration.ts +0 -83
- package/skills/wix-headless-fast/references/events/seed/SEED.md +0 -95
- package/skills/wix-headless-fast/references/events/seed/seed-events.mjs +0 -276
- package/skills/wix-headless-fast/references/forms/INSTRUCTIONS.md +0 -338
- package/skills/wix-headless-fast/references/forms/app/hooks/forms/useWixForm.ts +0 -85
- package/skills/wix-headless-fast/references/forms/app/wix/forms/form-store.ts +0 -332
- package/skills/wix-headless-fast/references/forms/app/wix/forms/forms-core.ts +0 -238
- package/skills/wix-headless-fast/references/forms/app/wix/forms/forms.ts +0 -54
- package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions-core.ts +0 -216
- package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions.ts +0 -59
- package/skills/wix-headless-fast/references/forms/app/wix/forms/types.ts +0 -135
- package/skills/wix-headless-fast/references/forms/lock/astro/package-lock.json +0 -10593
- package/skills/wix-headless-fast/references/forms/rest/forms.ts +0 -34
- package/skills/wix-headless-fast/references/forms/rest/submissions.ts +0 -56
- package/skills/wix-headless-fast/references/forms/seed/SEED.md +0 -116
- package/skills/wix-headless-fast/references/forms/seed/seed-forms.mjs +0 -327
- package/skills/wix-headless-fast/references/members/INSTRUCTIONS.md +0 -314
- package/skills/wix-headless-fast/references/members/app/components/members/AccountView.tsx +0 -60
- package/skills/wix-headless-fast/references/members/app/components/members/LoginForm.tsx +0 -155
- package/skills/wix-headless-fast/references/members/app/components/members/MemberMenu.tsx +0 -78
- package/skills/wix-headless-fast/references/members/app/components/members/RequireAuth.tsx +0 -47
- package/skills/wix-headless-fast/references/members/app/hooks/members/useMember.ts +0 -66
- package/skills/wix-headless-fast/references/members/app/wix/members/auth-core.ts +0 -105
- package/skills/wix-headless-fast/references/members/app/wix/members/auth.ts +0 -59
- package/skills/wix-headless-fast/references/members/app/wix/members/client.ts +0 -53
- package/skills/wix-headless-fast/references/members/app/wix/members/member-store.ts +0 -122
- package/skills/wix-headless-fast/references/members/app/wix/members/members-core.ts +0 -43
- package/skills/wix-headless-fast/references/members/app/wix/members/members.ts +0 -29
- package/skills/wix-headless-fast/references/members/app/wix/members/types.ts +0 -21
- package/skills/wix-headless-fast/references/members/app-astro/layouts/SiteLayout.astro +0 -42
- package/skills/wix-headless-fast/references/members/app-astro/pages/account.astro +0 -10
- package/skills/wix-headless-fast/references/members/app-astro/pages/login.astro +0 -11
- package/skills/wix-headless-fast/references/members/lock/astro/package-lock.json +0 -10329
- package/skills/wix-headless-fast/references/members/rest/auth.ts +0 -215
- package/skills/wix-headless-fast/references/members/rest/members.ts +0 -26
- package/skills/wix-headless-fast/references/members/seed/SEED.md +0 -39
- package/skills/wix-headless-fast/references/members/seed/seed-members.mjs +0 -94
- package/skills/wix-headless-fast/references/portfolio/INSTRUCTIONS.md +0 -313
- package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionProjectsView.tsx +0 -110
- package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionsView.tsx +0 -90
- package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/GalleryMedia.tsx +0 -35
- package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/ProjectDetailView.tsx +0 -85
- package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollectionProjects.ts +0 -32
- package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollections.ts +0 -21
- package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useProjectDetail.ts +0 -31
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collection-projects-store.ts +0 -82
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collections-store.ts +0 -58
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio-core.ts +0 -177
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio.ts +0 -78
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/project-detail-store.ts +0 -81
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/types.ts +0 -55
- package/skills/wix-headless-fast/references/portfolio/app-astro/layouts/SiteLayout.astro +0 -40
- package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio/[slug].astro +0 -30
- package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio.astro +0 -21
- package/skills/wix-headless-fast/references/portfolio/app-astro/pages/projects/[slug].astro +0 -29
- package/skills/wix-headless-fast/references/portfolio/lock/astro/package-lock.json +0 -10197
- package/skills/wix-headless-fast/references/portfolio/rest/portfolio.ts +0 -75
- package/skills/wix-headless-fast/references/portfolio/seed/SEED.md +0 -86
- package/skills/wix-headless-fast/references/portfolio/seed/seed-portfolio.mjs +0 -258
- package/skills/wix-headless-fast/references/pricing-plans/INSTRUCTIONS.md +0 -294
- package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlanDetailView.tsx +0 -47
- package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlansView.tsx +0 -101
- package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/SubscribeButton.tsx +0 -41
- package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlanPurchase.ts +0 -16
- package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlans.ts +0 -22
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plan-purchase-store.ts +0 -54
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-core.ts +0 -106
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-store.ts +0 -64
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans.ts +0 -27
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase-core.ts +0 -43
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase.ts +0 -22
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/types.ts +0 -30
- package/skills/wix-headless-fast/references/pricing-plans/app-astro/layouts/SiteLayout.astro +0 -41
- package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans/[slug].astro +0 -40
- package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans.astro +0 -21
- package/skills/wix-headless-fast/references/pricing-plans/lock/astro/package-lock.json +0 -11226
- package/skills/wix-headless-fast/references/pricing-plans/rest/plans.ts +0 -31
- package/skills/wix-headless-fast/references/pricing-plans/rest/purchase.ts +0 -20
- package/skills/wix-headless-fast/references/pricing-plans/seed/SEED.md +0 -79
- package/skills/wix-headless-fast/references/pricing-plans/seed/seed-pricing-plans.mjs +0 -279
- package/skills/wix-headless-fast/references/restaurants/INSTRUCTIONS.md +0 -358
- package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/MenuView.tsx +0 -142
- package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartButton.tsx +0 -26
- package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartDrawer.tsx +0 -121
- package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/ReservationView.tsx +0 -155
- package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useMenus.ts +0 -34
- package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useOrderCart.ts +0 -43
- package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useReservation.ts +0 -34
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-core.ts +0 -155
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-store.ts +0 -89
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu.ts +0 -71
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/order-store.ts +0 -103
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering-core.ts +0 -124
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering.ts +0 -185
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservation-store.ts +0 -193
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations-core.ts +0 -94
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations.ts +0 -74
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/types.ts +0 -168
- package/skills/wix-headless-fast/references/restaurants/app-astro/layouts/SiteLayout.astro +0 -47
- package/skills/wix-headless-fast/references/restaurants/app-astro/pages/menu.astro +0 -22
- package/skills/wix-headless-fast/references/restaurants/app-astro/pages/reservations.astro +0 -12
- package/skills/wix-headless-fast/references/restaurants/lock/astro/package-lock.json +0 -12560
- package/skills/wix-headless-fast/references/restaurants/rest/menu.ts +0 -60
- package/skills/wix-headless-fast/references/restaurants/rest/ordering.ts +0 -169
- package/skills/wix-headless-fast/references/restaurants/rest/reservations.ts +0 -68
- package/skills/wix-headless-fast/references/restaurants/seed/SEED.md +0 -89
- package/skills/wix-headless-fast/references/restaurants/seed/seed-restaurants.mjs +0 -479
- package/skills/wix-headless-fast/references/shared/CONTENT.md +0 -22
- package/skills/wix-headless-fast/references/shared/CUSTOM_OPERATIONS.md +0 -73
- package/skills/wix-headless-fast/references/shared/DESIGN.md +0 -26
- package/skills/wix-headless-fast/references/shared/SUPPLIED-CONTENT.md +0 -23
- package/skills/wix-headless-fast/references/shared/app/styles/global.css +0 -52
- package/skills/wix-headless-fast/references/shared/app/wix/config.ts +0 -15
- package/skills/wix-headless-fast/references/shared/app/wix/media.ts +0 -81
- package/skills/wix-headless-fast/references/shared/app/wix/money.ts +0 -24
- package/skills/wix-headless-fast/references/shared/app/wix/sdk.ts +0 -89
- package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app/wix/media-upload/client.ts +0 -46
- package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app-astro/pages/api/wix/media-upload.ts +0 -46
- package/skills/wix-headless-fast/references/shared/rest/client.ts +0 -155
- package/skills/wix-headless-fast/references/shared/rest/config.ts +0 -3
- package/skills/wix-headless-fast/references/shared/rest/media.ts +0 -65
- package/skills/wix-headless-fast/references/shared/seed/images.mjs +0 -145
- package/skills/wix-headless-fast/references/storefront/INSTRUCTIONS.md +0 -608
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartButton.tsx +0 -26
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartDrawer.tsx +0 -155
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/FilterPanel.tsx +0 -266
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/OptionPicker.tsx +0 -95
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/QuickAdd.tsx +0 -136
- package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useCart.ts +0 -48
- package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useProductDetail.ts +0 -39
- package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useShop.ts +0 -34
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-core.ts +0 -121
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-store.ts +0 -107
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart.ts +0 -138
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog-core.ts +0 -309
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog.ts +0 -133
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/product-detail-store.ts +0 -147
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/shop-store.ts +0 -289
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/types.ts +0 -167
- package/skills/wix-headless-fast/references/storefront/app-astro/layouts/SiteLayout.astro +0 -65
- package/skills/wix-headless-fast/references/storefront/lock/astro/package-lock.json +0 -12247
- package/skills/wix-headless-fast/references/storefront/rest/cart.ts +0 -132
- package/skills/wix-headless-fast/references/storefront/rest/catalog.ts +0 -123
- package/skills/wix-headless-fast/references/storefront/seed/SEED.md +0 -124
- package/skills/wix-headless-fast/references/storefront/seed/seed-store.mjs +0 -525
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
// React binding for the cart store. Works in any React root — Astro islands (several on one
|
|
2
|
-
// page share the same store) and SPAs alike.
|
|
3
|
-
import { useSyncExternalStore } from "react";
|
|
4
|
-
import {
|
|
5
|
-
addLine,
|
|
6
|
-
getCartState,
|
|
7
|
-
goToCheckout,
|
|
8
|
-
refreshCart,
|
|
9
|
-
removeCartLine,
|
|
10
|
-
setCartOpen,
|
|
11
|
-
subscribeCart,
|
|
12
|
-
updateLineQuantity,
|
|
13
|
-
type CartState,
|
|
14
|
-
} from "../../wix/storefront/cart-store";
|
|
15
|
-
import type { AddToCartExtras } from "../../wix/storefront/cart";
|
|
16
|
-
|
|
17
|
-
const SERVER_STATE = getCartState();
|
|
18
|
-
|
|
19
|
-
export interface UseCart extends CartState {
|
|
20
|
-
itemCount: number;
|
|
21
|
-
addToCart: (
|
|
22
|
-
productId: string,
|
|
23
|
-
variantId?: string | null,
|
|
24
|
-
quantity?: number,
|
|
25
|
-
extras?: AddToCartExtras,
|
|
26
|
-
) => Promise<void>;
|
|
27
|
-
updateQuantity: (lineItemId: string, quantity: number) => Promise<void>;
|
|
28
|
-
removeLine: (lineItemId: string) => Promise<void>;
|
|
29
|
-
checkout: () => Promise<void>;
|
|
30
|
-
openCart: () => void;
|
|
31
|
-
closeCart: () => void;
|
|
32
|
-
refresh: () => Promise<void>;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function useCart(): UseCart {
|
|
36
|
-
const state = useSyncExternalStore(subscribeCart, getCartState, () => SERVER_STATE);
|
|
37
|
-
return {
|
|
38
|
-
...state,
|
|
39
|
-
itemCount: state.cart?.itemCount ?? 0,
|
|
40
|
-
addToCart: addLine,
|
|
41
|
-
updateQuantity: updateLineQuantity,
|
|
42
|
-
removeLine: removeCartLine,
|
|
43
|
-
checkout: goToCheckout,
|
|
44
|
-
openCart: () => setCartOpen(true),
|
|
45
|
-
closeCart: () => setCartOpen(false),
|
|
46
|
-
refresh: refreshCart,
|
|
47
|
-
};
|
|
48
|
-
}
|
package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useProductDetail.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
// React binding of the product-detail store (wix/storefront/product-detail-store.ts) — option
|
|
2
|
-
// selection → variant resolution → add-to-cart lives there, framework-free. Always drive a PDP or
|
|
3
|
-
// quick-add picker through this hook (or the store): resolving variants by hand is where
|
|
4
|
-
// "added variants[0] regardless of the buyer's choice" comes from.
|
|
5
|
-
//
|
|
6
|
-
// SSR-friendly: pass the server-fetched ProductDetail as `initial` (Astro/Next); in a SPA pass
|
|
7
|
-
// the slug and it fetches on mount.
|
|
8
|
-
import { useEffect, useRef, useSyncExternalStore } from "react";
|
|
9
|
-
import {
|
|
10
|
-
createProductDetailStore,
|
|
11
|
-
type ProductDetailState,
|
|
12
|
-
type ProductDetailStore,
|
|
13
|
-
type ProductDetailStoreOptions,
|
|
14
|
-
} from "../../wix/storefront/product-detail-store";
|
|
15
|
-
|
|
16
|
-
export { type OptionGroupView } from "../../wix/storefront/product-detail-store";
|
|
17
|
-
|
|
18
|
-
export type UseProductDetailOptions = ProductDetailStoreOptions;
|
|
19
|
-
|
|
20
|
-
export type UseProductDetail = ProductDetailState &
|
|
21
|
-
Pick<ProductDetailStore, "selectOption" | "setModifier" | "setQuantity" | "add">;
|
|
22
|
-
|
|
23
|
-
export function useProductDetail({ initial, slug }: UseProductDetailOptions): UseProductDetail {
|
|
24
|
-
const ref = useRef<{ slug?: string; store: ProductDetailStore } | null>(null);
|
|
25
|
-
if (!ref.current || ref.current.slug !== slug) ref.current = { slug, store: createProductDetailStore({ initial, slug }) };
|
|
26
|
-
const store = ref.current.store;
|
|
27
|
-
useEffect(() => {
|
|
28
|
-
store.start();
|
|
29
|
-
return () => store.stop();
|
|
30
|
-
}, [store]);
|
|
31
|
-
const state = useSyncExternalStore(store.subscribe, store.getState, store.getState);
|
|
32
|
-
return {
|
|
33
|
-
...state,
|
|
34
|
-
selectOption: store.selectOption,
|
|
35
|
-
setModifier: store.setModifier,
|
|
36
|
-
setQuantity: store.setQuantity,
|
|
37
|
-
add: store.add,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
// React binding of the shop store (wix/storefront/shop-store.ts) — the listing state machine
|
|
2
|
-
// lives there, framework-free; this hook subscribes to one instance per mounted listing and
|
|
3
|
-
// exposes its state and actions under one name. Astro islands and React SPAs use this; a static
|
|
4
|
-
// page, Vue, or Svelte uses the store directly.
|
|
5
|
-
import { useEffect, useRef, useSyncExternalStore } from "react";
|
|
6
|
-
import { createShopStore, type ShopState, type ShopStore, type ShopStoreOptions } from "../../wix/storefront/shop-store";
|
|
7
|
-
|
|
8
|
-
export { SORTS, type ShopFilters } from "../../wix/storefront/shop-store";
|
|
9
|
-
|
|
10
|
-
export type UseShopOptions = ShopStoreOptions;
|
|
11
|
-
|
|
12
|
-
export type UseShop = ShopState &
|
|
13
|
-
Pick<ShopStore, "setActiveCategoryId" | "setSort" | "setFilters" | "toggleChoice" | "clearFilters" | "retry" | "loadMore">;
|
|
14
|
-
|
|
15
|
-
export function useShop(options: UseShopOptions = {}): UseShop {
|
|
16
|
-
const ref = useRef<ShopStore | null>(null);
|
|
17
|
-
if (!ref.current) ref.current = createShopStore(options);
|
|
18
|
-
const store = ref.current;
|
|
19
|
-
useEffect(() => {
|
|
20
|
-
store.start();
|
|
21
|
-
return () => store.stop();
|
|
22
|
-
}, [store]);
|
|
23
|
-
const state = useSyncExternalStore(store.subscribe, store.getState, store.getState);
|
|
24
|
-
return {
|
|
25
|
-
...state,
|
|
26
|
-
setActiveCategoryId: store.setActiveCategoryId,
|
|
27
|
-
setSort: store.setSort,
|
|
28
|
-
setFilters: store.setFilters,
|
|
29
|
-
toggleChoice: store.toggleChoice,
|
|
30
|
-
clearFilters: store.clearFilters,
|
|
31
|
-
retry: store.retry,
|
|
32
|
-
loadMore: store.loadMore,
|
|
33
|
-
};
|
|
34
|
-
}
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
// Cart rules and DTO mapping — transport-agnostic, imported by both ./cart.ts (SDK) and the REST
|
|
2
|
-
// twin in references/storefront/rest/cart.ts (fetch). Raw Cart V2 entities may carry `_id` (SDK)
|
|
3
|
-
// or `id` (REST). Has its own formatMoney (a copy of ../money.ts) so it stands alone when stripped.
|
|
4
|
-
import type { Cart, CartLine } from "./types";
|
|
5
|
-
import type { ImgSrc, Raw } from "./catalog-core";
|
|
6
|
-
|
|
7
|
-
/** Public app id of the Wix Stores catalog — required inside every catalogReference. */
|
|
8
|
-
export const WIX_STORES_APP_ID = "215238eb-22a5-4c36-9e7b-e7c08025e04e";
|
|
9
|
-
|
|
10
|
-
export const rawId = (raw: Raw | undefined | null): string => raw?._id ?? raw?.id ?? "";
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Cart V2 money is ConvertedMoney { amount, convertedAmount } with NO formatted string, and the
|
|
14
|
-
* currency lives on the cart, not on the money. Format with the buyer's display currency when
|
|
15
|
-
* present, else the site's. Never hardcode "$" or assume USD.
|
|
16
|
-
*/
|
|
17
|
-
export function formatMoney(money: Raw | null | undefined, currencyCode: string | null | undefined): string {
|
|
18
|
-
const value = money?.convertedAmount ?? money?.amount;
|
|
19
|
-
if (value == null || value === "") return "";
|
|
20
|
-
const currency = currencyCode || "USD";
|
|
21
|
-
try {
|
|
22
|
-
return new Intl.NumberFormat(undefined, { style: "currency", currency }).format(Number(value));
|
|
23
|
-
} catch {
|
|
24
|
-
return `${value} ${currency}`;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const cartCurrency = (raw: Raw | null | undefined): string =>
|
|
29
|
-
raw?.customerInfo?.currencyCode ?? raw?.businessInfo?.currencyCode ?? "";
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* "Monthly plan · every 2 months · 6 payments" from the line's subscriptionInfo (Cart V2 carries
|
|
33
|
-
* the plan on the line); "" for a one-time purchase. Every word comes from the plan — a
|
|
34
|
-
* subscription line must read as one in the cart, never a generic "recurring".
|
|
35
|
-
*/
|
|
36
|
-
export function subscriptionTerms(info: Raw | undefined): string {
|
|
37
|
-
if (!info) return "";
|
|
38
|
-
const s: Raw = info.subscriptionSettings ?? {};
|
|
39
|
-
const unit: Record<string, string> = { DAY: "day", WEEK: "week", MONTH: "month", YEAR: "year" };
|
|
40
|
-
const parts: string[] = [];
|
|
41
|
-
const title = info.title?.original ?? info.title?.translated ?? "";
|
|
42
|
-
if (title) parts.push(title);
|
|
43
|
-
const u = unit[String(s.frequency ?? "")];
|
|
44
|
-
if (u) parts.push(`every ${s.interval && s.interval > 1 ? `${s.interval} ${u}s` : u}`);
|
|
45
|
-
if (!s.autoRenewal && s.billingCycles) parts.push(`${s.billingCycles} payments`);
|
|
46
|
-
return parts.join(" · ");
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export function toLine(raw: Raw, currency: string, imgSrc: ImgSrc): CartLine {
|
|
50
|
-
return {
|
|
51
|
-
lineItemId: rawId(raw), // the LINE id — what update/remove take, never the product id
|
|
52
|
-
productName: raw.name?.original ?? "",
|
|
53
|
-
quantity: raw.quantityInfo?.confirmedQuantity ?? 0,
|
|
54
|
-
unitPrice: formatMoney(raw.pricing?.unitPrice, currency),
|
|
55
|
-
linePrice: formatMoney(raw.pricing?.totalPrice, currency),
|
|
56
|
-
imageUrl: imgSrc(raw.attributes?.image, 300, 300),
|
|
57
|
-
descriptionLines: ((raw.attributes?.descriptionLines ?? []) as Raw[])
|
|
58
|
-
.map((d) => {
|
|
59
|
-
const label = d.name?.original ?? "", value = d.plainText?.original ?? d.colorInfo?.original ?? "";
|
|
60
|
-
return label && value ? `${label}: ${value}` : value || label;
|
|
61
|
-
})
|
|
62
|
-
.filter(Boolean),
|
|
63
|
-
status: raw.status ?? "IN_STOCK", // not IN_STOCK → the line can't be checked out as-is
|
|
64
|
-
subscription: subscriptionTerms(raw.subscriptionInfo),
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export function toCart(raw: Raw | null, subtotal: string, discount: string, imgSrc: ImgSrc): Cart {
|
|
69
|
-
const currency = cartCurrency(raw);
|
|
70
|
-
const lines = ((raw?.lineItems ?? []) as Raw[]).map((l) => toLine(l, currency, imgSrc));
|
|
71
|
-
return { lines, itemCount: lines.reduce((n, l) => n + l.quantity, 0), subtotal, discount, currency };
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/** The after-discount subtotal and the CART-level discount from an estimate; "" when unknown. */
|
|
75
|
-
export function summaryTotals(estimate: Raw | null | undefined, raw: Raw): { subtotal: string; discount: string } {
|
|
76
|
-
const s = estimate?.summary?.priceSummary;
|
|
77
|
-
const currency = cartCurrency(raw);
|
|
78
|
-
const d = s?.discount;
|
|
79
|
-
return {
|
|
80
|
-
subtotal: formatMoney(s?.subtotal, currency),
|
|
81
|
-
discount: Number(d?.convertedAmount ?? d?.amount ?? 0) > 0 ? formatMoney(d, currency) : "",
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/** The catalogReference.options object for an add — omits every key the buyer didn't use. */
|
|
86
|
-
export function addOptions({ variantId, modifierChoices, customTextFields, subscriptionOptionId, preorder }: {
|
|
87
|
-
variantId?: string | null; modifierChoices?: Record<string, string>; customTextFields?: Record<string, string>;
|
|
88
|
-
subscriptionOptionId?: string; preorder?: boolean;
|
|
89
|
-
}): Raw {
|
|
90
|
-
const o: Raw = {};
|
|
91
|
-
if (variantId) o.variantId = variantId; // REQUIRED for any product with options
|
|
92
|
-
if (modifierChoices && Object.keys(modifierChoices).length) o.options = modifierChoices; // MODIFIERS only, never Size/Color
|
|
93
|
-
if (customTextFields && Object.keys(customTextFields).length) o.customTextFields = customTextFields;
|
|
94
|
-
if (subscriptionOptionId) o.subscriptionOptionId = subscriptionOptionId;
|
|
95
|
-
if (preorder) o.preOrderRequested = true;
|
|
96
|
-
return o;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/** Read the add result — a refused add still returns 200: a line whose status isn't IN_STOCK, or no line, is a refusal. */
|
|
100
|
-
export function assertAdded(cart: Raw | null | undefined, productId: string, variantId?: string | null): void {
|
|
101
|
-
const line = ((cart?.lineItems ?? []) as Raw[]).find(
|
|
102
|
-
(l) => l.source?.catalogReference?.catalogItemId === productId && (!variantId || l.source?.catalogReference?.options?.variantId === variantId),
|
|
103
|
-
);
|
|
104
|
-
if (line?.status && line.status !== "IN_STOCK") {
|
|
105
|
-
throw new Error(`This item isn't available right now (${String(line.status).toLowerCase().replace(/_/g, " ")}).`);
|
|
106
|
-
}
|
|
107
|
-
if (!line || line.quantityInfo?.confirmedQuantity === 0) {
|
|
108
|
-
throw new Error("The item couldn't be added. Make sure every required selection was made (options for a product with variants, and all mandatory customizations).");
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/** Refuse checkout for an empty cart or any line not IN_STOCK — say which. */
|
|
113
|
-
export function assertCheckoutable(raw: Raw | null): void {
|
|
114
|
-
const lines: Raw[] = raw?.lineItems ?? [];
|
|
115
|
-
if (!lines.length) throw new Error("Your cart is empty.");
|
|
116
|
-
const unavailable = lines.filter((l) => l.status && l.status !== "IN_STOCK");
|
|
117
|
-
if (unavailable.length) {
|
|
118
|
-
throw new Error(`Some items are no longer available: ${unavailable.map((l) => l.name?.original).filter(Boolean).join(", ")}.`);
|
|
119
|
-
}
|
|
120
|
-
if (!rawId(raw)) throw new Error("Checkout couldn't start: the cart has no id.");
|
|
121
|
-
}
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
// Client-side cart state — a module-scope store, deliberately NOT a React context.
|
|
2
|
-
// A context can't span Astro islands (each island is its own React root); a module
|
|
3
|
-
// singleton is shared by every island in the page bundle, and works identically in a
|
|
4
|
-
// single-root SPA. Consume it through useCart() (hooks/), or subscribe directly.
|
|
5
|
-
import type { Cart } from "./types";
|
|
6
|
-
import {
|
|
7
|
-
addToCart as apiAdd,
|
|
8
|
-
fetchCart,
|
|
9
|
-
removeLine as apiRemove,
|
|
10
|
-
updateQuantity as apiUpdate,
|
|
11
|
-
checkoutUrl,
|
|
12
|
-
type AddToCartExtras,
|
|
13
|
-
} from "./cart";
|
|
14
|
-
|
|
15
|
-
export interface CartState {
|
|
16
|
-
cart: Cart | null;
|
|
17
|
-
/** True while any cart operation is in flight. */
|
|
18
|
-
busy: boolean;
|
|
19
|
-
/** Last failed operation's message — render it; a new operation clears it. */
|
|
20
|
-
error: string | null;
|
|
21
|
-
/** Cart drawer visibility (CartButton opens it, CartDrawer renders by it). */
|
|
22
|
-
open: boolean;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const EMPTY: CartState = { cart: null, busy: false, error: null, open: false };
|
|
26
|
-
|
|
27
|
-
let state: CartState = EMPTY;
|
|
28
|
-
const listeners = new Set<() => void>();
|
|
29
|
-
let loaded = false;
|
|
30
|
-
|
|
31
|
-
function setState(patch: Partial<CartState>): void {
|
|
32
|
-
state = { ...state, ...patch };
|
|
33
|
-
for (const l of listeners) l();
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function getCartState(): CartState {
|
|
37
|
-
return state;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export function subscribeCart(listener: () => void): () => void {
|
|
41
|
-
listeners.add(listener);
|
|
42
|
-
// First subscriber triggers the initial load (browser only — SSR renders the empty state).
|
|
43
|
-
if (!loaded && typeof window !== "undefined") {
|
|
44
|
-
loaded = true;
|
|
45
|
-
void refreshCart();
|
|
46
|
-
}
|
|
47
|
-
return () => listeners.delete(listener);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
async function run(op: () => Promise<Cart>): Promise<void> {
|
|
51
|
-
setState({ busy: true, error: null });
|
|
52
|
-
try {
|
|
53
|
-
setState({ cart: await op(), busy: false });
|
|
54
|
-
} catch (e) {
|
|
55
|
-
setState({ busy: false, error: e instanceof Error ? e.message : String(e) });
|
|
56
|
-
throw e;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export async function refreshCart(): Promise<void> {
|
|
61
|
-
try {
|
|
62
|
-
setState({ cart: await fetchCart() });
|
|
63
|
-
} catch {
|
|
64
|
-
/* no cart yet — leave the empty state */
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/** Add to cart and open the drawer. Throws (and sets .error) on refusal. */
|
|
69
|
-
export async function addLine(
|
|
70
|
-
productId: string,
|
|
71
|
-
variantId?: string | null,
|
|
72
|
-
quantity = 1,
|
|
73
|
-
extras?: AddToCartExtras,
|
|
74
|
-
): Promise<void> {
|
|
75
|
-
try {
|
|
76
|
-
await run(() => apiAdd(productId, variantId, quantity, extras));
|
|
77
|
-
} finally {
|
|
78
|
-
// Open either way. On success this shows the new line; on refusal it's the only thing that
|
|
79
|
-
// makes .error visible — the drawer renders it, and a drawer that stays shut on failure
|
|
80
|
-
// turns a refused add (out of stock, a digital product with no file) into silence.
|
|
81
|
-
setState({ open: true });
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export async function updateLineQuantity(lineItemId: string, quantity: number): Promise<void> {
|
|
86
|
-
await run(() => apiUpdate(lineItemId, quantity));
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export async function removeCartLine(lineItemId: string): Promise<void> {
|
|
90
|
-
await run(() => apiRemove(lineItemId));
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/** Navigate to the Wix-hosted checkout. Never hand-build a checkout URL. */
|
|
94
|
-
export async function goToCheckout(): Promise<void> {
|
|
95
|
-
setState({ busy: true, error: null });
|
|
96
|
-
try {
|
|
97
|
-
const url = await checkoutUrl();
|
|
98
|
-
window.location.href = url;
|
|
99
|
-
} catch (e) {
|
|
100
|
-
setState({ busy: false, error: e instanceof Error ? e.message : String(e) });
|
|
101
|
-
throw e;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export function setCartOpen(open: boolean): void {
|
|
106
|
-
setState({ open });
|
|
107
|
-
}
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
// Cart + checkout (Wix eCom Cart V2) over the SDK — the only file that touches raw cart entities
|
|
2
|
-
// on this transport. Rules and mappers live in ./cart-core (shared with the REST twin in
|
|
3
|
-
// references/storefront/rest/); this file is the transport only. Copy as-is; extend by calling
|
|
4
|
-
// these exports, never by editing them. The request shapes are exact (catalogItems wrapper,
|
|
5
|
-
// options.variantId, the redirect-session body) and rewriting them is how carts break.
|
|
6
|
-
//
|
|
7
|
-
// Failures are loud: these throw on out-of-stock lines, an empty cart at checkout, and a
|
|
8
|
-
// missing required selection — surface the message to the buyer, don't swallow it.
|
|
9
|
-
// docs: https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/purchase-flow/cart-v2/get-current-cart.md
|
|
10
|
-
// docs: https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/purchase-flow/cart-v2/add-line-items-to-current-cart.md
|
|
11
|
-
// docs: https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/purchase-flow/cart-v2/update-line-items.md
|
|
12
|
-
// docs: https://dev.wix.com/docs/api-reference/business-management/headless/redirects/create-redirect-session.md
|
|
13
|
-
import { currentCartV2 } from "@wix/ecom";
|
|
14
|
-
import { redirects as redirectsModule } from "@wix/redirects";
|
|
15
|
-
import { productsV3 } from "@wix/stores";
|
|
16
|
-
import { wixModule } from "../sdk";
|
|
17
|
-
import { imgSrc } from "../media";
|
|
18
|
-
import { WIX_STORES_APP_ID, addOptions, assertAdded, assertCheckoutable, rawId, summaryTotals, toCart } from "./cart-core";
|
|
19
|
-
import type { Raw } from "./catalog-core";
|
|
20
|
-
import type { Cart } from "./types";
|
|
21
|
-
|
|
22
|
-
const cartApi = wixModule(currentCartV2);
|
|
23
|
-
const redirects = wixModule(redirectsModule);
|
|
24
|
-
const productsApi = wixModule(productsV3);
|
|
25
|
-
|
|
26
|
-
export interface AddToCartExtras {
|
|
27
|
-
/** TEXT_CHOICES modifier selections: modifier key -> choice key (options.options — MODIFIERS only, never Size/Color). */
|
|
28
|
-
modifierChoices?: Record<string, string>;
|
|
29
|
-
/** FREE_TEXT modifier inputs: freeTextSettings key -> the buyer's text. */
|
|
30
|
-
customTextFields?: Record<string, string>;
|
|
31
|
-
/** The variant is out of stock but pre-orderable — sends preOrderRequested. */
|
|
32
|
-
preorder?: boolean;
|
|
33
|
-
/** A chosen recurring plan (subscriptionPricesInfo); omit for a one-time purchase. */
|
|
34
|
-
subscriptionOptionId?: string;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// The V2 cart does NOT return line-item images (attributes.image is typed but comes back
|
|
38
|
-
// absent — verified against a live cart), so images are joined from the catalog by the
|
|
39
|
-
// line's catalogItemId and cached for the session.
|
|
40
|
-
const lineImageCache = new Map<string, string>();
|
|
41
|
-
async function fillLineImages(cart: Cart, raws: Raw[]): Promise<void> {
|
|
42
|
-
const wanted = new Map<string, number[]>(); // productId -> line indexes
|
|
43
|
-
raws.forEach((raw, i) => {
|
|
44
|
-
if (cart.lines[i].imageUrl) return;
|
|
45
|
-
const pid = raw.source?.catalogReference?.catalogItemId;
|
|
46
|
-
if (!pid) return;
|
|
47
|
-
const cached = lineImageCache.get(pid);
|
|
48
|
-
if (cached !== undefined) {
|
|
49
|
-
cart.lines[i].imageUrl = cached;
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
wanted.set(pid, [...(wanted.get(pid) ?? []), i]);
|
|
53
|
-
});
|
|
54
|
-
if (!wanted.size) return;
|
|
55
|
-
try {
|
|
56
|
-
const res = await productsApi.queryProducts().in("_id", [...wanted.keys()]).find();
|
|
57
|
-
for (const p of (res.items ?? []) as Raw[]) {
|
|
58
|
-
const url = imgSrc(p.media?.main, 300, 300);
|
|
59
|
-
lineImageCache.set(rawId(p), url);
|
|
60
|
-
for (const i of wanted.get(rawId(p)) ?? []) cart.lines[i].imageUrl = url;
|
|
61
|
-
}
|
|
62
|
-
} catch {
|
|
63
|
-
/* images are a nicety — the cart stays correct without them */
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
async function readCartWithSubtotal(raw: Raw | null): Promise<Cart> {
|
|
68
|
-
// Only estimate a cart WITH lines — on an absent/empty cart the endpoint returns 404.
|
|
69
|
-
if (!raw?.lineItems?.length) return toCart(raw, "", "", imgSrc);
|
|
70
|
-
// The authoritative after-discount subtotal and the CART-level discount come from the cart
|
|
71
|
-
// estimate, never from hand-summing lines. Its delivery/tax/fees read "0" when nothing was
|
|
72
|
-
// calculated — never render those as "Free"; shipping and tax resolve at checkout.
|
|
73
|
-
let totals = { subtotal: "", discount: "" };
|
|
74
|
-
try {
|
|
75
|
-
totals = summaryTotals(await cartApi.estimateCurrentCart(), raw);
|
|
76
|
-
} catch {
|
|
77
|
-
/* estimate is a display nicety — the cart itself is still valid */
|
|
78
|
-
}
|
|
79
|
-
const cart = toCart(raw, totals.subtotal, totals.discount, imgSrc);
|
|
80
|
-
await fillLineImages(cart, raw.lineItems as Raw[]);
|
|
81
|
-
return cart;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/** Read the visitor's current cart. An empty Cart (not an error) when none exists yet. */
|
|
85
|
-
export async function fetchCart(): Promise<Cart> {
|
|
86
|
-
try {
|
|
87
|
-
const { cart } = await cartApi.getCurrentCart();
|
|
88
|
-
return readCartWithSubtotal(cart as Raw);
|
|
89
|
-
} catch {
|
|
90
|
-
return toCart(null, "", "", imgSrc);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Add a product to the current cart. For a product WITH options, `variantId` is mandatory —
|
|
96
|
-
* resolve it with `resolveVariant()` from ./catalog first. Mandatory modifiers must be included.
|
|
97
|
-
* A refused add still returns 200, so the returned line is checked.
|
|
98
|
-
*/
|
|
99
|
-
export async function addToCart(productId: string, variantId?: string | null, quantity = 1, extras: AddToCartExtras = {}): Promise<Cart> {
|
|
100
|
-
const options = addOptions({ variantId, ...extras });
|
|
101
|
-
const { cart } = await cartApi.addLineItemsToCurrentCart({
|
|
102
|
-
catalogItems: [{ quantity, catalogReference: { catalogItemId: productId, appId: WIX_STORES_APP_ID, ...(Object.keys(options).length ? { options } : {}) } }],
|
|
103
|
-
});
|
|
104
|
-
assertAdded(cart as Raw, productId, variantId);
|
|
105
|
-
return readCartWithSubtotal(cart as Raw);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/** Change a line's quantity. `lineItemId` is CartLine.lineItemId, never the product id. */
|
|
109
|
-
export async function updateQuantity(lineItemId: string, quantity: number): Promise<Cart> {
|
|
110
|
-
const { cart } = await cartApi.updateLineItemsInCurrentCart({ lineItems: [{ lineItemId, quantity: { newQuantity: quantity } }] });
|
|
111
|
-
return readCartWithSubtotal(cart as Raw);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/** Remove a line from the cart by CartLine.lineItemId. */
|
|
115
|
-
export async function removeLine(lineItemId: string): Promise<Cart> {
|
|
116
|
-
const { cart } = await cartApi.removeLineItemsFromCurrentCart([lineItemId]);
|
|
117
|
-
return readCartWithSubtotal(cart as Raw);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Start the Wix-hosted checkout for the current cart and return the URL to navigate to.
|
|
122
|
-
* The cart's id IS the checkout id — no separate checkout-creation call.
|
|
123
|
-
* Call from the browser: the return origin must be the site's real https origin
|
|
124
|
-
* (window.location.origin), never a server-derived request origin.
|
|
125
|
-
*/
|
|
126
|
-
export async function checkoutUrl(): Promise<string> {
|
|
127
|
-
const { cart } = await cartApi.getCurrentCart();
|
|
128
|
-
const raw = cart as Raw;
|
|
129
|
-
assertCheckoutable(raw);
|
|
130
|
-
const origin = typeof window !== "undefined" ? window.location.origin : "";
|
|
131
|
-
const session = await redirects.createRedirectSession({
|
|
132
|
-
ecomCheckout: { checkoutId: rawId(raw) },
|
|
133
|
-
callbacks: { postFlowUrl: origin ? `${origin}/` : undefined, thankYouPageUrl: origin ? `${origin}/` : undefined },
|
|
134
|
-
});
|
|
135
|
-
const url = session?.redirectSession?.fullUrl;
|
|
136
|
-
if (!url) throw new Error("Checkout couldn't start: no redirect URL returned.");
|
|
137
|
-
return url;
|
|
138
|
-
}
|