@wix/agent-skills 1.14.0 → 1.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. package/README.md +12 -1
  2. package/package.json +1 -1
  3. package/skills/README.md +23 -0
  4. package/skills/wix-app/SKILL.md +10 -2
  5. package/skills/wix-app/references/AUTO_PATTERNS_DASHBOARD.md +326 -0
  6. package/skills/wix-app/references/CODE_QUALITY.md +1 -0
  7. package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +124 -115
  8. package/skills/wix-app/references/DASHBOARD_PAGE.md +3 -0
  9. package/skills/wix-app/references/DATA_COLLECTION.md +5 -3
  10. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +25 -9
  11. package/skills/wix-app/references/SITE_PLUGIN.md +1 -1
  12. package/skills/wix-app/references/STORES_VERSIONING.md +9 -211
  13. package/skills/wix-app/references/auto-patterns-dashboard/action-cell.md +115 -0
  14. package/skills/wix-app/references/auto-patterns-dashboard/app-config-structure.md +264 -0
  15. package/skills/wix-app/references/auto-patterns-dashboard/app-context.md +37 -0
  16. package/skills/wix-app/references/auto-patterns-dashboard/bulk-actions.md +86 -0
  17. package/skills/wix-app/references/auto-patterns-dashboard/collection-page-actions.md +119 -0
  18. package/skills/wix-app/references/auto-patterns-dashboard/collection-page.md +103 -0
  19. package/skills/wix-app/references/auto-patterns-dashboard/custom-actions-override.md +76 -0
  20. package/skills/wix-app/references/auto-patterns-dashboard/custom-columns-override.md +82 -0
  21. package/skills/wix-app/references/auto-patterns-dashboard/custom-components-override.md +89 -0
  22. package/skills/wix-app/references/auto-patterns-dashboard/custom-header-override.md +124 -0
  23. package/skills/wix-app/references/auto-patterns-dashboard/custom-sections-override.md +91 -0
  24. package/skills/wix-app/references/auto-patterns-dashboard/custom-slots-override.md +71 -0
  25. package/skills/wix-app/references/auto-patterns-dashboard/entity-page-actions.md +70 -0
  26. package/skills/wix-app/references/auto-patterns-dashboard/entity-page-view-actions.md +73 -0
  27. package/skills/wix-app/references/auto-patterns-dashboard/entity-page.md +98 -0
  28. package/skills/wix-app/references/auto-patterns-dashboard/example-patterns.json +278 -0
  29. package/skills/wix-app/references/auto-patterns-dashboard/pages-configuration.md +94 -0
  30. package/skills/wix-app/references/auto-patterns-dashboard/resolved-action.md +43 -0
  31. package/skills/wix-app/references/auto-patterns-dashboard/sdk-utilities.md +66 -0
  32. package/skills/wix-app/references/auto-patterns-dashboard/views.md +76 -0
  33. package/skills/wix-app/references/backend-event/COMMON-EVENTS.md +5 -0
  34. package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +1 -14
  35. package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +151 -0
  36. package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +54 -29
  37. package/skills/wix-app/references/editor-react-component/COMPONENT-CONFIGURATION.md +2 -2
  38. package/skills/wix-app/references/editor-react-component/COMPONENT-PREVIEW.md +57 -0
  39. package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +23 -105
  40. package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +127 -0
  41. package/skills/wix-app/references/editor-react-component/PARTS.md +2 -1
  42. package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +18 -16
  43. package/skills/wix-app/references/editor-react-component/REACT-PATTERNS.md +25 -53
  44. package/skills/wix-app/references/stores/CATEGORIES.md +22 -0
  45. package/skills/wix-app/references/stores/GET_PRODUCT.md +99 -0
  46. package/skills/wix-app/references/stores/INVENTORY.md +37 -0
  47. package/skills/wix-app/references/stores/QUERY.md +87 -0
  48. package/skills/wix-app/references/stores/WRITE.md +55 -0
  49. package/skills/wix-app/scripts/generate-auto-patterns.js +510 -0
  50. package/skills/wix-auth/SKILL.md +12 -0
  51. package/skills/wix-auth/references/device-flow.md +140 -0
  52. package/skills/wix-docs/SKILL.md +188 -0
  53. package/skills/wix-docs/references/API_SPEC_SEARCH.md +213 -0
  54. package/skills/wix-docs/references/EXTRACTING.md +120 -0
  55. package/skills/wix-headless/SKILL.md +89 -130
  56. package/skills/wix-headless/entry/bootstrap.mjs +93 -0
  57. package/skills/wix-headless/entry/skill.md +76 -0
  58. package/skills/wix-headless/references/AI_FEATURES.md +178 -0
  59. package/skills/wix-headless/references/CAPABILITIES.md +86 -0
  60. package/skills/wix-headless/references/DISCOVERY.md +34 -56
  61. package/skills/wix-headless/references/DOC_DISCOVERY.md +37 -0
  62. package/skills/wix-headless/references/FEEDBACK.md +129 -0
  63. package/skills/wix-headless/references/IMAGE_GENERATION.md +69 -0
  64. package/skills/wix-headless/references/SDK_HANDOFF.md +99 -0
  65. package/skills/wix-headless/references/SEED.md +45 -187
  66. package/skills/wix-headless/references/SETUP.md +32 -103
  67. package/skills/wix-headless/references/astro.md +98 -0
  68. package/skills/wix-headless/references/inline-recipes/how-to-code-a-blog.md +196 -0
  69. package/skills/wix-headless/references/inline-recipes/how-to-code-a-store.md +236 -0
  70. package/skills/wix-headless/references/inline-recipes/how-to-code-bookings.md +279 -0
  71. package/skills/wix-headless/references/inline-recipes/how-to-code-cms.md +163 -0
  72. package/skills/wix-headless/references/inline-recipes/how-to-code-events.md +203 -0
  73. package/skills/wix-headless/references/inline-recipes/how-to-code-forms.md +222 -0
  74. package/skills/wix-headless/references/inline-recipes/how-to-code-members-astro.md +124 -0
  75. package/skills/wix-headless/references/inline-recipes/how-to-code-members-custom-login.md +160 -0
  76. package/skills/wix-headless/references/inline-recipes/how-to-code-members-non-astro.md +118 -0
  77. package/skills/wix-headless/references/inline-recipes/how-to-code-portfolio.md +132 -0
  78. package/skills/wix-headless/references/inline-recipes/how-to-code-pricing-plans.md +124 -0
  79. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-orders.md +188 -0
  80. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-reservations.md +213 -0
  81. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurants.md +161 -0
  82. package/skills/wix-headless/references/inline-recipes/setup-blog.md +175 -0
  83. package/skills/wix-headless/references/inline-recipes/setup-bookings.md +232 -0
  84. package/skills/wix-headless/references/inline-recipes/setup-cms.md +200 -0
  85. package/skills/wix-headless/references/inline-recipes/setup-events.md +196 -0
  86. package/skills/wix-headless/references/inline-recipes/setup-forms.md +174 -0
  87. package/skills/wix-headless/references/inline-recipes/setup-online-store.md +192 -0
  88. package/skills/wix-headless/references/inline-recipes/setup-portfolio.md +155 -0
  89. package/skills/wix-headless/references/inline-recipes/setup-pricing-plans.md +229 -0
  90. package/skills/wix-headless/references/inline-recipes/setup-restaurant-experiences.md +73 -0
  91. package/skills/wix-headless/references/inline-recipes/setup-restaurant-orders.md +197 -0
  92. package/skills/wix-headless/references/inline-recipes/setup-restaurant-reservations.md +136 -0
  93. package/skills/wix-headless/references/inline-recipes/setup-restaurants.md +152 -0
  94. package/skills/wix-headless/references/managed/AUTHENTICATION.md +57 -0
  95. package/skills/wix-headless/references/managed/CONNECT.md +74 -0
  96. package/skills/wix-headless/references/managed/CREATE.md +130 -0
  97. package/skills/wix-headless/references/managed/DEPLOYMENT.md +79 -0
  98. package/skills/wix-headless/references/non-astro.md +59 -0
  99. package/skills/wix-headless/references/self-managed/AUTHENTICATION.md +22 -0
  100. package/skills/wix-headless/references/self-managed/DEPLOYMENT.md +15 -0
  101. package/skills/wix-headless/references/stripe/AUTHENTICATION.md +55 -0
  102. package/skills/wix-headless/references/stripe/DEPLOYMENT.md +71 -0
  103. package/skills/wix-manage/SKILL.md +29 -3
  104. package/skills/wix-manage/references/analytics/query-site-analytics.md +298 -0
  105. package/skills/wix-manage/references/app-installation/install-wix-apps.md +3 -0
  106. package/skills/wix-manage/references/bookings/create-and-update-booking-services.md +1 -1
  107. package/skills/wix-manage/references/bookings/create-booking-service-from-prompt.md +6 -5
  108. package/skills/wix-manage/references/bookings/create-course-service.md +30 -5
  109. package/skills/wix-manage/references/bookings/diagnose-availability-issues.md +299 -0
  110. package/skills/wix-manage/references/cms/cms-schema-management.md +6 -0
  111. package/skills/wix-manage/references/get-paid/how-to-setup-wix-payments.md +30 -7
  112. package/skills/wix-manage/references/marketing/create-and-publish-social-post.md +517 -0
  113. package/skills/wix-manage/references/marketing/generate-and-publish-marketing-plan.md +218 -0
  114. package/skills/wix-manage/references/rich-content/author-ricos-rich-content.md +249 -0
  115. package/skills/wix-manage/references/sites/site-import.md +270 -0
  116. package/skills/wix-manage/references/stores/create-product-from-image.md +8 -6
  117. package/skills/wix-manage/references/stores/create-product-with-options-catalog-v3.md +57 -0
  118. package/skills/wix-vibe-headless/SKILL.md +142 -0
  119. package/skills/wix-vibe-headless/platforms/README.md +22 -0
  120. package/skills/wix-vibe-headless/platforms/base44.md +142 -0
  121. package/skills/wix-vibe-headless/platforms/generic.md +87 -0
  122. package/skills/wix-vibe-headless/references/blog/INSTRUCTIONS.md +128 -0
  123. package/skills/wix-vibe-headless/references/blog/wix-blog.js +217 -0
  124. package/skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md +157 -0
  125. package/skills/wix-vibe-headless/references/bookings/wix-bookings-checkout.js +147 -0
  126. package/skills/wix-vibe-headless/references/bookings/wix-bookings-services.js +217 -0
  127. package/skills/wix-vibe-headless/references/cms/INSTRUCTIONS.md +154 -0
  128. package/skills/wix-vibe-headless/references/cms/wix-cms.js +186 -0
  129. package/skills/wix-vibe-headless/references/events/INSTRUCTIONS.md +142 -0
  130. package/skills/wix-vibe-headless/references/events/wix-events-browse.js +136 -0
  131. package/skills/wix-vibe-headless/references/events/wix-events-registration.js +187 -0
  132. package/skills/wix-vibe-headless/references/members/INSTRUCTIONS.md +211 -0
  133. package/skills/wix-vibe-headless/references/members/wix-members-auth.js +387 -0
  134. package/skills/wix-vibe-headless/references/portfolio/INSTRUCTIONS.md +111 -0
  135. package/skills/wix-vibe-headless/references/portfolio/wix-portfolio.js +223 -0
  136. package/skills/wix-vibe-headless/references/pricing-plans/INSTRUCTIONS.md +127 -0
  137. package/skills/wix-vibe-headless/references/pricing-plans/wix-pricing-plans.js +157 -0
  138. package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +138 -0
  139. package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-menu.js +224 -0
  140. package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-ordering.js +156 -0
  141. package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-reservations.js +107 -0
  142. package/skills/wix-vibe-headless/references/shared/wix-client.js +186 -0
  143. package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +164 -0
  144. package/skills/wix-vibe-headless/references/storefront/wix-store-cart.js +147 -0
  145. package/skills/wix-vibe-headless/references/storefront/wix-store-catalog.js +146 -0
  146. package/skills/wix-headless/references/BUILD-astro.md +0 -253
  147. package/skills/wix-headless/references/BUILD-own-build.md +0 -167
  148. package/skills/wix-headless/references/BUILD.md +0 -105
  149. package/skills/wix-headless/references/DESIGN_SYSTEM.md +0 -165
  150. package/skills/wix-headless/references/DISCOVERY-connect.md +0 -55
  151. package/skills/wix-headless/references/DISCOVERY-create.md +0 -238
  152. package/skills/wix-headless/references/PLAN-connect.md +0 -19
  153. package/skills/wix-headless/references/PLAN-create.md +0 -17
  154. package/skills/wix-headless/references/PLAN.md +0 -92
  155. package/skills/wix-headless/references/astro/blog/BLOG_PAGES.md +0 -300
  156. package/skills/wix-headless/references/astro/blog/BLOG_SETUP.md +0 -218
  157. package/skills/wix-headless/references/astro/bookings/COMPONENTS.md +0 -45
  158. package/skills/wix-headless/references/astro/bookings/SERVICES_PAGES.md +0 -77
  159. package/skills/wix-headless/references/astro/cms/CMS_FOUNDATIONS.md +0 -214
  160. package/skills/wix-headless/references/astro/cms/FAQ_KNOWLEDGE_BASE.md +0 -231
  161. package/skills/wix-headless/references/astro/cms/PORTFOLIO.md +0 -453
  162. package/skills/wix-headless/references/astro/cms/RESOURCE_LIBRARY.md +0 -354
  163. package/skills/wix-headless/references/astro/cms/TEAM_DIRECTORY.md +0 -299
  164. package/skills/wix-headless/references/astro/designer/INSTRUCTIONS.md +0 -351
  165. package/skills/wix-headless/references/astro/ecom/CART_PAGES.md +0 -119
  166. package/skills/wix-headless/references/astro/ecom/CART_WIRING.md +0 -103
  167. package/skills/wix-headless/references/astro/ecom/COMPONENTS_CSS.md +0 -132
  168. package/skills/wix-headless/references/astro/forms/CONTACT_FORM.md +0 -463
  169. package/skills/wix-headless/references/astro/gift-cards/COMPONENTS.md +0 -119
  170. package/skills/wix-headless/references/astro/gift-cards/PAGES.md +0 -129
  171. package/skills/wix-headless/references/astro/stores/BACK_IN_STOCK.md +0 -178
  172. package/skills/wix-headless/references/astro/stores/CATEGORY_PAGES.md +0 -85
  173. package/skills/wix-headless/references/astro/stores/COMPONENTS_CSS.md +0 -129
  174. package/skills/wix-headless/references/astro/stores/HOME_AND_NAV.md +0 -229
  175. package/skills/wix-headless/references/astro/stores/PRODUCT_PAGES.md +0 -215
  176. package/skills/wix-headless/references/astro/stores/SHARED_WIRING.md +0 -165
  177. package/skills/wix-headless/references/astro/templates/Layout.astro +0 -132
  178. package/skills/wix-headless/references/astro/templates/astro.config.mjs +0 -41
  179. package/skills/wix-headless/references/astro/templates/bookings/AvailabilityCalendar.tsx +0 -374
  180. package/skills/wix-headless/references/astro/templates/bookings/BookingForm.tsx +0 -136
  181. package/skills/wix-headless/references/astro/templates/bookings/SeoTags.astro +0 -25
  182. package/skills/wix-headless/references/astro/templates/bookings/ServiceBookingFlow.tsx +0 -71
  183. package/skills/wix-headless/references/astro/templates/bookings/ServiceCard.astro +0 -54
  184. package/skills/wix-headless/references/astro/templates/bookings/booking-confirmation.astro +0 -49
  185. package/skills/wix-headless/references/astro/templates/bookings/bookingDriver.ts +0 -245
  186. package/skills/wix-headless/references/astro/templates/bookings/components-bookings.css +0 -424
  187. package/skills/wix-headless/references/astro/templates/bookings/services/[slug].astro +0 -176
  188. package/skills/wix-headless/references/astro/templates/bookings/services/index.astro +0 -181
  189. package/skills/wix-headless/references/astro/templates/ecom/CartBadge.tsx +0 -84
  190. package/skills/wix-headless/references/astro/templates/ecom/CartView.tsx +0 -543
  191. package/skills/wix-headless/references/astro/templates/ecom/cart.astro +0 -13
  192. package/skills/wix-headless/references/astro/templates/ecom/components-ecom.css +0 -302
  193. package/skills/wix-headless/references/astro/templates/ecom/discounts.ts +0 -71
  194. package/skills/wix-headless/references/astro/templates/ecom/thank-you.astro +0 -24
  195. package/skills/wix-headless/references/astro/templates/gift-cards/GiftCardPurchase.tsx +0 -172
  196. package/skills/wix-headless/references/astro/templates/gift-cards/_home-teaser-snippet.astro +0 -42
  197. package/skills/wix-headless/references/astro/templates/gift-cards/_nav-snippet.astro +0 -11
  198. package/skills/wix-headless/references/astro/templates/gift-cards/components-gift-cards.css +0 -220
  199. package/skills/wix-headless/references/astro/templates/gift-cards/gift-cards.astro +0 -51
  200. package/skills/wix-headless/references/astro/templates/gift-cards/gift-cards.ts +0 -75
  201. package/skills/wix-headless/references/astro/templates/global.css +0 -288
  202. package/skills/wix-headless/references/astro/templates/stores/AddToCartButton.tsx +0 -77
  203. package/skills/wix-headless/references/astro/templates/stores/BackInStockForm.tsx +0 -176
  204. package/skills/wix-headless/references/astro/templates/stores/CategoryRail.astro +0 -69
  205. package/skills/wix-headless/references/astro/templates/stores/ProductCard.astro +0 -79
  206. package/skills/wix-headless/references/astro/templates/stores/ProductPurchase.tsx +0 -397
  207. package/skills/wix-headless/references/astro/templates/stores/SeoTags.astro +0 -21
  208. package/skills/wix-headless/references/astro/templates/stores/back-in-stock.ts +0 -67
  209. package/skills/wix-headless/references/astro/templates/stores/categories.ts +0 -155
  210. package/skills/wix-headless/references/astro/templates/stores/category/[slug].astro +0 -130
  211. package/skills/wix-headless/references/astro/templates/stores/components-stores.css +0 -400
  212. package/skills/wix-headless/references/astro/templates/stores/products/[slug].astro +0 -128
  213. package/skills/wix-headless/references/astro/templates/stores/products/index.astro +0 -101
  214. package/skills/wix-headless/references/blog/BLOG_CONTENT.md +0 -161
  215. package/skills/wix-headless/references/blog/INSTRUCTIONS.md +0 -32
  216. package/skills/wix-headless/references/bookings/FLOW.md +0 -246
  217. package/skills/wix-headless/references/bookings/INSTRUCTIONS.md +0 -95
  218. package/skills/wix-headless/references/bookings/SERVICES_DATA.md +0 -355
  219. package/skills/wix-headless/references/cms/CMS_FOUNDATIONS.md +0 -176
  220. package/skills/wix-headless/references/cms/INSTRUCTIONS.md +0 -71
  221. package/skills/wix-headless/references/commands/known-apps.json +0 -6
  222. package/skills/wix-headless/references/custom/CONNECTION_PLAN.md +0 -142
  223. package/skills/wix-headless/references/custom/INSTRUCTIONS.md +0 -88
  224. package/skills/wix-headless/references/custom/blog/WIRING.md +0 -52
  225. package/skills/wix-headless/references/custom/bookings/WIRING.md +0 -197
  226. package/skills/wix-headless/references/custom/cms/WIRING.md +0 -97
  227. package/skills/wix-headless/references/custom/ecom/WIRING.md +0 -67
  228. package/skills/wix-headless/references/custom/forms/WIRING.md +0 -101
  229. package/skills/wix-headless/references/custom/stores/WIRING.md +0 -80
  230. package/skills/wix-headless/references/ecom/INSTRUCTIONS.md +0 -59
  231. package/skills/wix-headless/references/forms/INSTRUCTIONS.md +0 -43
  232. package/skills/wix-headless/references/gift-cards/INSTRUCTIONS.md +0 -51
  233. package/skills/wix-headless/references/images/INSTRUCTIONS.md +0 -357
  234. package/skills/wix-headless/references/seed-recipes.md +0 -49
  235. package/skills/wix-headless/references/shared/AGENTS_MD.md +0 -47
  236. package/skills/wix-headless/references/shared/AUTHENTICATION.md +0 -108
  237. package/skills/wix-headless/references/shared/BUILD_NOISE.md +0 -8
  238. package/skills/wix-headless/references/shared/DESIGN_MD.md +0 -84
  239. package/skills/wix-headless/references/shared/DOCS_SEARCH.md +0 -41
  240. package/skills/wix-headless/references/shared/IMAGE_GENERATION.md +0 -186
  241. package/skills/wix-headless/references/shared/IMPLEMENTER.md +0 -206
  242. package/skills/wix-headless/references/shared/PRODUCTION_SHARP_EDGES.md +0 -97
  243. package/skills/wix-headless/references/shared/RETURN_CONTRACT.md +0 -143
  244. package/skills/wix-headless/references/shared/STYLING.md +0 -140
  245. package/skills/wix-headless/references/stores/INSTRUCTIONS.md +0 -126
  246. package/skills/wix-headless/references/stores/PRODUCT_CATALOG_DATA.md +0 -252
  247. package/skills/wix-headless/references/verticals/_schema.json +0 -74
  248. package/skills/wix-headless/references/verticals/_schema.md +0 -95
  249. package/skills/wix-headless/references/verticals/blog.md +0 -31
  250. package/skills/wix-headless/references/verticals/bookings.md +0 -41
  251. package/skills/wix-headless/references/verticals/cms.md +0 -30
  252. package/skills/wix-headless/references/verticals/ecom.md +0 -25
  253. package/skills/wix-headless/references/verticals/forms.md +0 -26
  254. package/skills/wix-headless/references/verticals/gift-cards.md +0 -24
  255. package/skills/wix-headless/references/verticals/stores.md +0 -33
  256. package/skills/wix-headless/scripts/check-manifest.mjs +0 -335
  257. package/skills/wix-headless/scripts/compose.mjs +0 -520
  258. package/skills/wix-headless/scripts/emit-design-tokens.mjs +0 -157
  259. package/skills/wix-headless/scripts/flatten.sh +0 -61
  260. package/skills/wix-headless/scripts/generate-images.mjs +0 -242
  261. package/skills/wix-headless/scripts/patch-decorative-slots.mjs +0 -154
  262. package/skills/wix-headless/scripts/plan-entity-image-waves.mjs +0 -190
  263. package/skills/wix-headless/scripts/scaffold.sh +0 -139
  264. package/skills/wix-headless/scripts/seed-utilities.sh +0 -93
  265. package/skills/wix-headless/scripts/write-decorative-json.mjs +0 -62
  266. package/skills/wix-headless/shared-utilities/analytics.ts +0 -40
  267. package/skills/wix-headless/shared-utilities/ricos.ts +0 -179
  268. package/skills/wix-headless/shared-utilities/wix-image.ts +0 -72
@@ -0,0 +1,164 @@
1
+
2
+ # Wix Storefront Skill
3
+
4
+ > **Source files (in this skill):** the shared transport `references/shared/wix-client.js` and both storefront helpers from `references/storefront/`. All helpers import from `"./wix-client.js"`, so copy them into the same folder (e.g. `src/rest/`). Copy **both** for a full storefront:
5
+ >
6
+ > | File | What it covers |
7
+ > |---|---|
8
+ > | `wix-store-catalog.js` | Products, categories, product detail, search |
9
+ > | `wix-store-cart.js` | Add to cart, cart management, checkout |
10
+
11
+ Builds a real, client-only Wix storefront. The browser talks to Wix directly over a
12
+ public `WIX_CLIENT_ID`. Never mock products; never hand-build `/checkout` URLs — always
13
+ go through the eCom cart + redirect-session.
14
+
15
+ ## When to use
16
+ - User wants a Wix eCommerce store or asks to "connect Wix".
17
+ - Replacing placeholder/mock products with live Wix data.
18
+ - Adding cart, checkout, categories, or product detail pages over an existing Wix Stores catalog.
19
+
20
+ ## Prerequisites
21
+ 1. A Wix site with **Wix Stores installed and products already added** (this skill does
22
+ NOT provision — it's read-only over the catalog).
23
+ 2. The site's public headless **`WIX_CLIENT_ID`**, provided in the handoff prompt (the
24
+ Wix Business Manager surfaces a copyable prompt with the id filled in — see
25
+ the router `SKILL.md`). Paste it into `src/rest/wix-client.js` in place of the placeholder. It is a
26
+ buyer-facing credential (it only mints anonymous visitor tokens), **not** a secret, so
27
+ hardcoding/committing it is fine.
28
+ 3. The deployed app domain must be allow-listed on the OAuth client for Wix-hosted
29
+ checkout to return. This is a **separate Wix setup flow the user completes later** —
30
+ out of this skill's scope. If checkout return fails before that setup is done, that's
31
+ expected; flag it and continue.
32
+
33
+ ## The API (copy as-is; do not re-derive it)
34
+ This skill ships only the REST layer — no UI components. Build the storefront's UI
35
+ however the project wants; wire it to these two snippets. Copy them into the app (e.g.
36
+ `src/api/`) and only adjust import paths:
37
+ - `src/rest/wix-client.js` — visitor-token mint/refresh + transport. Set `WIX_CLIENT_ID` to
38
+ the id from the prompt (replace the `<YOUR-CLIENT-ID>` placeholder). The visitor refresh
39
+ token IS the cart identity; it is persisted to localStorage. Do not re-mint anonymously
40
+ per load or the cart silently empties.
41
+ - `src/rest/wix-store-catalog.js` — **Catalog:**
42
+ `queryProducts`, `queryProductsByCategory`, `getProductBySlug`, `countProducts`,
43
+ `queryCategories`, `getCategoryBySlug`
44
+ - `src/rest/wix-store-cart.js` — **Cart & checkout:**
45
+ `addToCart`, `getCurrentCart`, `updateCartItemQuantity`, `removeFromCart`, `checkout`
46
+
47
+ The Product and Cart shapes are documented as JSDoc comments at the top of each helper file.
48
+ Read them before building the UI — they describe the key fields and link to the full API
49
+ reference for anything not shown.
50
+
51
+ ## How to wire it (UI is the project's choice)
52
+ - **Product grid** — `queryProducts()` for the listing (visible products only); pass
53
+ `nextCursor` back as `cursor` to load the next page. Render most fields directly from the Wix
54
+ product object (see the `Product` typedef in `wix-store-catalog.js` for key fields) — the one
55
+ exception is `plainDescription`, which is HTML (see PDP below). For price, use
56
+ `actualPriceRange.minValue.formattedAmount` (already includes the currency symbol) — no
57
+ manual formatting needed.
58
+ - **PDP** — `getProductBySlug(slug)` keyed off the URL slug; returns null on miss — show
59
+ a not-found state, never invent a product. **Drive the whole PDP from the returned product
60
+ object at runtime — build it generically, not around the one product you happened to inspect.**
61
+ A catalog is heterogeneous: some products have `options`, some have `modifiers` (mandatory or
62
+ optional), some track inventory, some none of these. Render a selector for **every** entry the
63
+ product actually carries: one control per `product.options` (variant choices) **and** one per
64
+ `product.modifiers` (TEXT_CHOICES → choice buttons/select; FREE_TEXT → a text input); render
65
+ neither when the arrays are empty. Skipping modifiers is a common miss — a product with a
66
+ **mandatory** modifier (e.g. "gift wrap?") whose control isn't rendered can never be added: the
67
+ buyer can't satisfy the requirement, so `add-to-cart` returns 200 with an **empty** `lineItems`
68
+ and the add silently no-ops.
69
+ Render `product.plainDescription` as **HTML** — despite the name it contains markup (`<p>`,
70
+ `<br>`, `<strong>`), so `dangerouslySetInnerHTML={{ __html: product.plainDescription }}` (React)
71
+ or `el.innerHTML = product.plainDescription`, never as a plain text node (that shows raw `<p>`
72
+ tags). Strip tags only for plain-text contexts (SEO/meta description, a truncated card teaser).
73
+ - **Gate the Add-to-cart button** — disable it only until the requirements the product *actually
74
+ has* are met, computed from the product object (never assume every product has options or
75
+ modifiers): if `product.options` is non-empty, a variant must resolve from the selections; every
76
+ `modifier.mandatory === true` must have a value. A product with no options and no mandatory
77
+ modifiers is immediately addable — don't leave the button stuck. Optional modifiers never block.
78
+ Then pass the selections to `addToCart` (see Cart below); never call it with a required selection missing.
79
+ - **Reflect stock in the UI** — the product object already carries availability at three levels; surface
80
+ it rather than letting the buyer discover it only on click. Read it from the data at runtime (never
81
+ hardcode):
82
+ - **Grid / card:** `product.inventory.availabilityStatus` (`IN_STOCK` / `OUT_OF_STOCK` /
83
+ `PARTIALLY_OUT_OF_STOCK`) — badge an out-of-stock product as sold out.
84
+ - **Option choice:** `product.options[].choicesSettings.choices[].inStock` — disable/strike a choice
85
+ (e.g. size L) that has no in-stock variant, before a full variant is even resolved.
86
+ - **Variant:** `variantsInfo.variants[].inventoryStatus.inStock` — once selections resolve to a
87
+ variant, disable Add-to-cart (label "Out of stock") when that variant is `inStock: false`.
88
+ A product/variant with inventory tracking **off** reports `availabilityStatus: IN_STOCK` /
89
+ `inStock: true` and stays freely addable — tracking-off is not "no data", it's "always available".
90
+ `addToCart` still throws on a sold-out line as a backstop, but the UI should prevent reaching it.
91
+ - **Categories** — `queryCategories()` for a category menu; `getCategoryBySlug(slug)` for
92
+ a category landing page. Pass `category.id` to `queryProductsByCategory(categoryId, { limit?, cursor? })`
93
+ to list only the products in that category; paginate exactly like `queryProducts`.
94
+ `queryCategories()` includes Wix's auto-created **"All Products" system category** (`slug:
95
+ "all-products"`) — it mirrors the full catalog, so drop it from the category menu
96
+ (`categories.filter(c => c.slug !== "all-products")`). Filter by that slug, not by name (renames/
97
+ localizes) or `visible` (it's `visible: true` like any other).
98
+ - **Cart** — `addToCart(catalogItemId, variantId?, qty?, { modifierChoices?, customTextFields? }?)`,
99
+ `updateCartItemQuantity(lineItemId, qty)`, `removeFromCart(lineItemId)`.
100
+ - `variantId` (`variantsInfo.variants[].id` from `getProductBySlug`) — required for products with
101
+ options; resolve it by matching the buyer's selections to `variant.choices[].optionChoiceIds`.
102
+ - `modifierChoices` — `{ [modifier.key]: choiceKey }` for `TEXT_CHOICES` modifiers.
103
+ - `customTextFields` — `{ [modifier.freeTextSettings.key]: userInput }` for `FREE_TEXT` modifiers.
104
+ Mandatory modifiers must be included. See the eCommerce integration guide:
105
+ https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/e-commerce-integration.md
106
+ - Use `cart.lineItems[].id` as `lineItemId` (not `catalogItemId`) for mutations.
107
+ - Read the cart back with `getCurrentCart()` rather than mirroring it locally.
108
+ - **Checkout** — `window.location.href = await checkout()`. After the buyer returns from
109
+ hosted checkout the order is placed and the cart is empty — re-fetch with
110
+ `getCurrentCart()` on return (e.g. on mount + `visibilitychange`) to clear the UI.
111
+ - **Empty state** — if `countProducts()` is 0, show an empty state telling the user to
112
+ add products in their Wix dashboard. Never invent products.
113
+
114
+ ## Hard rules (do not violate)
115
+ - ✅ Checkout ONLY via `checkout()` (`create-checkout` → `/headless/v1/redirect-session`
116
+ `fullUrl`), then redirect.
117
+ - ❌ Never hand-build `/checkout`, cart-add, or product permalinks for purchase.
118
+ - ❌ Never mock products — render live Wix data or the empty state.
119
+ - ❌ Never generate fake reviews, ratings, or testimonials. Empty review UI only.
120
+ - ✅ Set `WIX_CLIENT_ID` from the prompt's value (public client id — safe to hardcode).
121
+ - ✅ `lineItemId` for cart mutations is `cart.lineItems[].id`, not `catalogItemId`.
122
+ - ✅ On the PDP, render a control for **every** `product.options` entry **and** every `product.modifiers`
123
+ entry — never only variants. Keep Add-to-cart disabled until a variant resolves and every
124
+ `modifier.mandatory === true` has a value; a mandatory modifier with no rendered control makes the
125
+ product unbuyable (add-to-cart returns 200 with empty `lineItems`).
126
+ - ✅ Pass `addToCart`'s `variantId` (`variantsInfo.variants[].id`) for products with variants; omit for products without.
127
+ - ✅ Pass `modifierChoices` (`{ [modifier.key]: choiceKey }`) for TEXT_CHOICES modifiers; pass `customTextFields`
128
+ (`{ [modifier.freeTextSettings.key]: userInput }`) for FREE_TEXT modifiers. Include mandatory modifiers.
129
+ - The engine fails loudly on purpose: `addToCart`/`checkout` throw on out-of-stock or
130
+ empty carts. A green path means it is really buyable — don't swallow these.
131
+
132
+ ## Beyond the snippets
133
+ The snippets cover the common storefront paths. If you hit a use case they don't cover
134
+ (e.g. coupons, members/auth, a product field not shown in the typedef), make the call
135
+ yourself with `wixApiRequest` — but look up the exact endpoint, HTTP method, and request
136
+ body in the **official Wix API reference** first; never guess:
137
+ - Official Wix API reference: https://dev.wix.com/docs/api-reference.md
138
+ - eCommerce integration guide (modifiers, custom text, variants): https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/e-commerce-integration.md
139
+ - Member login + a "my orders" account view → the **members** vertical (`references/members/INSTRUCTIONS.md`): custom login on your own UI so buyers can sign in and see their account.
140
+
141
+ Keep the snippets as the default for everything they already do; reach for the API
142
+ reference only for the gap.
143
+
144
+ ## Point the user to their dashboard
145
+ In some cases, users need to access the Wix dashboard in order to edit the store content for their site. To facilitate this, provide the user with deep links directly to the relevant dashboard pages. For store data those pages are:
146
+ - **Products** — `https://manage.wix.com/dashboard/{metaSiteId}/wix-stores/products` (`Dashboard → Store → Products`; add/edit products, variants, inventory)
147
+ - **Categories** — `https://manage.wix.com/dashboard/{metaSiteId}/wix-stores/categories/list` (`Dashboard → Store → Categories`; organize products into the category menu)
148
+
149
+ Substitute the site's `metaSiteId` to complete the links (you have it from the handoff / `ListWixSites`). Include the in-dashboard navigation as a fallback.
150
+
151
+ ## Verification checklist (before declaring done)
152
+ - [ ] `WIX_CLIENT_ID` set to the prompt's value (not the `<YOUR-CLIENT-ID>` placeholder)
153
+ - [ ] Visitor token persists across reload (cart survives reload, same visitor)
154
+ - [ ] Every product choice renders on the PDP — variant options **and** modifiers (mandatory ones included)
155
+ - [ ] Add-to-cart button stays disabled until all required choices are made (variant + mandatory modifiers)
156
+ - [ ] A product with a mandatory modifier adds successfully (its selection is sent, cart line appears)
157
+ - [ ] Stock reflected in the UI — sold-out product badged (grid), out-of-stock option choices and variants disabled/labelled (PDP)
158
+ - [ ] Add to cart works; out-of-stock items throw rather than add a dead line
159
+ - [ ] Quantity update / remove reflect in `getCurrentCart()`
160
+ - [ ] Checkout redirects via redirect-session `fullUrl` (no hand-built URL)
161
+ - [ ] Cart re-fetched on return from checkout (clears once the order is placed)
162
+ - [ ] Empty state shown when `countProducts()` is 0
163
+ - [ ] No mock products anywhere
164
+ - [ ] Told the user at least once that they can continue setting up their store in the dashboard and provided deep links.
@@ -0,0 +1,147 @@
1
+ import { wixApiRequest } from "./wix-client.js";
2
+
3
+ // Data model reference: see INSTRUCTIONS.md
4
+ // Product shape (for addToCart): see wix-store-catalog.js
5
+
6
+ // Stores app id — required inside catalogReference for store products.
7
+ const STORES_APP_ID = "215238eb-22a5-4c36-9e7b-e7c08025e04e";
8
+
9
+ /**
10
+ * Wix eCom Cart — key fields for building a cart UI.
11
+ * Full model: https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/purchase-flow/cart/get-cart.md
12
+ *
13
+ * id {string}, currency {string},
14
+ * lineItems[].id {string} — lineItemId for update/remove (NOT catalogItemId),
15
+ * lineItems[].quantity {number},
16
+ * lineItems[].catalogReference.catalogItemId {string},
17
+ * lineItems[].productName.original {string},
18
+ * lineItems[].price.formattedAmount {string} — after discounts with currency symbol,
19
+ * lineItems[].fullPrice.formattedAmount {string} — before discount (strikethrough),
20
+ * lineItems[].descriptionLines {array} — human-readable option/modifier labels:
21
+ * [{ name: { original }, plainText: { original } OR colorInfo: { original, code } }],
22
+ * lineItems[].image.url {string},
23
+ * lineItems[].availability.status {string} — "AVAILABLE"|"NOT_AVAILABLE"|"PARTIALLY_AVAILABLE"|"NOT_FOUND"
24
+ */
25
+
26
+ /**
27
+ * Add a product to the visitor's current cart.
28
+ *
29
+ * For products with options (variants), pass the chosen variantId — resolve it from
30
+ * product.variantsInfo.variants (from getProductBySlug) by matching the buyer's selected
31
+ * option choices to variant.choices[].optionChoiceIds.
32
+ *
33
+ * For products with modifiers:
34
+ * - TEXT_CHOICES: pass modifierChoices: { [modifier.key]: choiceKey }
35
+ * - FREE_TEXT: pass customTextFields: { [modifier.freeTextSettings.key]: userInput }
36
+ * Mandatory modifiers (modifier.mandatory === true) MUST be included.
37
+ *
38
+ * Throws on out-of-stock so the buyer can't reach checkout with an unbuyable line.
39
+ * Full catalogReference reference: https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/e-commerce-integration.md
40
+ *
41
+ * @param {string} catalogItemId Product GUID (product.id).
42
+ * @param {string} [variantId] variantsInfo.variants[].id — required for products with variants.
43
+ * @param {number} [quantity]
44
+ * @param {{ modifierChoices?: Record<string,string>, customTextFields?: Record<string,string> }} [extras]
45
+ * @returns {Promise<object>} Updated cart.
46
+ */
47
+ export async function addToCart(catalogItemId, variantId, quantity = 1, { modifierChoices, customTextFields } = {}) {
48
+ const catalogReferenceOptions = {};
49
+ if (variantId) catalogReferenceOptions.variantId = variantId;
50
+ if (modifierChoices && Object.keys(modifierChoices).length) catalogReferenceOptions.options = modifierChoices;
51
+ if (customTextFields && Object.keys(customTextFields).length) catalogReferenceOptions.customTextFields = customTextFields;
52
+
53
+ const catalogReference = { appId: STORES_APP_ID, catalogItemId };
54
+ if (Object.keys(catalogReferenceOptions).length) catalogReference.options = catalogReferenceOptions;
55
+ const res = await wixApiRequest("/ecom/v1/carts/current/add-to-cart", {
56
+ method: "POST",
57
+ body: { lineItems: [{ catalogReference, quantity }] },
58
+ });
59
+ const line = (res?.cart?.lineItems ?? []).find(
60
+ (l) => l.catalogReference?.catalogItemId === catalogItemId && (!variantId || l.catalogReference?.options?.variantId === variantId),
61
+ );
62
+ // Wix returns 200 even when the line is silently rejected — guard both signals:
63
+ // 1. availability.status set to something other than AVAILABLE
64
+ // 2. no matching line at all (quantity 0 / line absent)
65
+ if (line?.availability?.status && line.availability.status !== "AVAILABLE") {
66
+ throw new Error(`Item not available for sale (status: ${line.availability.status}). Is it in stock?`);
67
+ }
68
+ if (!line || line.quantity === 0) {
69
+ // A missing line usually means a required selection wasn't sent — a mandatory modifier
70
+ // (pass modifierChoices/customTextFields) or the variantId for a product with options —
71
+ // not necessarily out of stock. Verify every required choice is included in this call.
72
+ throw new Error(
73
+ "Item could not be added to the cart. Check that every required selection was sent: " +
74
+ "the variantId for a product with options, and all mandatory modifiers " +
75
+ "(modifierChoices for TEXT_CHOICES, customTextFields for FREE_TEXT). It may also be out of stock.",
76
+ );
77
+ }
78
+ return res?.cart;
79
+ }
80
+
81
+ /** Read the visitor's current cart. Returns null if no cart exists yet. */
82
+ export async function getCurrentCart() {
83
+ try {
84
+ const res = await wixApiRequest("/ecom/v1/carts/current", { method: "GET" });
85
+ return res?.cart ?? null;
86
+ } catch {
87
+ return null;
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Create a checkout from the current cart and return the hosted checkout URL.
93
+ * Throws on empty cart, unavailable lines, or a missing redirect URL.
94
+ * Usage: window.location.href = await checkout()
95
+ * @returns {Promise<string>}
96
+ */
97
+ export async function checkout() {
98
+ const cart = await getCurrentCart();
99
+ const lines = cart?.lineItems ?? [];
100
+ if (!lines.length) throw new Error("Cannot check out: the cart is empty.");
101
+ const unavailable = lines.filter((l) => l.availability?.status && l.availability.status !== "AVAILABLE");
102
+ if (unavailable.length) {
103
+ const names = unavailable.map((l) => l.productName?.original ?? l.catalogReference?.catalogItemId).join(", ");
104
+ throw new Error(`Cannot check out: ${unavailable.length} item(s) not available — ${names}.`);
105
+ }
106
+
107
+ const checkoutRes = await wixApiRequest("/ecom/v1/carts/current/create-checkout", {
108
+ method: "POST",
109
+ body: { channelType: "WEB" },
110
+ });
111
+ const checkoutId = checkoutRes?.checkoutId;
112
+ if (!checkoutId) throw new Error("Failed to create checkout from the current cart.");
113
+
114
+ const redirect = await wixApiRequest("/headless/v1/redirect-session", {
115
+ method: "POST",
116
+ body: { ecomCheckout: { checkoutId }, callbacks: { postFlowUrl: window.location.href } },
117
+ });
118
+ const url = redirect?.redirectSession?.fullUrl;
119
+ if (!url) throw new Error("Failed to create the checkout redirect session.");
120
+ return url;
121
+ }
122
+
123
+ /**
124
+ * Update the quantity of a cart line. lineItemId is cart.lineItems[].id, not catalogItemId.
125
+ * Wix caps the result at remaining stock — returned quantity may be lower than requested.
126
+ * @returns {Promise<object>} Updated cart.
127
+ */
128
+ export async function updateCartItemQuantity(lineItemId, quantity) {
129
+ const res = await wixApiRequest("/ecom/v1/carts/current/update-line-items-quantity", {
130
+ method: "POST",
131
+ body: { lineItems: [{ id: lineItemId, quantity }] },
132
+ });
133
+ return res?.cart;
134
+ }
135
+
136
+ /**
137
+ * Remove a line from the current cart by its cart.lineItems[].id.
138
+ * @param {string} lineItemId
139
+ * @returns {Promise<object>} Updated cart.
140
+ */
141
+ export async function removeFromCart(lineItemId) {
142
+ const res = await wixApiRequest("/ecom/v1/carts/current/remove-line-items", {
143
+ method: "POST",
144
+ body: { lineItemIds: [lineItemId] },
145
+ });
146
+ return res?.cart;
147
+ }
@@ -0,0 +1,146 @@
1
+ import { wixApiRequest } from "./wix-client.js";
2
+
3
+ // Data model reference: see INSTRUCTIONS.md
4
+
5
+ /**
6
+ * Wix Stores V3 Product — key fields for the storefront catalog.
7
+ * Full model: https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/products-v3/query-products.md
8
+ *
9
+ * id {string}, name {string}, slug {string}, visible {boolean}, productType "PHYSICAL"|"DIGITAL",
10
+ * mainCategoryId {string},
11
+ * media.main.image {object} — { id, url, height, width, altText },
12
+ * media.itemsInfo.items {array} — gallery: [{ id, altText, image: { id, url, height, width, altText }, mediaType }],
13
+ * actualPriceRange.minValue.formattedAmount {string} — lowest price with currency symbol,
14
+ * actualPriceRange.maxValue.formattedAmount {string} — highest price with currency symbol,
15
+ * compareAtPriceRange.minValue.formattedAmount {string} — strikethrough price (present when on sale),
16
+ * inventory.availabilityStatus {string} — "IN_STOCK"|"OUT_OF_STOCK"|"PARTIALLY_OUT_OF_STOCK",
17
+ * options {array} — product options e.g. Size, Color:
18
+ * [{ id, name, optionRenderType "TEXT_CHOICES"|"COLOR_CHOICES"|"SWATCH_CHOICES",
19
+ * choicesSettings.choices [{ choiceId, key, name, inStock, visible, linkedMedia }] }],
20
+ * modifiers {array} — non-variant customizations (engraving, gift wrap):
21
+ * [{ id, name, mandatory, modifierRenderType "TEXT_CHOICES"|"FREE_TEXT",
22
+ * key, choicesSettings.choices, freeTextSettings.key }],
23
+ * plainDescription {string} — product description as an HTML string (contains <p>, <br>,
24
+ * <strong>…) despite the "plain" name — NOT plain text. Render with innerHTML /
25
+ * dangerouslySetInnerHTML; strip tags only for plain-text contexts (meta description, teaser),
26
+ * variantsInfo.variants {array} — returned only by getProductBySlug:
27
+ * [{ id, visible, choices [{ optionChoiceIds: { optionId, choiceId } }],
28
+ * price: { actualPrice, compareAtPrice }, media, inventoryStatus: { inStock } }]
29
+ * To resolve a buyer's option selections to a variantId: find the variant whose choices
30
+ * match all selected { optionId, choiceId } pairs, then pass variant.id to addToCart.
31
+ *
32
+ * Category: { id, name, slug, visible, description, image, itemCounter, parentCategory.id }
33
+ * NB: queryCategories includes the auto-created system category { slug: "all-products" } —
34
+ * filter it out of a category menu (see INSTRUCTIONS.md). `visible` does not flag it.
35
+ * Full model: https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/categories
36
+ */
37
+
38
+ /**
39
+ * Query visible products (one page). Pass nextCursor back as cursor to load the next page.
40
+ * @param {{ limit?: number, cursor?: string }} [options]
41
+ * @returns {Promise<{ products: object[], nextCursor: string|null }>}
42
+ */
43
+ export async function queryProducts({ limit = 100, cursor } = {}) {
44
+ const res = await wixApiRequest("/stores/v3/products/query", {
45
+ method: "POST",
46
+ body: {
47
+ fields: ["CURRENCY", "PLAIN_DESCRIPTION", "MEDIA_ITEMS_INFO"],
48
+ query: {
49
+ ...(cursor ? {} : { filter: { visible: true } }),
50
+ cursorPaging: cursor ? { limit, cursor } : { limit },
51
+ },
52
+ },
53
+ });
54
+ return {
55
+ products: res?.products ?? [],
56
+ nextCursor: res?.pagingMetadata?.cursors?.next ?? null,
57
+ };
58
+ }
59
+
60
+ /**
61
+ * Fetch a product by its URL slug. Returns null if not found.
62
+ * Returns the full product including variantsInfo.variants (with per-variant media and choices).
63
+ * @param {string} slug
64
+ * @returns {Promise<object|null>}
65
+ */
66
+ export async function getProductBySlug(slug) {
67
+ const res = await wixApiRequest(`/stores/v3/products/slug/${encodeURIComponent(slug)}`, {
68
+ method: "GET",
69
+ query: { fields: ["CURRENCY", "PLAIN_DESCRIPTION", "MEDIA_ITEMS_INFO"] },
70
+ });
71
+ return res?.product ?? null;
72
+ }
73
+
74
+ /**
75
+ * Query visible products belonging to a category (one page).
76
+ * @param {string} categoryId Category GUID from queryCategories / getCategoryBySlug.
77
+ * @param {{ limit?: number, cursor?: string }} [options]
78
+ * @returns {Promise<{ products: object[], nextCursor: string|null }>}
79
+ */
80
+ export async function queryProductsByCategory(categoryId, { limit = 100, cursor } = {}) {
81
+ const res = await wixApiRequest("/stores/v3/products/search", {
82
+ method: "POST",
83
+ body: {
84
+ fields: ["CURRENCY", "PLAIN_DESCRIPTION", "MEDIA_ITEMS_INFO"],
85
+ search: {
86
+ ...(cursor
87
+ ? { cursorPaging: { limit, cursor } }
88
+ : {
89
+ cursorPaging: { limit },
90
+ filter: {
91
+ visible: true,
92
+ "allCategoriesInfo.categories": { $matchItems: [{ id: categoryId }] },
93
+ },
94
+ }),
95
+ },
96
+ },
97
+ });
98
+ return {
99
+ products: res?.products ?? [],
100
+ nextCursor: res?.pagingMetadata?.cursors?.next ?? null,
101
+ };
102
+ }
103
+
104
+ /**
105
+ * Total number of visible products. Used for empty-state logic (0 → prompt user to add products).
106
+ * @returns {Promise<number>}
107
+ */
108
+ export async function countProducts() {
109
+ const res = await wixApiRequest("/stores/v3/products/count", {
110
+ method: "POST",
111
+ body: { filter: { visible: true } },
112
+ });
113
+ return res?.count ?? 0;
114
+ }
115
+
116
+ /**
117
+ * Query Wix Stores categories (one page).
118
+ * @param {{ limit?: number, cursor?: string }} [options]
119
+ * @returns {Promise<{ categories: object[], nextCursor: string|null }>}
120
+ */
121
+ export async function queryCategories({ limit = 100, cursor } = {}) {
122
+ const res = await wixApiRequest("/categories/v1/categories/query", {
123
+ method: "POST",
124
+ body: {
125
+ treeReference: { appNamespace: "@wix/stores", treeKey: null },
126
+ query: { cursorPaging: cursor ? { limit, cursor } : { limit } },
127
+ },
128
+ });
129
+ return {
130
+ categories: res?.categories ?? [],
131
+ nextCursor: res?.pagingMetadata?.cursors?.next ?? null,
132
+ };
133
+ }
134
+
135
+ /**
136
+ * Get a single category by its URL slug. Returns null if not found.
137
+ * @param {string} slug
138
+ * @returns {Promise<object|null>}
139
+ */
140
+ export async function getCategoryBySlug(slug) {
141
+ const res = await wixApiRequest(`/categories/v1/categories/slug/${encodeURIComponent(slug)}`, {
142
+ method: "GET",
143
+ query: { "treeReference.appNamespace": "@wix/stores" },
144
+ });
145
+ return res?.category ?? null;
146
+ }