@wix/agent-skills 1.21.0 → 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.
Files changed (258) hide show
  1. package/package.json +1 -1
  2. package/skills/wix-app/SKILL.md +60 -4
  3. package/skills/wix-app/references/DASHBOARD_PAGE.md +11 -25
  4. package/skills/wix-app/references/DATA_COLLECTION.md +16 -219
  5. package/skills/wix-app/references/dashboard-page/DATA_SOURCES.md +182 -0
  6. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE.md +97 -0
  7. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_COLLECTION.md +184 -0
  8. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_ROUTER.md +203 -0
  9. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_SETTINGS.md +44 -0
  10. package/skills/wix-app/references/dashboard-page/QUERY_AND_PAGING.md +182 -0
  11. package/skills/wix-app/references/dashboard-page/TABLE_STATE.md +133 -0
  12. package/skills/wix-app/references/dashboard-page/UX_SUCCESS_MODEL.md +10 -5
  13. package/skills/wix-app/references/data-collection/LIFECYCLE.md +68 -0
  14. package/skills/wix-app/references/data-collection/PERMISSIONS.md +47 -0
  15. package/skills/wix-app/references/data-collection/SCHEMA.md +181 -0
  16. package/skills/wix-app/references/data-collection/WIX_DATA.md +38 -66
  17. package/skills/wix-headless-fast/SKILL.md +61 -223
  18. package/skills/wix-headless-fast/cold-start/bootstrap.mjs +156 -0
  19. package/skills/wix-headless-fast/{entry/skill.md → cold-start/cold-start.md} +11 -12
  20. package/skills/wix-headless-fast/guides/existing-site.md +76 -0
  21. package/skills/wix-headless-fast/guides/reference-mode.md +97 -0
  22. package/skills/wix-headless-fast/install/AGENTS.md +6 -3
  23. package/skills/wix-headless-fast/install/attach.mjs +15 -47
  24. package/skills/wix-headless-fast/install/deploy.mjs +21 -60
  25. package/skills/wix-headless-fast/install/lock.mjs +55 -0
  26. package/skills/wix-headless-fast/install/setup.mjs +32 -12
  27. package/skills/wix-headless-fast/install/templates.mjs +168 -0
  28. package/skills/wix-manage/references/google-ads/google-ads-dashboard-navigation.md +27 -0
  29. package/skills/wix-manage/references/google-ads/manage-campaign-success-guide.md +83 -37
  30. package/skills/wix-headless-fast/references/blog/INSTRUCTIONS.md +0 -303
  31. package/skills/wix-headless-fast/references/blog/app/components/blog/BlogFeedView.tsx +0 -136
  32. package/skills/wix-headless-fast/references/blog/app/components/blog/PostView.tsx +0 -112
  33. package/skills/wix-headless-fast/references/blog/app/components/blog/RichContent.tsx +0 -42
  34. package/skills/wix-headless-fast/references/blog/app/hooks/blog/useBlogFeed.ts +0 -31
  35. package/skills/wix-headless-fast/references/blog/app/hooks/blog/usePost.ts +0 -22
  36. package/skills/wix-headless-fast/references/blog/app/wix/blog/blog-feed-store.ts +0 -137
  37. package/skills/wix-headless-fast/references/blog/app/wix/blog/post-store.ts +0 -78
  38. package/skills/wix-headless-fast/references/blog/app/wix/blog/posts-core.ts +0 -117
  39. package/skills/wix-headless-fast/references/blog/app/wix/blog/posts.ts +0 -52
  40. package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy-core.ts +0 -47
  41. package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy.ts +0 -58
  42. package/skills/wix-headless-fast/references/blog/app/wix/blog/types.ts +0 -62
  43. package/skills/wix-headless-fast/references/blog/app-astro/layouts/SiteLayout.astro +0 -40
  44. package/skills/wix-headless-fast/references/blog/app-astro/pages/blog/[...slug].astro +0 -97
  45. package/skills/wix-headless-fast/references/blog/app-astro/pages/blog.astro +0 -24
  46. package/skills/wix-headless-fast/references/blog/lock/astro/package-lock.json +0 -16156
  47. package/skills/wix-headless-fast/references/blog/rest/posts.ts +0 -42
  48. package/skills/wix-headless-fast/references/blog/rest/taxonomy.ts +0 -62
  49. package/skills/wix-headless-fast/references/blog/seed/SEED.md +0 -81
  50. package/skills/wix-headless-fast/references/blog/seed/read-site.mjs +0 -22
  51. package/skills/wix-headless-fast/references/blog/seed/seed-blog.mjs +0 -287
  52. package/skills/wix-headless-fast/references/bookings/INSTRUCTIONS.md +0 -277
  53. package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServiceBookingView.tsx +0 -144
  54. package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServicesView.tsx +0 -119
  55. package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useBookingFlow.ts +0 -32
  56. package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useServices.ts +0 -23
  57. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-core.ts +0 -218
  58. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-flow-store.ts +0 -169
  59. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking.ts +0 -121
  60. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-core.ts +0 -92
  61. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-store.ts +0 -90
  62. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services.ts +0 -57
  63. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/types.ts +0 -72
  64. package/skills/wix-headless-fast/references/bookings/app-astro/layouts/SiteLayout.astro +0 -40
  65. package/skills/wix-headless-fast/references/bookings/app-astro/pages/services/[slug].astro +0 -76
  66. package/skills/wix-headless-fast/references/bookings/app-astro/pages/services.astro +0 -22
  67. package/skills/wix-headless-fast/references/bookings/lock/astro/package-lock.json +0 -11962
  68. package/skills/wix-headless-fast/references/bookings/rest/booking.ts +0 -113
  69. package/skills/wix-headless-fast/references/bookings/rest/services.ts +0 -55
  70. package/skills/wix-headless-fast/references/bookings/seed/SEED.md +0 -71
  71. package/skills/wix-headless-fast/references/bookings/seed/read-site.mjs +0 -28
  72. package/skills/wix-headless-fast/references/bookings/seed/seed-bookings.mjs +0 -302
  73. package/skills/wix-headless-fast/references/cms/INSTRUCTIONS.md +0 -355
  74. package/skills/wix-headless-fast/references/cms/app/hooks/cms/useCollection.ts +0 -50
  75. package/skills/wix-headless-fast/references/cms/app/hooks/cms/useItem.ts +0 -37
  76. package/skills/wix-headless-fast/references/cms/app/wix/cms/collection-store.ts +0 -158
  77. package/skills/wix-headless-fast/references/cms/app/wix/cms/item-store.ts +0 -93
  78. package/skills/wix-headless-fast/references/cms/app/wix/cms/items-core.ts +0 -177
  79. package/skills/wix-headless-fast/references/cms/app/wix/cms/items.ts +0 -123
  80. package/skills/wix-headless-fast/references/cms/app/wix/cms/types.ts +0 -75
  81. package/skills/wix-headless-fast/references/cms/app-astro/layouts/SiteLayout.astro +0 -41
  82. package/skills/wix-headless-fast/references/cms/lock/astro/package-lock.json +0 -11262
  83. package/skills/wix-headless-fast/references/cms/rest/items.ts +0 -125
  84. package/skills/wix-headless-fast/references/cms/seed/SEED.md +0 -112
  85. package/skills/wix-headless-fast/references/cms/seed/read-site.mjs +0 -20
  86. package/skills/wix-headless-fast/references/cms/seed/seed-cms.mjs +0 -324
  87. package/skills/wix-headless-fast/references/events/INSTRUCTIONS.md +0 -307
  88. package/skills/wix-headless-fast/references/events/app/components/events/EventConfirmationView.tsx +0 -66
  89. package/skills/wix-headless-fast/references/events/app/components/events/EventRegistrationView.tsx +0 -178
  90. package/skills/wix-headless-fast/references/events/app/components/events/EventsView.tsx +0 -118
  91. package/skills/wix-headless-fast/references/events/app/hooks/events/useEventRegistration.ts +0 -35
  92. package/skills/wix-headless-fast/references/events/app/hooks/events/useEvents.ts +0 -24
  93. package/skills/wix-headless-fast/references/events/app/wix/events/events-core.ts +0 -130
  94. package/skills/wix-headless-fast/references/events/app/wix/events/events-store.ts +0 -97
  95. package/skills/wix-headless-fast/references/events/app/wix/events/events.ts +0 -55
  96. package/skills/wix-headless-fast/references/events/app/wix/events/registration-core.ts +0 -113
  97. package/skills/wix-headless-fast/references/events/app/wix/events/registration-store.ts +0 -156
  98. package/skills/wix-headless-fast/references/events/app/wix/events/registration.ts +0 -97
  99. package/skills/wix-headless-fast/references/events/app/wix/events/types.ts +0 -61
  100. package/skills/wix-headless-fast/references/events/app-astro/layouts/SiteLayout.astro +0 -40
  101. package/skills/wix-headless-fast/references/events/app-astro/pages/event-confirmation.astro +0 -12
  102. package/skills/wix-headless-fast/references/events/app-astro/pages/events/[slug].astro +0 -80
  103. package/skills/wix-headless-fast/references/events/app-astro/pages/events.astro +0 -21
  104. package/skills/wix-headless-fast/references/events/lock/astro/package-lock.json +0 -11884
  105. package/skills/wix-headless-fast/references/events/rest/events.ts +0 -57
  106. package/skills/wix-headless-fast/references/events/rest/registration.ts +0 -83
  107. package/skills/wix-headless-fast/references/events/seed/SEED.md +0 -95
  108. package/skills/wix-headless-fast/references/events/seed/read-site.mjs +0 -26
  109. package/skills/wix-headless-fast/references/events/seed/seed-events.mjs +0 -276
  110. package/skills/wix-headless-fast/references/forms/INSTRUCTIONS.md +0 -340
  111. package/skills/wix-headless-fast/references/forms/app/hooks/forms/useWixForm.ts +0 -85
  112. package/skills/wix-headless-fast/references/forms/app/wix/forms/form-store.ts +0 -332
  113. package/skills/wix-headless-fast/references/forms/app/wix/forms/forms-core.ts +0 -238
  114. package/skills/wix-headless-fast/references/forms/app/wix/forms/forms.ts +0 -54
  115. package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions-core.ts +0 -216
  116. package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions.ts +0 -59
  117. package/skills/wix-headless-fast/references/forms/app/wix/forms/types.ts +0 -135
  118. package/skills/wix-headless-fast/references/forms/lock/astro/package-lock.json +0 -10593
  119. package/skills/wix-headless-fast/references/forms/rest/forms.ts +0 -34
  120. package/skills/wix-headless-fast/references/forms/rest/submissions.ts +0 -56
  121. package/skills/wix-headless-fast/references/forms/seed/SEED.md +0 -116
  122. package/skills/wix-headless-fast/references/forms/seed/read-site.mjs +0 -20
  123. package/skills/wix-headless-fast/references/forms/seed/seed-forms.mjs +0 -327
  124. package/skills/wix-headless-fast/references/members/INSTRUCTIONS.md +0 -316
  125. package/skills/wix-headless-fast/references/members/app/components/members/AccountView.tsx +0 -60
  126. package/skills/wix-headless-fast/references/members/app/components/members/LoginForm.tsx +0 -155
  127. package/skills/wix-headless-fast/references/members/app/components/members/MemberMenu.tsx +0 -78
  128. package/skills/wix-headless-fast/references/members/app/components/members/RequireAuth.tsx +0 -47
  129. package/skills/wix-headless-fast/references/members/app/hooks/members/useMember.ts +0 -66
  130. package/skills/wix-headless-fast/references/members/app/wix/members/auth-core.ts +0 -105
  131. package/skills/wix-headless-fast/references/members/app/wix/members/auth.ts +0 -59
  132. package/skills/wix-headless-fast/references/members/app/wix/members/client.ts +0 -53
  133. package/skills/wix-headless-fast/references/members/app/wix/members/member-store.ts +0 -122
  134. package/skills/wix-headless-fast/references/members/app/wix/members/members-core.ts +0 -43
  135. package/skills/wix-headless-fast/references/members/app/wix/members/members.ts +0 -29
  136. package/skills/wix-headless-fast/references/members/app/wix/members/types.ts +0 -21
  137. package/skills/wix-headless-fast/references/members/app-astro/layouts/SiteLayout.astro +0 -42
  138. package/skills/wix-headless-fast/references/members/app-astro/pages/account.astro +0 -10
  139. package/skills/wix-headless-fast/references/members/app-astro/pages/login.astro +0 -11
  140. package/skills/wix-headless-fast/references/members/lock/astro/package-lock.json +0 -10329
  141. package/skills/wix-headless-fast/references/members/rest/auth.ts +0 -215
  142. package/skills/wix-headless-fast/references/members/rest/members.ts +0 -26
  143. package/skills/wix-headless-fast/references/members/seed/SEED.md +0 -39
  144. package/skills/wix-headless-fast/references/members/seed/read-site.mjs +0 -15
  145. package/skills/wix-headless-fast/references/members/seed/seed-members.mjs +0 -94
  146. package/skills/wix-headless-fast/references/portfolio/INSTRUCTIONS.md +0 -315
  147. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionProjectsView.tsx +0 -110
  148. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionsView.tsx +0 -90
  149. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/GalleryMedia.tsx +0 -35
  150. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/ProjectDetailView.tsx +0 -85
  151. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollectionProjects.ts +0 -32
  152. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollections.ts +0 -21
  153. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useProjectDetail.ts +0 -31
  154. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collection-projects-store.ts +0 -82
  155. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collections-store.ts +0 -58
  156. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio-core.ts +0 -177
  157. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio.ts +0 -78
  158. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/project-detail-store.ts +0 -81
  159. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/types.ts +0 -55
  160. package/skills/wix-headless-fast/references/portfolio/app-astro/layouts/SiteLayout.astro +0 -40
  161. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio/[slug].astro +0 -30
  162. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio.astro +0 -21
  163. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/projects/[slug].astro +0 -29
  164. package/skills/wix-headless-fast/references/portfolio/lock/astro/package-lock.json +0 -10197
  165. package/skills/wix-headless-fast/references/portfolio/rest/portfolio.ts +0 -75
  166. package/skills/wix-headless-fast/references/portfolio/seed/SEED.md +0 -86
  167. package/skills/wix-headless-fast/references/portfolio/seed/read-site.mjs +0 -20
  168. package/skills/wix-headless-fast/references/portfolio/seed/seed-portfolio.mjs +0 -256
  169. package/skills/wix-headless-fast/references/pricing-plans/INSTRUCTIONS.md +0 -296
  170. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlanDetailView.tsx +0 -47
  171. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlansView.tsx +0 -101
  172. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/SubscribeButton.tsx +0 -41
  173. package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlanPurchase.ts +0 -16
  174. package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlans.ts +0 -22
  175. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plan-purchase-store.ts +0 -54
  176. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-core.ts +0 -106
  177. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-store.ts +0 -64
  178. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans.ts +0 -27
  179. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase-core.ts +0 -43
  180. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase.ts +0 -22
  181. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/types.ts +0 -30
  182. package/skills/wix-headless-fast/references/pricing-plans/app-astro/layouts/SiteLayout.astro +0 -41
  183. package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans/[slug].astro +0 -40
  184. package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans.astro +0 -21
  185. package/skills/wix-headless-fast/references/pricing-plans/lock/astro/package-lock.json +0 -11226
  186. package/skills/wix-headless-fast/references/pricing-plans/rest/plans.ts +0 -31
  187. package/skills/wix-headless-fast/references/pricing-plans/rest/purchase.ts +0 -20
  188. package/skills/wix-headless-fast/references/pricing-plans/seed/SEED.md +0 -79
  189. package/skills/wix-headless-fast/references/pricing-plans/seed/read-site.mjs +0 -21
  190. package/skills/wix-headless-fast/references/pricing-plans/seed/seed-pricing-plans.mjs +0 -279
  191. package/skills/wix-headless-fast/references/restaurants/INSTRUCTIONS.md +0 -360
  192. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/MenuView.tsx +0 -142
  193. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartButton.tsx +0 -26
  194. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartDrawer.tsx +0 -121
  195. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/ReservationView.tsx +0 -155
  196. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useMenus.ts +0 -34
  197. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useOrderCart.ts +0 -43
  198. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useReservation.ts +0 -34
  199. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-core.ts +0 -155
  200. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-store.ts +0 -89
  201. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu.ts +0 -71
  202. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/order-store.ts +0 -103
  203. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering-core.ts +0 -124
  204. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering.ts +0 -185
  205. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservation-store.ts +0 -193
  206. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations-core.ts +0 -94
  207. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations.ts +0 -74
  208. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/types.ts +0 -168
  209. package/skills/wix-headless-fast/references/restaurants/app-astro/layouts/SiteLayout.astro +0 -47
  210. package/skills/wix-headless-fast/references/restaurants/app-astro/pages/menu.astro +0 -22
  211. package/skills/wix-headless-fast/references/restaurants/app-astro/pages/reservations.astro +0 -12
  212. package/skills/wix-headless-fast/references/restaurants/lock/astro/package-lock.json +0 -12560
  213. package/skills/wix-headless-fast/references/restaurants/rest/menu.ts +0 -60
  214. package/skills/wix-headless-fast/references/restaurants/rest/ordering.ts +0 -169
  215. package/skills/wix-headless-fast/references/restaurants/rest/reservations.ts +0 -68
  216. package/skills/wix-headless-fast/references/restaurants/seed/SEED.md +0 -89
  217. package/skills/wix-headless-fast/references/restaurants/seed/read-site.mjs +0 -25
  218. package/skills/wix-headless-fast/references/restaurants/seed/seed-restaurants.mjs +0 -499
  219. package/skills/wix-headless-fast/references/shared/CONTENT.md +0 -22
  220. package/skills/wix-headless-fast/references/shared/CUSTOM_OPERATIONS.md +0 -73
  221. package/skills/wix-headless-fast/references/shared/DESIGN.md +0 -26
  222. package/skills/wix-headless-fast/references/shared/SUPPLIED-CONTENT.md +0 -23
  223. package/skills/wix-headless-fast/references/shared/app/styles/global.css +0 -52
  224. package/skills/wix-headless-fast/references/shared/app/wix/config.ts +0 -15
  225. package/skills/wix-headless-fast/references/shared/app/wix/media.ts +0 -81
  226. package/skills/wix-headless-fast/references/shared/app/wix/money.ts +0 -24
  227. package/skills/wix-headless-fast/references/shared/app/wix/sdk.ts +0 -89
  228. package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app/wix/media-upload/client.ts +0 -46
  229. package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app-astro/pages/api/wix/media-upload.ts +0 -46
  230. package/skills/wix-headless-fast/references/shared/rest/client.ts +0 -155
  231. package/skills/wix-headless-fast/references/shared/rest/config.ts +0 -3
  232. package/skills/wix-headless-fast/references/shared/rest/media.ts +0 -65
  233. package/skills/wix-headless-fast/references/shared/seed/images.mjs +0 -145
  234. package/skills/wix-headless-fast/references/shared/seed/read-site.mjs +0 -99
  235. package/skills/wix-headless-fast/references/storefront/INSTRUCTIONS.md +0 -612
  236. package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartButton.tsx +0 -26
  237. package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartDrawer.tsx +0 -155
  238. package/skills/wix-headless-fast/references/storefront/app/components/storefront/FilterPanel.tsx +0 -266
  239. package/skills/wix-headless-fast/references/storefront/app/components/storefront/OptionPicker.tsx +0 -95
  240. package/skills/wix-headless-fast/references/storefront/app/components/storefront/QuickAdd.tsx +0 -136
  241. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useCart.ts +0 -48
  242. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useProductDetail.ts +0 -39
  243. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useShop.ts +0 -34
  244. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-core.ts +0 -121
  245. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-store.ts +0 -107
  246. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart.ts +0 -138
  247. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog-core.ts +0 -314
  248. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog.ts +0 -133
  249. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/product-detail-store.ts +0 -147
  250. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/shop-store.ts +0 -289
  251. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/types.ts +0 -169
  252. package/skills/wix-headless-fast/references/storefront/app-astro/layouts/SiteLayout.astro +0 -65
  253. package/skills/wix-headless-fast/references/storefront/lock/astro/package-lock.json +0 -12247
  254. package/skills/wix-headless-fast/references/storefront/rest/cart.ts +0 -132
  255. package/skills/wix-headless-fast/references/storefront/rest/catalog.ts +0 -123
  256. package/skills/wix-headless-fast/references/storefront/seed/SEED.md +0 -130
  257. package/skills/wix-headless-fast/references/storefront/seed/read-site.mjs +0 -38
  258. package/skills/wix-headless-fast/references/storefront/seed/seed-store.mjs +0 -561
@@ -1,52 +0,0 @@
1
- @import url('https://fonts.googleapis.com/css2?family=Wix+Madefor+Text:wght@400;500;600;700;800&display=swap');
2
- @import 'tailwindcss';
3
-
4
- /* ─── THE design system ─────────────────────────────────────────────────────────────────
5
- Theme the entire store by editing THIS @theme block (same token family as the official
6
- Wix headless templates). Every shipped component styles itself from these via Tailwind
7
- utilities (bg-primary, text-muted-foreground, rounded-lg, …) — change a token, everything
8
- follows. A dark theme is just flipped values (dark background/foreground, adjusted
9
- secondary/border). Don't restyle shipped component markup; restyle the tokens.
10
-
11
- Choosing values: argue polarity from the business — light is not "cheap" (wellness/food
12
- usually read better light); never dark-by-default for "premium". Palette: one dominant +
13
- accents from ADJACENT hues (~30° arc), 2-4 colors total. Every background/foreground pair
14
- you set must hit WCAG 4.5:1 (3:1 for text ≥24px); body copy never below 16px/1.5. Derive
15
- from THIS brand — a look repeated across projects is a failure, not a shortcut. The user's
16
- explicit direction beats all of this except the contrast floor. */
17
- @theme {
18
- --color-background: hsl(0 0% 100%);
19
- --color-foreground: hsl(230 24% 14%);
20
- --color-primary: hsl(230 24% 14%);
21
- --color-primary-foreground: hsl(0 0% 100%);
22
- --color-secondary: hsl(228 24% 96%);
23
- --color-secondary-foreground: hsl(230 24% 14%);
24
- --color-muted-foreground: hsl(228 8% 46%);
25
- --color-border: hsl(220 14% 90%);
26
-
27
- --radius-lg: 12px;
28
- --radius-md: 8px;
29
- --radius-sm: 6px;
30
-
31
- --font-sans: 'Wix Madefor Text', system-ui, sans-serif;
32
- }
33
-
34
- @layer base {
35
- body {
36
- background-color: var(--color-background);
37
- color: var(--color-foreground);
38
- font-family: var(--font-sans);
39
- -webkit-font-smoothing: antialiased;
40
- font-feature-settings: 'cv02', 'cv03', 'cv04', 'cv11';
41
- }
42
- }
43
-
44
- @layer utilities {
45
- .eyebrow {
46
- font-size: 0.8125rem;
47
- font-weight: 600;
48
- letter-spacing: 0.1em;
49
- text-transform: uppercase;
50
- color: var(--color-muted-foreground);
51
- }
52
- }
@@ -1,15 +0,0 @@
1
- // Wix connection config — written by the skill's deploy step (install/deploy.mjs).
2
- //
3
- // WIX_CLIENT_ID = null → ambient auth (a Wix-managed Astro project: `@wix/astro` authenticates
4
- // every SDK call automatically; there is no client and nothing to set).
5
- // WIX_CLIENT_ID = "..." → manual visitor client (any other React setup): the public OAuth client id.
6
- // It is NOT a secret — it only mints anonymous visitor tokens — so
7
- // hardcoding and committing it is fine. On a Wix-managed non-Astro project
8
- // it equals the `appId` in wix.config.json.
9
- export const WIX_CLIENT_ID: string | null = null;
10
-
11
- // The Members vertical uses an explicit OAuthStrategy client only to drive the
12
- // custom credential form. In managed Astro it writes the resulting member
13
- // tokens into Astro's wixSession cookie, so subsequent ambient SDK calls use
14
- // that same member identity.
15
- export const WIX_MEMBERS_CLIENT_ID: string | null = null;
@@ -1,81 +0,0 @@
1
- // Wix media resolution — define once, use on EVERY image render path. Copy as-is.
2
- //
3
- // SDK media fields come back either as an already-absolute https URL, or as a
4
- // `wix:image://v1/<hash>/<file>#originWidth=…` identifier that a browser cannot load
5
- // (ERR_UNKNOWN_URL_SCHEME). The wix:image:// form must go through the SDK media module;
6
- // never hand-build a static.wixstatic.com URL (wrong format → 403).
7
- // docs: https://dev.wix.com/docs/sdk/core-modules/sdk/media.md
8
- import { media } from "@wix/sdk";
9
-
10
- type MediaLike =
11
- | string
12
- | null
13
- | undefined
14
- | { image?: string | null; url?: string | null };
15
-
16
- /** Resolve any Wix media value to a browser-loadable URL ("" when absent). */
17
- export function imgSrc(value: MediaLike, width = 600, height = 600): string {
18
- const v =
19
- typeof value === "object" && value !== null
20
- ? (value.image ?? value.url ?? "")
21
- : (value ?? "");
22
- if (!v) return "";
23
- if (typeof v === "string" && v.startsWith("wix:image://")) {
24
- return media.getScaledToFillImageUrl(v, width, height, {});
25
- }
26
- if (typeof v !== "string") return "";
27
- // An absolute Wix media URL (bare, or already carrying a /v1/fill/ segment at some other size):
28
- // re-issue it through the scaler at the requested size, so every image path lands on one shape.
29
- const m = v.match(/^https:\/\/static\.wixstatic\.com\/media\/([^/?#]+)/);
30
- if (m) return `https://static.wixstatic.com/media/${m[1]}/v1/fill/w_${width},h_${height},al_c,q_90/${m[1]}`;
31
- return v;
32
- }
33
-
34
- /**
35
- * Responsive candidates for `srcset`: the same image at several widths through Wix's scaler, so a
36
- * card never downloads a hero-sized file. Pair with `sizes`:
37
- * <img src={imgSrc(m, 640, 640)} srcSet={imgSrcSet(m)} sizes="(min-width: 1024px) 25vw, 50vw"
38
- * width={640} height={640} loading="lazy" alt={…} />
39
- * Accepts every form an image reaches you in: a raw `wix:image://` id, an ALREADY-RESOLVED Wix URL
40
- * (what the DTOs carry — `imageUrl`, `gallery[]`; its `/v1/fill/w_…,h_…` segment is rewritten per
41
- * width), or any other https URL (returned as the single candidate). `ratio` is height/width
42
- * (1 = square). "" only when there is no image at all — still set `src` as well.
43
- */
44
- export function imgSrcSet(value: MediaLike, widths: number[] = [320, 480, 640, 960], ratio = 1): string {
45
- const raw = typeof value === "object" && value !== null ? (value.image ?? value.url ?? "") : (value ?? "");
46
- if (typeof raw !== "string" || !raw) return "";
47
- if (raw.startsWith("wix:image://")) {
48
- return widths.map((w) => `${imgSrc(value, w, Math.round(w * ratio))} ${w}w`).join(", ");
49
- }
50
- // A resolved Wix URL: …/v1/fill/w_800,h_800,al_c,… — swap the size for each width.
51
- const FILL = /\/v1\/fill\/w_\d+,h_\d+/;
52
- if (/static\.wixstatic\.com\//.test(raw) && FILL.test(raw)) {
53
- return widths.map((w) => `${raw.replace(FILL, `/v1/fill/w_${w},h_${Math.round(w * ratio)}`)} ${w}w`).join(", ");
54
- }
55
- return raw; // one candidate, never an empty srcset for a real image
56
- }
57
-
58
- /**
59
- * Everything an <img> needs for one Wix image, so a tile can never ship `srcSet` without `src`:
60
- * <img {...imgAttrs(p.imageUrl, "(min-width: 1024px) 25vw, 50vw")} alt={p.name} />
61
- * `sizes` is the width the image renders at (a CSS length or media-query list); `ratio` is
62
- * height/width. Returns an empty object when there is no image — render your placeholder then.
63
- */
64
- export function imgAttrs(value: MediaLike, sizes: string, ratio = 1): { src: string; srcSet: string; sizes: string; loading: "lazy"; decoding: "async" } | Record<string, never> {
65
- const src = imgSrc(value, 640, Math.round(640 * ratio));
66
- if (!src) return {};
67
- return { src, srcSet: imgSrcSet(value, undefined, ratio), sizes, loading: "lazy", decoding: "async" };
68
- }
69
-
70
- /**
71
- * The identity of a media value BEFORE scaling — de-duplicate galleries on this, never on a
72
- * resolved URL (two scaled URLs of one photo differ in their size parameters).
73
- */
74
- export function mediaKey(value: MediaLike): string {
75
- const v = typeof value === "object" && value !== null ? (value.image ?? value.url ?? "") : (value ?? "");
76
- if (!v) return "";
77
- // The file id, whichever form the value takes — a raw id and a resolved URL of one photo share it.
78
- if (v.startsWith("wix:image://")) return v.slice("wix:image://v1/".length).split("/")[0].split("#")[0];
79
- const m = v.match(/^https:\/\/static\.wixstatic\.com\/media\/([^/?#]+)/);
80
- return m ? m[1] : v;
81
- }
@@ -1,24 +0,0 @@
1
- // Money formatting for API amounts that carry no formatted string. Copy as-is.
2
- //
3
- // Catalog prices come with a ready `formattedAmount` — use that directly. But eCom Cart V2
4
- // amounts are ConvertedMoney `{ amount, convertedAmount }` with NO formatted string, and the
5
- // currency lives on the cart, not on the money object. Never hardcode "$" or assume USD.
6
- export interface ConvertedMoneyLike {
7
- amount?: string | null;
8
- convertedAmount?: string | null;
9
- }
10
-
11
- /** Format a ConvertedMoney in the given currency, using the visitor's locale. */
12
- export function formatMoney(
13
- money: ConvertedMoneyLike | null | undefined,
14
- currencyCode: string | null | undefined,
15
- ): string {
16
- const value = money?.convertedAmount ?? money?.amount;
17
- if (value == null || value === "") return "";
18
- const currency = currencyCode || "USD";
19
- try {
20
- return new Intl.NumberFormat(undefined, { style: "currency", currency }).format(Number(value));
21
- } catch {
22
- return `${value} ${currency}`;
23
- }
24
- }
@@ -1,89 +0,0 @@
1
- // The one auth seam for every Wix SDK call in this app. Copy as-is; do not rewrite.
2
- //
3
- // Two modes, switched by WIX_CLIENT_ID in ./config:
4
- // null (ambient) — a Wix-managed Astro project: `@wix/astro` authenticates raw SDK module
5
- // calls automatically, server-side AND in client islands. `wixModule()`
6
- // returns the module untouched.
7
- // string (manual) — any other React setup (Vite SPA, non-Astro): one shared client is built
8
- // with OAuthStrategy, and `wixModule()` returns the module bound to it.
9
- // The strategy self-manages visitor tokens on every call (mints on first
10
- // use, renews on expiry) and persists them through the storage below.
11
- //
12
- // The visitor token IS the identity of the current cart / member session, so in manual mode
13
- // tokens persist to localStorage — never re-minted per load (a fresh anonymous mint is a NEW
14
- // visitor and silently empties the cart).
15
- // docs: https://dev.wix.com/docs/sdk/core-modules/sdk/oauth-strategy.md
16
- // docs: https://dev.wix.com/docs/go-headless/wix-managed-headless/authentication/about-the-astro-integration.md
17
- import { createClient, OAuthStrategy, EMPTY_TOKENS } from "@wix/sdk";
18
- import { fetchWithAuth as ambientFetch } from "@wix/sdk/context";
19
- import type { IOAuthStrategy, TokenStorage, Tokens } from "@wix/sdk";
20
- import { WIX_CLIENT_ID } from "./config";
21
-
22
- const STORAGE_KEY = `wix-session-${WIX_CLIENT_ID ?? "ambient"}`;
23
-
24
- function browserTokenStorage(): TokenStorage {
25
- return {
26
- getTokens(): Tokens {
27
- if (typeof window !== "undefined") {
28
- try {
29
- const raw = window.localStorage.getItem(STORAGE_KEY);
30
- if (raw) return JSON.parse(raw) as Tokens;
31
- } catch {
32
- /* disabled/corrupt storage — fall through to empty */
33
- }
34
- }
35
- return EMPTY_TOKENS;
36
- },
37
- setTokens(tokens: Tokens): void {
38
- if (typeof window === "undefined") return;
39
- try {
40
- window.localStorage.setItem(STORAGE_KEY, JSON.stringify(tokens));
41
- } catch {
42
- /* storage full/disabled — the session just won't survive a reload */
43
- }
44
- },
45
- };
46
- }
47
-
48
- const client = WIX_CLIENT_ID
49
- ? createClient({
50
- auth: OAuthStrategy({
51
- clientId: WIX_CLIENT_ID,
52
- tokenStorage: browserTokenStorage(),
53
- }),
54
- })
55
- : null;
56
-
57
- /**
58
- * Bind an SDK module to this app's auth. Usage (identical in both modes):
59
- * import { productsV3 } from "@wix/stores";
60
- * const products = wixModule(productsV3);
61
- * await products.queryProducts(...)
62
- */
63
- export function wixModule<T>(module: T): T {
64
- // The cast bridges the SDK's internal Descriptors constraint; the in/out type is identical.
65
- return client
66
- ? (client.use(module as unknown as Record<string, unknown>) as unknown as T)
67
- : module;
68
- }
69
-
70
- /**
71
- * An authenticated fetch of a Wix REST endpoint under the SAME auth as the SDK modules (ambient
72
- * on managed Astro, the shared client elsewhere) — for the few APIs whose generated SDK module is
73
- * too heavy to bundle (the Forms schema module alone is 15 MB: server-side it pushes a Wix
74
- * deploy past its size limit, client-side every visitor downloads it). Same visitor identity,
75
- * same token, no second mint. `path` is the wixapis.com path; returns the raw Response.
76
- */
77
- export function wixFetch(path: string, init?: RequestInit): Promise<Response> {
78
- const url = path.startsWith("http") ? path : `https://www.wixapis.com${path}`;
79
- return client ? client.fetchWithAuth(url, init) : ambientFetch(url, init);
80
- }
81
-
82
- /**
83
- * The shared data client's manual-mode auth strategy, or null under ambient auth. The
84
- * Members vertical deliberately owns a separate explicit client for its custom in-app login;
85
- * app code reads that session through the members hooks instead.
86
- */
87
- export function wixAuth(): IOAuthStrategy | null {
88
- return client ? client.auth : null;
89
- }
@@ -1,46 +0,0 @@
1
- // Safe browser half of the optional Media Upload capability.
2
- // The browser supplies bytes only. It cannot choose a destination or elevate a Wix call:
3
- // the named policy is enforced by /api/wix/media-upload on the server.
4
-
5
- export type UploadedMedia = {
6
- id: string;
7
- url?: string;
8
- uploadUrl: string;
9
- };
10
-
11
- type UploadPolicyRequest = {
12
- policyId: string;
13
- fileName: string;
14
- mimeType: string;
15
- sizeInBytes: number;
16
- };
17
-
18
- export async function uploadMedia(policyId: string, file: File | Blob, fileName?: string): Promise<UploadedMedia> {
19
- const mimeType = file.type;
20
- const request: UploadPolicyRequest = {
21
- policyId,
22
- fileName: fileName ?? (file instanceof File ? file.name : "upload"),
23
- mimeType,
24
- sizeInBytes: file.size,
25
- };
26
- const ticket = await fetch("/api/wix/media-upload", {
27
- method: "POST",
28
- headers: { "Content-Type": "application/json" },
29
- body: JSON.stringify(request),
30
- });
31
- if (!ticket.ok) throw new Error(`Upload could not be authorized (${ticket.status})`);
32
- const { uploadUrl } = (await ticket.json()) as UploadedMedia;
33
-
34
- const uploaded = await fetch(uploadUrl, {
35
- method: "PUT",
36
- headers: { "Content-Type": mimeType },
37
- body: file,
38
- });
39
- const payload = (await uploaded.json().catch(() => null)) as
40
- | { file?: { id?: string; url?: string }; id?: string; url?: string }
41
- | null;
42
- const media = payload?.file ?? payload;
43
- if (!uploaded.ok || !media?.id) throw new Error(`Upload failed (${uploaded.status})`);
44
-
45
- return { id: media.id, url: media.url, uploadUrl };
46
- }
@@ -1,46 +0,0 @@
1
- import type { APIRoute } from "astro";
2
- import { auth } from "@wix/essentials";
3
- import { files } from "@wix/media";
4
- import { mediaUploadPolicies } from "../../../wix/media-upload/policies.generated";
5
-
6
- const elevatedGenerateUploadUrl = auth.elevate(files.generateFileUploadUrl);
7
-
8
- type UploadRequest = {
9
- policyId?: unknown;
10
- fileName?: unknown;
11
- mimeType?: unknown;
12
- sizeInBytes?: unknown;
13
- };
14
-
15
- const json = (body: unknown, status = 200) =>
16
- new Response(JSON.stringify(body), { status, headers: { "Content-Type": "application/json" } });
17
-
18
- export const POST: APIRoute = async ({ request }) => {
19
- let body: UploadRequest;
20
- try {
21
- body = (await request.json()) as UploadRequest;
22
- } catch {
23
- return json({ error: "Expected JSON" }, 400);
24
- }
25
-
26
- if (
27
- typeof body.policyId !== "string" ||
28
- typeof body.fileName !== "string" ||
29
- typeof body.mimeType !== "string" ||
30
- typeof body.sizeInBytes !== "number" ||
31
- !Number.isSafeInteger(body.sizeInBytes)
32
- ) {
33
- return json({ error: "Invalid upload request" }, 400);
34
- }
35
- const policy = mediaUploadPolicies.find((candidate) => candidate.id === body.policyId);
36
- if (!policy) return json({ error: "Unknown upload policy" }, 404);
37
- if (!policy.accept.includes(body.mimeType as never)) return json({ error: "File type is not allowed" }, 415);
38
- if (body.sizeInBytes < 1 || body.sizeInBytes > policy.maxBytes) return json({ error: "File exceeds this policy's size limit" }, 413);
39
-
40
- // Do not accept a folder id, labels, privacy setting, or any other destination choice from
41
- // the browser. Add those as fixed policy fields only after the product actually needs them.
42
- const result = await elevatedGenerateUploadUrl(body.mimeType, {
43
- fileName: body.fileName.slice(0, 255),
44
- });
45
- return json({ uploadUrl: result.uploadUrl });
46
- };
@@ -1,155 +0,0 @@
1
- // The one auth seam for every Wix REST call — the twin of app/wix/sdk.ts, over fetch. No
2
- // dependencies. deploy.mjs --stack static copies it flat into js/wix/ next to the core files and
3
- // strips it to JS (comments kept); a port to another language reads it as the specification.
4
- // Imports carry the .js suffix so the stripped output runs as browser ESM unchanged.
5
- //
6
- // WIX_CLIENT_ID is the public OAuth client id (`appId` in wix.config.json). It is NOT a secret — it
7
- // only mints anonymous VISITOR tokens — so it is fine in page source. deploy.mjs writes ./config.
8
- //
9
- // THE TOKEN IS THE CART. A visitor token is the shopper's identity: their cart lives on it. Mint
10
- // once per shopper, persist it, refresh it — never mint per request (a fresh token is a new visitor
11
- // with an empty cart). Where it persists depends on where this code runs:
12
- // browser — localStorage, keyed by client id so two sites on one origin don't share a token
13
- // (what this file does).
14
- // server (a Python/PHP/Go port) — the SHOPPER'S SESSION, one token set per shopper. Never one
15
- // process-wide token for everyone: that is one shared cart for all visitors.
16
- // This is the only part of a port that isn't line-for-line.
17
- // docs: https://dev.wix.com/docs/go-headless/coding/authentication/visitors.md
18
- import { WIX_CLIENT_ID } from "./config.js";
19
-
20
- export const WIX_API_BASE = "https://www.wixapis.com";
21
- const TOKEN_URL = `${WIX_API_BASE}/oauth2/token`;
22
- const STORAGE_KEY = `wix-visitor-${WIX_CLIENT_ID}`;
23
-
24
- export interface Tokens {
25
- accessToken: string;
26
- refreshToken: string;
27
- /** Epoch ms. */
28
- expiresAt: number;
29
- /** Whose tokens: absent or "visitor" for an anonymous visitor, "member" after a login (a vertical's rest/auth.ts). */
30
- role?: "visitor" | "member";
31
- }
32
-
33
- /** Swap this for a server-session-backed store in a port; the browser default is localStorage. */
34
- export interface TokenStore {
35
- load(): Tokens | null;
36
- save(tokens: Tokens): void;
37
- }
38
-
39
- let memory: Tokens | null = null;
40
- export const browserTokenStore: TokenStore = {
41
- load() {
42
- if (memory) return memory;
43
- if (typeof localStorage === "undefined") return null;
44
- try {
45
- const raw = localStorage.getItem(STORAGE_KEY);
46
- if (raw) memory = JSON.parse(raw) as Tokens;
47
- } catch {
48
- /* disabled or corrupt storage — mint a fresh visitor */
49
- }
50
- return memory;
51
- },
52
- save(tokens) {
53
- memory = tokens;
54
- if (typeof localStorage === "undefined") return;
55
- try {
56
- localStorage.setItem(STORAGE_KEY, JSON.stringify(tokens));
57
- } catch {
58
- /* storage full or disabled — the session just won't survive a reload */
59
- }
60
- },
61
- };
62
- let store: TokenStore = browserTokenStore;
63
- /** A port calls this once with its session-backed store. */
64
- export function useTokenStore(s: TokenStore): void {
65
- store = s;
66
- }
67
-
68
- // POST /oauth2/token — grantType "anonymous" mints a visitor; "refresh_token" renews and KEEPS the
69
- // identity (a member refresh token yields member tokens); "authorization_code" + codeVerifier turns
70
- // a login's authorization code into MEMBER tokens (a vertical's rest/auth.ts). `role` records which.
71
- export async function mintTokens(body: Record<string, string>, role: Tokens["role"] = "visitor"): Promise<Tokens> {
72
- const res = await fetch(TOKEN_URL, {
73
- method: "POST",
74
- headers: { "Content-Type": "application/json" },
75
- body: JSON.stringify({ clientId: WIX_CLIENT_ID, ...body }),
76
- });
77
- if (!res.ok) throw new Error(`Wix auth failed (${res.status}).`);
78
- const data = await res.json();
79
- return { accessToken: data.access_token, refreshToken: data.refresh_token, expiresAt: Date.now() + data.expires_in * 1000, role };
80
- }
81
-
82
- /** The persisted token set as it is (possibly expired), or null before the first mint. */
83
- export function loadTokens(): Tokens | null {
84
- return store.load();
85
- }
86
-
87
- /** Adopt a token set — a member's after login. Every call from here on runs as that identity. */
88
- export function setTokens(tokens: Tokens): void {
89
- store.save(tokens);
90
- }
91
-
92
- /** Drop the current identity (logout): the next call mints a fresh anonymous visitor. */
93
- export function clearTokens(): void {
94
- store.save({ accessToken: "", refreshToken: "", expiresAt: 0 });
95
- }
96
-
97
- /** A valid access token: cached, refreshed when expired, minted on first use. */
98
- export async function accessToken(): Promise<string> {
99
- const t = store.load();
100
- if (t && t.expiresAt - 60_000 > Date.now()) return t.accessToken;
101
- let fresh: Tokens | undefined;
102
- if (t?.refreshToken) {
103
- try {
104
- fresh = await mintTokens({ grantType: "refresh_token", refreshToken: t.refreshToken }, t.role ?? "visitor");
105
- } catch {
106
- /* fall through to a new visitor */
107
- }
108
- }
109
- fresh ??= await mintTokens({ grantType: "anonymous" });
110
- store.save(fresh);
111
- return fresh.accessToken;
112
- }
113
-
114
- export class WixApiError extends Error {
115
- /** The response's `details` as Wix sent it (applicationError, validationError) — for callers that map codes. */
116
- public details?: Record<string, any>;
117
- constructor(message: string, public status: number, public code?: string, details?: Record<string, any>) {
118
- super(message);
119
- this.details = details;
120
- }
121
- }
122
-
123
- /**
124
- * Every Wix call goes through here. `path` is relative to WIX_API_BASE; `query` becomes the query
125
- * string (an array repeats the key: fields=A&fields=B). Throws WixApiError on a non-2xx, including
126
- * 404 — callers that treat 404 as "not found" catch it. The header carries the RAW access token,
127
- * no "Bearer " prefix.
128
- */
129
- export async function wixRequest<T = any>(
130
- path: string,
131
- { method = "POST", body, query }: { method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE"; body?: unknown; query?: Record<string, string | readonly string[]> } = {},
132
- ): Promise<T> {
133
- const url = new URL(path, WIX_API_BASE);
134
- for (const [k, v] of Object.entries(query ?? {})) {
135
- for (const item of Array.isArray(v) ? v : [v as string]) url.searchParams.append(k, String(item));
136
- }
137
- const res = await fetch(url, {
138
- method,
139
- headers: { Authorization: await accessToken(), "Content-Type": "application/json" },
140
- body: body === undefined ? undefined : JSON.stringify(body),
141
- });
142
- if (!res.ok) {
143
- let message = "", code: string | undefined, details: Record<string, any> | undefined;
144
- try {
145
- const j = await res.json();
146
- message = j?.message ?? "";
147
- code = j?.details?.applicationError?.code;
148
- details = j?.details;
149
- } catch {
150
- /* no JSON body */
151
- }
152
- throw new WixApiError(message || `${method} ${url.pathname} failed (${res.status}).`, res.status, code, details);
153
- }
154
- return (res.status === 204 ? null : await res.json()) as T;
155
- }
@@ -1,3 +0,0 @@
1
- // Written by install/deploy.mjs --stack static from wix.config.json (or --client-id).
2
- // The public OAuth client id — not a secret: it only mints anonymous visitor tokens.
3
- export const WIX_CLIENT_ID: string = "";
@@ -1,65 +0,0 @@
1
- // Wix media → browser-loadable URLs — the twin of app/wix/media.ts, without the SDK.
2
- //
3
- // A media value arrives as either an absolute https://static.wixstatic.com/... URL or a raw
4
- // `wix:image://v1/<file>/<name>#originWidth=W&originHeight=H` identifier a browser cannot load
5
- // (ERR_UNKNOWN_URL_SCHEME). The raw form is scaled through this ONE URL shape; any other hand-built
6
- // form 403s: https://static.wixstatic.com/media/<file>/v1/fill/w_<W>,h_<H>,al_c,q_90/<file>
7
- const STATIC = "https://static.wixstatic.com/media";
8
- const FILL = /\/v1\/fill\/w_\d+,h_\d+/;
9
-
10
- export type MediaLike = string | null | undefined | { image?: string | null; url?: string | null };
11
-
12
- function rawOf(value: unknown): string {
13
- if (!value) return "";
14
- if (typeof value === "string") return value;
15
- const o = value as { image?: string | null; url?: string | null };
16
- return o.image ?? o.url ?? "";
17
- }
18
-
19
- /** Resolve any Wix media value to a URL sized w×h ("" when absent). */
20
- export function imgSrc(value: unknown, width = 600, height = 600): string {
21
- const v = rawOf(value);
22
- if (!v) return "";
23
- if (v.startsWith("wix:image://")) {
24
- const file = v.slice("wix:image://v1/".length).split("/")[0].split("#")[0];
25
- return `${STATIC}/${file}/v1/fill/w_${width},h_${height},al_c,q_90/${file}`;
26
- }
27
- // An absolute Wix media URL (bare, or already scaled to some other size): re-issue it through the
28
- // scaler at the requested size, so every image path lands on one shape.
29
- const m = v.match(/^https:\/\/static\.wixstatic\.com\/media\/([^/?#]+)/);
30
- if (m) return `${STATIC}/${m[1]}/v1/fill/w_${width},h_${height},al_c,q_90/${m[1]}`;
31
- return v;
32
- }
33
-
34
- /** srcset candidates at several widths; `ratio` is height/width. "" only when there is no image. */
35
- export function imgSrcSet(value: unknown, widths: number[] = [320, 480, 640, 960], ratio = 1): string {
36
- const v = rawOf(value);
37
- if (!v) return "";
38
- if (v.startsWith("wix:image://")) return widths.map((w) => `${imgSrc(value, w, Math.round(w * ratio))} ${w}w`).join(", ");
39
- if (v.includes("static.wixstatic.com/") && FILL.test(v)) {
40
- return widths.map((w) => `${v.replace(FILL, `/v1/fill/w_${w},h_${Math.round(w * ratio)}`)} ${w}w`).join(", ");
41
- }
42
- return v;
43
- }
44
-
45
- /**
46
- * Everything an <img> needs for one Wix image, so a tile can never ship `srcset` without `src`.
47
- * Attribute names as HTML spells them — spread into a template or apply with setAttribute:
48
- * `<img ${attrs(imgAttrs(p.imageUrl, "(min-width: 1024px) 25vw, 50vw"))} alt="…">`
49
- * `sizes` is the width the image renders at; `ratio` is height/width. {} when there is no image.
50
- */
51
- export function imgAttrs(value: unknown, sizes: string, ratio = 1): Record<string, string> {
52
- const src = imgSrc(value, 640, Math.round(640 * ratio));
53
- if (!src) return {};
54
- return { src, srcset: imgSrcSet(value, undefined, ratio), sizes, loading: "lazy", decoding: "async" };
55
- }
56
-
57
- /** The media identity before scaling — de-duplicate galleries on this, never on a resolved URL. */
58
- export function mediaKey(value: unknown): string {
59
- const v = rawOf(value);
60
- if (!v) return "";
61
- // The file id, whichever form the value takes — a raw id and a resolved URL of one photo share it.
62
- if (v.startsWith("wix:image://")) return v.slice("wix:image://v1/".length).split("/")[0].split("#")[0];
63
- const m = v.match(/^https:\/\/static\.wixstatic\.com\/media\/([^/?#]+)/);
64
- return m ? m[1] : v;
65
- }