@wix/agent-skills 1.20.1 → 1.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/package.json +1 -1
  2. package/skills/wix-app/SKILL.md +71 -113
  3. package/skills/wix-app/references/APP_TOOLS.md +2 -1
  4. package/skills/wix-app/references/BACKEND_EVENT.md +3 -3
  5. package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +41 -152
  6. package/skills/wix-app/references/DASHBOARD_MODAL.md +4 -4
  7. package/skills/wix-app/references/DASHBOARD_PAGE.md +11 -25
  8. package/skills/wix-app/references/DATA_COLLECTION.md +16 -219
  9. package/skills/wix-app/references/SDK_MODULE_MAP.md +44 -0
  10. package/skills/wix-app/references/SITE_PLUGIN.md +36 -190
  11. package/skills/wix-app/references/app-tools/TOOLS.md +3 -1
  12. package/skills/wix-app/references/custom-element-widget/SETTINGS_PANEL.md +21 -0
  13. package/skills/wix-app/references/dashboard-page/DATA_SOURCES.md +182 -0
  14. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE.md +97 -0
  15. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_COLLECTION.md +184 -0
  16. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_ROUTER.md +203 -0
  17. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_SETTINGS.md +44 -0
  18. package/skills/wix-app/references/dashboard-page/ECOM_NAVIGATION.md +17 -0
  19. package/skills/wix-app/references/dashboard-page/QUERY_AND_PAGING.md +182 -0
  20. package/skills/wix-app/references/dashboard-page/TABLE_STATE.md +133 -0
  21. package/skills/wix-app/references/dashboard-page/UX_SUCCESS_MODEL.md +10 -5
  22. package/skills/wix-app/references/dashboard-plugin/SLOTS.md +4 -18
  23. package/skills/wix-app/references/data-collection/LIFECYCLE.md +68 -0
  24. package/skills/wix-app/references/data-collection/PERMISSIONS.md +47 -0
  25. package/skills/wix-app/references/data-collection/SCHEMA.md +181 -0
  26. package/skills/wix-app/references/data-collection/WIX_DATA.md +38 -66
  27. package/skills/wix-app/references/site-plugin/EXAMPLES.md +1 -1
  28. package/skills/wix-headless-fast/SKILL.md +144 -221
  29. package/skills/wix-headless-fast/cold-start/bootstrap.mjs +156 -0
  30. package/skills/wix-headless-fast/{entry/skill.md → cold-start/cold-start.md} +15 -15
  31. package/skills/wix-headless-fast/guides/existing-site.md +76 -0
  32. package/skills/wix-headless-fast/guides/reference-mode.md +97 -0
  33. package/skills/wix-headless-fast/install/AGENTS.md +35 -0
  34. package/skills/wix-headless-fast/install/agents-md.mjs +39 -0
  35. package/skills/wix-headless-fast/install/attach.mjs +161 -86
  36. package/skills/wix-headless-fast/install/deploy.mjs +21 -60
  37. package/skills/wix-headless-fast/install/lock.mjs +55 -0
  38. package/skills/wix-headless-fast/install/setup.mjs +259 -0
  39. package/skills/wix-headless-fast/install/templates.mjs +168 -0
  40. package/skills/wix-manage/references/ecommerce/pricing-promotions/ecom-pricing-create-coupon.md +10 -19
  41. package/skills/wix-manage/references/events/create-wix-event.md +5 -1
  42. package/skills/wix-manage/references/google-ads/google-ads-dashboard-navigation.md +27 -0
  43. package/skills/wix-manage/references/google-ads/manage-campaign-success-guide.md +83 -37
  44. package/skills/wix-headless-fast/install/fast-path.mjs +0 -181
  45. package/skills/wix-headless-fast/references/blog/INSTRUCTIONS.md +0 -301
  46. package/skills/wix-headless-fast/references/blog/app/components/blog/BlogFeedView.tsx +0 -136
  47. package/skills/wix-headless-fast/references/blog/app/components/blog/PostView.tsx +0 -112
  48. package/skills/wix-headless-fast/references/blog/app/components/blog/RichContent.tsx +0 -42
  49. package/skills/wix-headless-fast/references/blog/app/hooks/blog/useBlogFeed.ts +0 -31
  50. package/skills/wix-headless-fast/references/blog/app/hooks/blog/usePost.ts +0 -22
  51. package/skills/wix-headless-fast/references/blog/app/wix/blog/blog-feed-store.ts +0 -137
  52. package/skills/wix-headless-fast/references/blog/app/wix/blog/post-store.ts +0 -78
  53. package/skills/wix-headless-fast/references/blog/app/wix/blog/posts-core.ts +0 -117
  54. package/skills/wix-headless-fast/references/blog/app/wix/blog/posts.ts +0 -52
  55. package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy-core.ts +0 -47
  56. package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy.ts +0 -58
  57. package/skills/wix-headless-fast/references/blog/app/wix/blog/types.ts +0 -62
  58. package/skills/wix-headless-fast/references/blog/app-astro/layouts/SiteLayout.astro +0 -40
  59. package/skills/wix-headless-fast/references/blog/app-astro/pages/blog/[...slug].astro +0 -97
  60. package/skills/wix-headless-fast/references/blog/app-astro/pages/blog.astro +0 -24
  61. package/skills/wix-headless-fast/references/blog/lock/astro/package-lock.json +0 -16156
  62. package/skills/wix-headless-fast/references/blog/rest/posts.ts +0 -42
  63. package/skills/wix-headless-fast/references/blog/rest/taxonomy.ts +0 -62
  64. package/skills/wix-headless-fast/references/blog/seed/SEED.md +0 -81
  65. package/skills/wix-headless-fast/references/blog/seed/seed-blog.mjs +0 -287
  66. package/skills/wix-headless-fast/references/bookings/INSTRUCTIONS.md +0 -275
  67. package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServiceBookingView.tsx +0 -144
  68. package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServicesView.tsx +0 -119
  69. package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useBookingFlow.ts +0 -32
  70. package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useServices.ts +0 -23
  71. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-core.ts +0 -218
  72. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-flow-store.ts +0 -169
  73. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking.ts +0 -121
  74. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-core.ts +0 -92
  75. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-store.ts +0 -90
  76. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services.ts +0 -57
  77. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/types.ts +0 -72
  78. package/skills/wix-headless-fast/references/bookings/app-astro/layouts/SiteLayout.astro +0 -40
  79. package/skills/wix-headless-fast/references/bookings/app-astro/pages/services/[slug].astro +0 -76
  80. package/skills/wix-headless-fast/references/bookings/app-astro/pages/services.astro +0 -22
  81. package/skills/wix-headless-fast/references/bookings/lock/astro/package-lock.json +0 -11962
  82. package/skills/wix-headless-fast/references/bookings/rest/booking.ts +0 -113
  83. package/skills/wix-headless-fast/references/bookings/rest/services.ts +0 -55
  84. package/skills/wix-headless-fast/references/bookings/seed/SEED.md +0 -71
  85. package/skills/wix-headless-fast/references/bookings/seed/seed-bookings.mjs +0 -302
  86. package/skills/wix-headless-fast/references/cms/INSTRUCTIONS.md +0 -353
  87. package/skills/wix-headless-fast/references/cms/app/hooks/cms/useCollection.ts +0 -50
  88. package/skills/wix-headless-fast/references/cms/app/hooks/cms/useItem.ts +0 -37
  89. package/skills/wix-headless-fast/references/cms/app/wix/cms/collection-store.ts +0 -158
  90. package/skills/wix-headless-fast/references/cms/app/wix/cms/item-store.ts +0 -93
  91. package/skills/wix-headless-fast/references/cms/app/wix/cms/items-core.ts +0 -177
  92. package/skills/wix-headless-fast/references/cms/app/wix/cms/items.ts +0 -123
  93. package/skills/wix-headless-fast/references/cms/app/wix/cms/types.ts +0 -75
  94. package/skills/wix-headless-fast/references/cms/app-astro/layouts/SiteLayout.astro +0 -41
  95. package/skills/wix-headless-fast/references/cms/lock/astro/package-lock.json +0 -11262
  96. package/skills/wix-headless-fast/references/cms/rest/items.ts +0 -125
  97. package/skills/wix-headless-fast/references/cms/seed/SEED.md +0 -112
  98. package/skills/wix-headless-fast/references/cms/seed/seed-cms.mjs +0 -324
  99. package/skills/wix-headless-fast/references/events/INSTRUCTIONS.md +0 -305
  100. package/skills/wix-headless-fast/references/events/app/components/events/EventConfirmationView.tsx +0 -66
  101. package/skills/wix-headless-fast/references/events/app/components/events/EventRegistrationView.tsx +0 -178
  102. package/skills/wix-headless-fast/references/events/app/components/events/EventsView.tsx +0 -118
  103. package/skills/wix-headless-fast/references/events/app/hooks/events/useEventRegistration.ts +0 -35
  104. package/skills/wix-headless-fast/references/events/app/hooks/events/useEvents.ts +0 -24
  105. package/skills/wix-headless-fast/references/events/app/wix/events/events-core.ts +0 -130
  106. package/skills/wix-headless-fast/references/events/app/wix/events/events-store.ts +0 -97
  107. package/skills/wix-headless-fast/references/events/app/wix/events/events.ts +0 -55
  108. package/skills/wix-headless-fast/references/events/app/wix/events/registration-core.ts +0 -113
  109. package/skills/wix-headless-fast/references/events/app/wix/events/registration-store.ts +0 -156
  110. package/skills/wix-headless-fast/references/events/app/wix/events/registration.ts +0 -97
  111. package/skills/wix-headless-fast/references/events/app/wix/events/types.ts +0 -61
  112. package/skills/wix-headless-fast/references/events/app-astro/layouts/SiteLayout.astro +0 -40
  113. package/skills/wix-headless-fast/references/events/app-astro/pages/event-confirmation.astro +0 -12
  114. package/skills/wix-headless-fast/references/events/app-astro/pages/events/[slug].astro +0 -80
  115. package/skills/wix-headless-fast/references/events/app-astro/pages/events.astro +0 -21
  116. package/skills/wix-headless-fast/references/events/lock/astro/package-lock.json +0 -11884
  117. package/skills/wix-headless-fast/references/events/rest/events.ts +0 -57
  118. package/skills/wix-headless-fast/references/events/rest/registration.ts +0 -83
  119. package/skills/wix-headless-fast/references/events/seed/SEED.md +0 -95
  120. package/skills/wix-headless-fast/references/events/seed/seed-events.mjs +0 -276
  121. package/skills/wix-headless-fast/references/forms/INSTRUCTIONS.md +0 -338
  122. package/skills/wix-headless-fast/references/forms/app/hooks/forms/useWixForm.ts +0 -85
  123. package/skills/wix-headless-fast/references/forms/app/wix/forms/form-store.ts +0 -332
  124. package/skills/wix-headless-fast/references/forms/app/wix/forms/forms-core.ts +0 -238
  125. package/skills/wix-headless-fast/references/forms/app/wix/forms/forms.ts +0 -54
  126. package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions-core.ts +0 -216
  127. package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions.ts +0 -59
  128. package/skills/wix-headless-fast/references/forms/app/wix/forms/types.ts +0 -135
  129. package/skills/wix-headless-fast/references/forms/lock/astro/package-lock.json +0 -10593
  130. package/skills/wix-headless-fast/references/forms/rest/forms.ts +0 -34
  131. package/skills/wix-headless-fast/references/forms/rest/submissions.ts +0 -56
  132. package/skills/wix-headless-fast/references/forms/seed/SEED.md +0 -116
  133. package/skills/wix-headless-fast/references/forms/seed/seed-forms.mjs +0 -327
  134. package/skills/wix-headless-fast/references/members/INSTRUCTIONS.md +0 -314
  135. package/skills/wix-headless-fast/references/members/app/components/members/AccountView.tsx +0 -60
  136. package/skills/wix-headless-fast/references/members/app/components/members/LoginForm.tsx +0 -155
  137. package/skills/wix-headless-fast/references/members/app/components/members/MemberMenu.tsx +0 -78
  138. package/skills/wix-headless-fast/references/members/app/components/members/RequireAuth.tsx +0 -47
  139. package/skills/wix-headless-fast/references/members/app/hooks/members/useMember.ts +0 -66
  140. package/skills/wix-headless-fast/references/members/app/wix/members/auth-core.ts +0 -105
  141. package/skills/wix-headless-fast/references/members/app/wix/members/auth.ts +0 -59
  142. package/skills/wix-headless-fast/references/members/app/wix/members/client.ts +0 -53
  143. package/skills/wix-headless-fast/references/members/app/wix/members/member-store.ts +0 -122
  144. package/skills/wix-headless-fast/references/members/app/wix/members/members-core.ts +0 -43
  145. package/skills/wix-headless-fast/references/members/app/wix/members/members.ts +0 -29
  146. package/skills/wix-headless-fast/references/members/app/wix/members/types.ts +0 -21
  147. package/skills/wix-headless-fast/references/members/app-astro/layouts/SiteLayout.astro +0 -42
  148. package/skills/wix-headless-fast/references/members/app-astro/pages/account.astro +0 -10
  149. package/skills/wix-headless-fast/references/members/app-astro/pages/login.astro +0 -11
  150. package/skills/wix-headless-fast/references/members/lock/astro/package-lock.json +0 -10329
  151. package/skills/wix-headless-fast/references/members/rest/auth.ts +0 -215
  152. package/skills/wix-headless-fast/references/members/rest/members.ts +0 -26
  153. package/skills/wix-headless-fast/references/members/seed/SEED.md +0 -39
  154. package/skills/wix-headless-fast/references/members/seed/seed-members.mjs +0 -94
  155. package/skills/wix-headless-fast/references/portfolio/INSTRUCTIONS.md +0 -313
  156. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionProjectsView.tsx +0 -110
  157. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionsView.tsx +0 -90
  158. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/GalleryMedia.tsx +0 -35
  159. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/ProjectDetailView.tsx +0 -85
  160. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollectionProjects.ts +0 -32
  161. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollections.ts +0 -21
  162. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useProjectDetail.ts +0 -31
  163. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collection-projects-store.ts +0 -82
  164. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collections-store.ts +0 -58
  165. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio-core.ts +0 -177
  166. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio.ts +0 -78
  167. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/project-detail-store.ts +0 -81
  168. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/types.ts +0 -55
  169. package/skills/wix-headless-fast/references/portfolio/app-astro/layouts/SiteLayout.astro +0 -40
  170. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio/[slug].astro +0 -30
  171. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio.astro +0 -21
  172. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/projects/[slug].astro +0 -29
  173. package/skills/wix-headless-fast/references/portfolio/lock/astro/package-lock.json +0 -10197
  174. package/skills/wix-headless-fast/references/portfolio/rest/portfolio.ts +0 -75
  175. package/skills/wix-headless-fast/references/portfolio/seed/SEED.md +0 -86
  176. package/skills/wix-headless-fast/references/portfolio/seed/seed-portfolio.mjs +0 -258
  177. package/skills/wix-headless-fast/references/pricing-plans/INSTRUCTIONS.md +0 -294
  178. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlanDetailView.tsx +0 -47
  179. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlansView.tsx +0 -101
  180. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/SubscribeButton.tsx +0 -41
  181. package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlanPurchase.ts +0 -16
  182. package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlans.ts +0 -22
  183. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plan-purchase-store.ts +0 -54
  184. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-core.ts +0 -106
  185. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-store.ts +0 -64
  186. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans.ts +0 -27
  187. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase-core.ts +0 -43
  188. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase.ts +0 -22
  189. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/types.ts +0 -30
  190. package/skills/wix-headless-fast/references/pricing-plans/app-astro/layouts/SiteLayout.astro +0 -41
  191. package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans/[slug].astro +0 -40
  192. package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans.astro +0 -21
  193. package/skills/wix-headless-fast/references/pricing-plans/lock/astro/package-lock.json +0 -11226
  194. package/skills/wix-headless-fast/references/pricing-plans/rest/plans.ts +0 -31
  195. package/skills/wix-headless-fast/references/pricing-plans/rest/purchase.ts +0 -20
  196. package/skills/wix-headless-fast/references/pricing-plans/seed/SEED.md +0 -79
  197. package/skills/wix-headless-fast/references/pricing-plans/seed/seed-pricing-plans.mjs +0 -279
  198. package/skills/wix-headless-fast/references/restaurants/INSTRUCTIONS.md +0 -358
  199. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/MenuView.tsx +0 -142
  200. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartButton.tsx +0 -26
  201. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartDrawer.tsx +0 -121
  202. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/ReservationView.tsx +0 -155
  203. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useMenus.ts +0 -34
  204. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useOrderCart.ts +0 -43
  205. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useReservation.ts +0 -34
  206. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-core.ts +0 -155
  207. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-store.ts +0 -89
  208. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu.ts +0 -71
  209. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/order-store.ts +0 -103
  210. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering-core.ts +0 -124
  211. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering.ts +0 -185
  212. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservation-store.ts +0 -193
  213. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations-core.ts +0 -94
  214. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations.ts +0 -74
  215. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/types.ts +0 -168
  216. package/skills/wix-headless-fast/references/restaurants/app-astro/layouts/SiteLayout.astro +0 -47
  217. package/skills/wix-headless-fast/references/restaurants/app-astro/pages/menu.astro +0 -22
  218. package/skills/wix-headless-fast/references/restaurants/app-astro/pages/reservations.astro +0 -12
  219. package/skills/wix-headless-fast/references/restaurants/lock/astro/package-lock.json +0 -12560
  220. package/skills/wix-headless-fast/references/restaurants/rest/menu.ts +0 -60
  221. package/skills/wix-headless-fast/references/restaurants/rest/ordering.ts +0 -169
  222. package/skills/wix-headless-fast/references/restaurants/rest/reservations.ts +0 -68
  223. package/skills/wix-headless-fast/references/restaurants/seed/SEED.md +0 -89
  224. package/skills/wix-headless-fast/references/restaurants/seed/seed-restaurants.mjs +0 -479
  225. package/skills/wix-headless-fast/references/shared/CONTENT.md +0 -22
  226. package/skills/wix-headless-fast/references/shared/CUSTOM_OPERATIONS.md +0 -73
  227. package/skills/wix-headless-fast/references/shared/DESIGN.md +0 -26
  228. package/skills/wix-headless-fast/references/shared/SUPPLIED-CONTENT.md +0 -23
  229. package/skills/wix-headless-fast/references/shared/app/styles/global.css +0 -52
  230. package/skills/wix-headless-fast/references/shared/app/wix/config.ts +0 -15
  231. package/skills/wix-headless-fast/references/shared/app/wix/media.ts +0 -81
  232. package/skills/wix-headless-fast/references/shared/app/wix/money.ts +0 -24
  233. package/skills/wix-headless-fast/references/shared/app/wix/sdk.ts +0 -89
  234. package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app/wix/media-upload/client.ts +0 -46
  235. package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app-astro/pages/api/wix/media-upload.ts +0 -46
  236. package/skills/wix-headless-fast/references/shared/rest/client.ts +0 -155
  237. package/skills/wix-headless-fast/references/shared/rest/config.ts +0 -3
  238. package/skills/wix-headless-fast/references/shared/rest/media.ts +0 -65
  239. package/skills/wix-headless-fast/references/shared/seed/images.mjs +0 -145
  240. package/skills/wix-headless-fast/references/storefront/INSTRUCTIONS.md +0 -608
  241. package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartButton.tsx +0 -26
  242. package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartDrawer.tsx +0 -155
  243. package/skills/wix-headless-fast/references/storefront/app/components/storefront/FilterPanel.tsx +0 -266
  244. package/skills/wix-headless-fast/references/storefront/app/components/storefront/OptionPicker.tsx +0 -95
  245. package/skills/wix-headless-fast/references/storefront/app/components/storefront/QuickAdd.tsx +0 -136
  246. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useCart.ts +0 -48
  247. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useProductDetail.ts +0 -39
  248. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useShop.ts +0 -34
  249. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-core.ts +0 -121
  250. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-store.ts +0 -107
  251. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart.ts +0 -138
  252. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog-core.ts +0 -309
  253. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog.ts +0 -133
  254. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/product-detail-store.ts +0 -147
  255. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/shop-store.ts +0 -289
  256. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/types.ts +0 -167
  257. package/skills/wix-headless-fast/references/storefront/app-astro/layouts/SiteLayout.astro +0 -65
  258. package/skills/wix-headless-fast/references/storefront/lock/astro/package-lock.json +0 -12247
  259. package/skills/wix-headless-fast/references/storefront/rest/cart.ts +0 -132
  260. package/skills/wix-headless-fast/references/storefront/rest/catalog.ts +0 -123
  261. package/skills/wix-headless-fast/references/storefront/seed/SEED.md +0 -124
  262. package/skills/wix-headless-fast/references/storefront/seed/seed-store.mjs +0 -525
@@ -1,42 +0,0 @@
1
- // Post reads over REST — the twin of app/wix/blog/posts.ts. Same exports, same DTOs; the rules and
2
- // mappers come from posts-core (the SAME file the SDK transport uses, deployed flat next to this one
3
- // by deploy.mjs --stack static), so this file is only the transport: one fetch with a literal body
4
- // per function. Every call here is safe from a browser with a visitor token — only PUBLISHED posts
5
- // come back to it. Porting: keep the paths, keep the bodies, port the core once.
6
- // docs: https://dev.wix.com/docs/api-reference/business-solutions/blog/posts-stats/query-posts.md
7
- // docs: https://dev.wix.com/docs/api-reference/business-solutions/blog/posts-stats/get-post-by-slug.md
8
- import { wixRequest } from "./client.js";
9
- import { imgSrc } from "./media.js";
10
- import { BLOG_APP_ID, DETAIL_FIELDSETS, feedQuery, postMetaLine, slugQuery, toDetail, toSummary, type FetchPostsOptions, type Raw } from "./posts-core.js";
11
- import type { PostDetail, PostPage } from "./types.js";
12
-
13
- export { BLOG_APP_ID, postMetaLine, type FetchPostsOptions };
14
-
15
- const POSTS_QUERY = "/blog/v3/posts/query";
16
-
17
- /**
18
- * One page of published posts, newest first (pinned posts lead); `nextCursor` continues the same
19
- * query — send it alone, the filters ride inside it.
20
- * POST /blog/v3/posts/query { query: { filter?, sort, cursorPaging: { limit } } } — first page
21
- * POST /blog/v3/posts/query { query: { cursorPaging: { limit, cursor } } } — later pages
22
- */
23
- export async function fetchPosts(o: FetchPostsOptions = {}): Promise<PostPage> {
24
- const res = await wixRequest<Raw>(POSTS_QUERY, { body: { query: feedQuery(o) } });
25
- const paging: Raw = res?.pagingMetadata ?? {};
26
- return {
27
- posts: ((res?.posts ?? []) as Raw[]).map((p) => toSummary(p, imgSrc)),
28
- nextCursor: paging.hasNext ? (paging.cursors?.next ?? null) : null,
29
- };
30
- }
31
-
32
- /**
33
- * One post by URL slug with the full body (the RICH_CONTENT + CONTENT_TEXT fieldsets — without
34
- * them richContent and contentText are absent). Null when the slug resolves to nothing — a real
35
- * 404 for the page, never a fallback to another post.
36
- * POST /blog/v3/posts/query { fieldsets: ["RICH_CONTENT", "CONTENT_TEXT"], query: { filter: { slug: { $eq } }, cursorPaging: { limit: 1 } } }
37
- */
38
- export async function fetchPostBySlug(slug: string): Promise<PostDetail | null> {
39
- const res = await wixRequest<Raw>(POSTS_QUERY, { body: { fieldsets: DETAIL_FIELDSETS, query: slugQuery(slug) } });
40
- const raw: Raw | undefined = res?.posts?.[0];
41
- return raw ? toDetail(raw, imgSrc) : null;
42
- }
@@ -1,62 +0,0 @@
1
- // Category + tag reads over REST — the twin of app/wix/blog/taxonomy.ts. Same exports, same DTOs;
2
- // the mappers come from taxonomy-core (the SAME file the SDK transport uses, deployed flat next to
3
- // this one). Taxonomy queries page by OFFSET (`paging`), unlike posts (`cursorPaging`); a blog's
4
- // taxonomy fits in one read of 100. All four calls are visitor-safe.
5
- // docs: https://dev.wix.com/docs/api-reference/business-solutions/blog/category/query-categories.md
6
- // docs: https://dev.wix.com/docs/api-reference/business-solutions/blog/category/get-category-by-slug.md
7
- // docs: https://dev.wix.com/docs/api-reference/business-solutions/blog/tags/query-tags.md
8
- // docs: https://dev.wix.com/docs/api-reference/business-solutions/blog/tags/get-tag-by-slug.md
9
- import { wixRequest } from "./client.js";
10
- import { imgSrc } from "./media.js";
11
- import { CATEGORY_SORT, TAG_SORT, TAXONOMY_LIMIT, toCategory, toTag } from "./taxonomy-core.js";
12
- import type { Raw } from "./posts-core.js";
13
- import type { BlogCategory, BlogTag } from "./types.js";
14
-
15
- /**
16
- * Categories in menu order. Non-fatal: [] on failure (the feed renders without its filter row).
17
- * POST /blog/v3/categories/query { query: { sort: [{ fieldName: "displayPosition", order: "ASC" }], paging: { limit: 100 } } }
18
- */
19
- export async function fetchBlogCategories(): Promise<BlogCategory[]> {
20
- try {
21
- const res = await wixRequest<Raw>("/blog/v3/categories/query", { body: { query: { sort: CATEGORY_SORT, paging: { limit: TAXONOMY_LIMIT } } } });
22
- return ((res?.categories ?? []) as Raw[]).map((c) => toCategory(c, imgSrc)).filter((c) => c.id);
23
- } catch {
24
- return [];
25
- }
26
- }
27
-
28
- /**
29
- * Tags, most-published-posts first. Non-fatal: [] on failure.
30
- * POST /blog/v3/tags/query { query: { sort: [{ fieldName: "publishedPostCount", order: "DESC" }], paging: { limit: 100 } } }
31
- */
32
- export async function fetchBlogTags(): Promise<BlogTag[]> {
33
- try {
34
- const res = await wixRequest<Raw>("/blog/v3/tags/query", { body: { query: { sort: TAG_SORT, paging: { limit: TAXONOMY_LIMIT } } } });
35
- return ((res?.tags ?? []) as Raw[]).map(toTag).filter((t) => t.id);
36
- } catch {
37
- return [];
38
- }
39
- }
40
-
41
- // The two by-slug getters answer in DIFFERENT envelopes ({ category } and { tag }); a missing slug
42
- // is a 404 — mapped to null here, as the SDK transport does.
43
-
44
- /** One category by its URL slug. Null when not found. GET /blog/v3/categories/slugs/{slug} */
45
- export async function fetchCategoryBySlug(slug: string): Promise<BlogCategory | null> {
46
- try {
47
- const res = await wixRequest<Raw>(`/blog/v3/categories/slugs/${encodeURIComponent(slug)}`, { method: "GET" });
48
- return res?.category ? toCategory(res.category, imgSrc) : null;
49
- } catch {
50
- return null;
51
- }
52
- }
53
-
54
- /** One tag by its URL slug. Null when not found. GET /blog/v3/tags/slugs/{slug} */
55
- export async function fetchTagBySlug(slug: string): Promise<BlogTag | null> {
56
- try {
57
- const res = await wixRequest<Raw>(`/blog/v3/tags/slugs/${encodeURIComponent(slug)}`, { method: "GET" });
58
- return res?.tag ? toTag(res.tag) : null;
59
- } catch {
60
- return null;
61
- }
62
- }
@@ -1,81 +0,0 @@
1
- # Blog — seeding
2
-
3
- Seed by **running `seed-blog.mjs` with a plan file** — don't hand-write the REST calls.
4
- The script mints its own site token via the Wix CLI (logged-in session + `wix.config.json`
5
- required), installs the Blog app if needed, resolves a real author memberId (every post
6
- create requires one), and creates everything in the right order — categories/tags first,
7
- then **published** posts, then imported cover images (PATCH + re-publish).
8
-
9
- ```bash
10
- # from the project root (where wix.config.json lives):
11
- node <SKILL_ROOT>/references/blog/seed/seed-blog.mjs plan.json
12
- ```
13
-
14
- `plan.json` is plain data — write it from the brief. **Default to 3 posts** (the seed shows
15
- the shape; the owner writes the rest in the dashboard) and make them exercise the UI: group
16
- them into 2 categories when the brief has natural sections, tag a couple, vary the content
17
- blocks (heading + paragraphs + a quote or list per post), and give every post a cover — a
18
- feed without covers looks broken.
19
-
20
- ```json
21
- {
22
- "categories": ["Brewing", "Stories"],
23
- "posts": [
24
- { "title": "How We Roast Our Single-Origin Beans", "category": "Stories", "tags": ["coffee"],
25
- "coverImageUrl": "https://…",
26
- "content": [
27
- { "type": "heading", "text": "From farm to cup", "level": 2 },
28
- { "type": "paragraph", "text": "Every batch starts with beans sourced from a single estate." },
29
- { "type": "quote", "text": "Great coffee is grown, not made." }
30
- ] },
31
- { "title": "The Pour-Over, Step by Step", "category": "Brewing", "tags": ["guides"],
32
- "coverImageUrl": "https://…",
33
- "content": [
34
- { "type": "paragraph", "text": "A repeatable ritual in five minutes." },
35
- { "type": "ordered", "items": ["Rinse the filter", "Bloom 30 seconds", "Pour in circles"] }
36
- ] },
37
- { "title": "Why Water Matters More Than You Think", "category": "Brewing",
38
- "coverImageUrl": "https://…",
39
- "content": [
40
- { "type": "paragraph", "text": "Coffee is 98% water — its minerals decide the cup." },
41
- { "type": "bulleted", "items": ["Filtered, not distilled", "Aim for ~150 ppm hardness"] }
42
- ] }
43
- ]
44
- }
45
- ```
46
-
47
- - `content` blocks: `{type:"heading",text,level?}` · `{type:"paragraph",text}` ·
48
- `{type:"quote",text}` · `{type:"bulleted"|"ordered",items:[…]}`. For node types these don't
49
- cover (code, inline images), pass a pre-built Ricos `richContent` on the post instead.
50
- - `category`/`categories`/`tags` are display **names** — created idempotently and resolved to
51
- ids internally. Optional: skip them entirely when the brief doesn't group posts.
52
- - Cover — the default is a `coverImagePrompt` (AI-generated, ~1 Wix AI credit per image,
53
- account-billed): brand-contextual — subject, aesthetic/mood, palette, lighting — always
54
- ending "no text, no watermarks". At least one image in the set shows the real subject of the business — the actual product/space/service, not abstract decoration. For an asset the user actually supplied use
55
- `coverImagePath` (a file on this machine — uploaded to Wix Media) or `coverImageUrl` (their
56
- own hosted URL; verify it with `curl -sI` → 200) — never a stock-photo or guessed URL. Covers resolve
57
- in parallel and never block the seed; a failed cover leaves that post text-only (the script
58
- re-publishes each post it covers).
59
- - Posts are created **published** — an unpublished post never reaches visitors. The bulk
60
- create returns 200 even on partial failure: check each `posts[].success` in the result.
61
-
62
- **Seeding is additive — never delete or overwrite existing content**; ask first if a cleanup
63
- seems needed.
64
-
65
- ## Supplied content
66
-
67
- The general rules are in `references/shared/SUPPLIED-CONTENT.md`. For a blog, each post the user
68
- hands over is one entry. Its title becomes `title`; its body becomes `content` blocks, one block per
69
- paragraph, heading or list, whether the body arrived as text, HTML or Markdown; a category becomes
70
- `category` (and joins the `categories` list); tags become `tags`; their cover image becomes
71
- `coverImageUrl`. A post with no body is a question for the user. Authors and publish dates are
72
- not seeded — say so.
73
-
74
- ## Escape hatch — individual functions
75
- `setupBlog` composes exported steps — `installBlogApp`, `getAuthorMemberId`, `createPosts`,
76
- `createCategories`, `createTags`, `importImage`, `attachPostCovers`, plus `makeCtx()` —
77
- import them only for a partial re-seed.
78
-
79
- ## Reference
80
- Unexpected shape or an uncovered operation → read the live Wix API reference; the
81
- authoritative source recipe is `wix-headless/references/inline-recipes/setup-blog.md`.
@@ -1,287 +0,0 @@
1
- // Blog seed — a BUILD-TIME script, never shipped in the app. Run from the project root
2
- // (where wix.config.json lives) with a plan file:
3
- //
4
- // node <SKILL_ROOT>/references/blog/seed/seed-blog.mjs plan.json
5
- //
6
- // It mints its own site token via the Wix CLI, installs the Wix Blog app if needed, resolves
7
- // a real author memberId (every post create requires one), creates categories/tags (idempotent
8
- // by label, with a fresh-install verify-retry), bulk-creates PUBLISHED posts with Ricos
9
- // richContent, and imports+attaches cover images (PATCH + re-publish). Prints a JSON result
10
- // to stdout.
11
- //
12
- // Plan shape (see SEED.md):
13
- // { "categories"?: [name], "tags"?: [name],
14
- // "posts": [{ "title", "content": [blocks] | "richContent"?, "category"?|"categories"?,
15
- // "tags"?, "coverImageUrl"? | "coverImagePrompt"? }] }
16
- // content blocks: { type:"heading", text, level? } | { type:"paragraph", text }
17
- // | { type:"quote", text } | { type:"bulleted"|"ordered", items:[text,…] }
18
- //
19
- // Seeding is ADDITIVE — never deletes or overwrites existing content. Unexpected shapes →
20
- // read the live API reference; authoritative source recipe:
21
- // wix-headless/references/inline-recipes/setup-blog.md.
22
- import { execFileSync } from "node:child_process";
23
- import { readFileSync } from "node:fs";
24
- import { resolveItemImages } from "../../shared/seed/images.mjs";
25
-
26
- const API = "https://www.wixapis.com";
27
- const BLOG_APP_ID = "14bcded7-0066-7c35-14d7-466cb3f09103";
28
-
29
- export function makeCtx({ cwd = process.cwd() } = {}) {
30
- const config = JSON.parse(readFileSync(`${cwd}/wix.config.json`, "utf8"));
31
- const siteId = config.siteId ?? config.projectId;
32
- if (!siteId) throw new Error("wix.config.json has no siteId — is this a Wix CLI project?");
33
- const token = execFileSync("npx", ["@wix/cli@latest", "token", "--site", siteId], {
34
- encoding: "utf8",
35
- cwd,
36
- }).trim();
37
- if (!token) throw new Error("The Wix CLI returned no token — run `npx @wix/cli@latest login` first.");
38
- return { token, siteId };
39
- }
40
-
41
- async function req(ctx, path, { method = "POST", body } = {}) {
42
- const res = await fetch(API + path, {
43
- method,
44
- headers: {
45
- Authorization: `Bearer ${ctx.token}`,
46
- "wix-site-id": ctx.siteId,
47
- "Content-Type": "application/json",
48
- },
49
- body: body ? JSON.stringify(body) : undefined,
50
- });
51
- const json = await res.json().catch(() => ({}));
52
- if (!res.ok) throw new Error(`${method} ${path} -> ${res.status}: ${JSON.stringify(json).slice(0, 400)}`);
53
- return json;
54
- }
55
-
56
- const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
57
-
58
- // ---- Ricos richContent builder (setup-blog.md § "CRITICAL RICOS NESTING") --------------------
59
- // Rules baked in: TEXT is always a leaf inside a container; BLOCKQUOTE / LIST_ITEM wrap a
60
- // PARAGRAPH; BULLETED_LIST / ORDERED_LIST wrap LIST_ITEM -> PARAGRAPH -> TEXT; every container
61
- // node gets a unique id, TEXT leaves use id "". For node types not covered here (code, images)
62
- // pass a pre-built `richContent` on the post instead — it's used verbatim.
63
- const mkText = (text) => ({ type: "TEXT", id: "", nodes: [], textData: { text: text || "", decorations: [] } });
64
- const mkParagraph = (id, text) => ({ type: "PARAGRAPH", id, nodes: [mkText(text)], paragraphData: {} });
65
-
66
- function mkRichContent(blocks = [], postIdx = 0) {
67
- let n = 0;
68
- const id = () => `p${postIdx}-n${n++}`;
69
- const nodes = [];
70
- for (const b of blocks) {
71
- switch (b.type) {
72
- case "heading":
73
- nodes.push({ type: "HEADING", id: id(), nodes: [mkText(b.text)], headingData: { level: b.level ?? 2 } });
74
- break;
75
- case "quote":
76
- nodes.push({ type: "BLOCKQUOTE", id: id(), nodes: [mkParagraph(id(), b.text)], blockquoteData: { indentation: 1 } });
77
- break;
78
- case "bulleted":
79
- case "ordered": {
80
- const listType = b.type === "bulleted" ? "BULLETED_LIST" : "ORDERED_LIST";
81
- nodes.push({
82
- type: listType, id: id(),
83
- nodes: (b.items ?? []).map((item) => ({ type: "LIST_ITEM", id: id(), nodes: [mkParagraph(id(), item)] })),
84
- });
85
- break;
86
- }
87
- case "paragraph":
88
- default:
89
- nodes.push(mkParagraph(id(), b.text));
90
- }
91
- }
92
- return { nodes };
93
- }
94
-
95
- // One post's plain data -> a flat Blog V3 draft-post object. media is omitted — covers are a
96
- // separate pass (attachPostCovers), per the recipe.
97
- function buildPost(p, i, memberId) {
98
- return {
99
- title: p.title,
100
- memberId,
101
- richContent: p.richContent ?? mkRichContent(p.content, i),
102
- ...(p.categoryIds ? { categoryIds: p.categoryIds } : {}),
103
- ...(p.tagIds ? { tagIds: p.tagIds } : {}),
104
- };
105
- }
106
-
107
- // ---- operations ----------------------------------------------------------------------------
108
-
109
- // docs: https://dev.wix.com/docs/api-reference/articles/work-with-wix-apis/platform/about-apps-created-by-wix.md
110
- export async function installBlogApp(ctx) {
111
- try {
112
- await req(ctx, "/apps-installer-service/v1/app-instance/install", { body: {
113
- tenant: { tenantType: "SITE", id: ctx.siteId },
114
- appInstance: { appDefId: BLOG_APP_ID, enabled: true },
115
- } });
116
- } catch {
117
- /* already installed is fine */
118
- }
119
- }
120
-
121
- // Every post create needs a REAL author memberId — a fabricated id fails with
122
- // "memberIds ... do not exist". A provisioned site has the owner as members[0].
123
- // docs: https://dev.wix.com/docs/api-reference/crm/members-contacts/members/members/list-members.md
124
- export async function getAuthorMemberId(ctx) {
125
- const r = await req(ctx, "/members/v1/members?fieldsets=PUBLIC&paging.limit=1", { method: "GET" });
126
- const id = r.members?.[0]?.id;
127
- if (!id) throw new Error(`No site member found for author attribution: ${JSON.stringify(r).slice(0, 400)}`);
128
- return id;
129
- }
130
-
131
- /**
132
- * Create posts, PUBLISHED (publish:true — unpublished posts never reach visitors).
133
- * Endpoint auto-selected per the recipe: single-post endpoint for exactly one (nested
134
- * `{ draftPost }` envelope), bulk for >= 2 — `bulk` sits BETWEEN v3 and draft-posts, and each
135
- * bulk item is FLAT (wrapping it in `draftPost` 400s). Returns [{ id, index, success }].
136
- * docs: https://dev.wix.com/docs/api-reference/business-solutions/blog/draft-posts/create-draft-post.md
137
- * docs: https://dev.wix.com/docs/api-reference/business-solutions/blog/draft-posts/bulk-create-draft-posts.md
138
- */
139
- export async function createPosts(ctx, posts, { memberId, publish = true } = {}) {
140
- if (!memberId) throw new Error("createPosts requires opts.memberId (see getAuthorMemberId)");
141
- if (posts.length === 1) {
142
- const r = await req(ctx, "/blog/v3/draft-posts", { body: { draftPost: buildPost(posts[0], 0, memberId), publish } });
143
- return [{ id: r.draftPost?.id, index: 0, success: !!r.draftPost?.id }];
144
- }
145
- const r = await req(ctx, "/blog/v3/bulk/draft-posts/create", {
146
- body: { draftPosts: posts.map((p, i) => buildPost(p, i, memberId)), publish },
147
- });
148
- // Bulk returns 200 even on partial failure — read per-item results[].itemMetadata.success.
149
- return (r.results ?? []).map((x) => ({
150
- id: x.itemMetadata?.id, index: x.itemMetadata?.originalIndex, success: !!x.itemMetadata?.success,
151
- }));
152
- }
153
-
154
- // Existing label -> id, straight from the query (the source of truth for what persisted).
155
- // docs: https://dev.wix.com/docs/api-reference/business-solutions/blog/category/query-categories.md
156
- // docs: https://dev.wix.com/docs/api-reference/business-solutions/blog/tags/query-tags.md
157
- async function labelIdMap(ctx, kind) {
158
- const path = kind === "categories" ? "/blog/v3/categories/query" : "/v3/tags/query";
159
- const r = await req(ctx, path, { body: { query: { paging: { limit: 100 } } } });
160
- return new Map((r[kind] ?? []).map((x) => [x.label, x.id]));
161
- }
162
-
163
- // Create category/tag labels resiliently. TWO hazards this absorbs:
164
- // 1. Fresh-install provisioning window — for a few seconds after the Blog app installs,
165
- // per-item category/tag creates return 200 with an id but DON'T persist (the id is a lie).
166
- // So the create response is never trusted — re-query, treat the query as truth, re-create
167
- // what's still missing until it sticks.
168
- // 2. Idempotency — an already-present label (a partial-failure re-run) is skipped.
169
- // Category bodies are NESTED (`{ category: { label } }`); tag bodies are FLAT (`{ label }`) —
170
- // a `{ tag: { label } }` body sends an empty top-level label and 400s. Returns [{ id, name }].
171
- async function ensureLabels(ctx, kind, createPath, mkBody, names) {
172
- let map = await labelIdMap(ctx, kind);
173
- for (let attempt = 0; attempt < 8; attempt++) {
174
- const missing = names.filter((n) => !map.has(n));
175
- if (!missing.length) break;
176
- if (attempt) await sleep(1500); // backoff only between retries — happy path pays nothing
177
- for (const name of missing) {
178
- try { await req(ctx, createPath, { body: mkBody(name) }); }
179
- catch (e) { if (!String(e.message).includes("-> 409")) throw e; } // 409 = raced, already there
180
- }
181
- map = await labelIdMap(ctx, kind);
182
- }
183
- return names.map((name) => ({ id: map.get(name), name }));
184
- }
185
-
186
- /** Create categories idempotently by label (no bulk endpoint). Feed ids into post.categoryIds. */
187
- // docs: https://dev.wix.com/docs/api-reference/business-solutions/blog/category/create-category.md
188
- export async function createCategories(ctx, names) {
189
- return ensureLabels(ctx, "categories", "/blog/v3/categories", (name) => ({ category: { label: name } }), names);
190
- }
191
-
192
- /** Create tags idempotently by label. Feed ids into post.tagIds. */
193
- // docs: https://dev.wix.com/docs/api-reference/business-solutions/blog/tags/create-tag.md
194
- export async function createTags(ctx, names) {
195
- return ensureLabels(ctx, "tags", "/blog/v3/tags", (name) => ({ label: name }), names);
196
- }
197
-
198
- // Blog binds a post cover by Wix Media file ID — an external url must be imported first; a
199
- // plan `coverImagePrompt` is generated (Wix AI, 1 credit) then imported. Both live in the
200
- // shared util (parallel, resilient, never blocks the seed).
201
- export { importImage } from "../../shared/seed/images.mjs";
202
-
203
- // covers: [{ postId, fileId }] where fileId is the Wix Media file.id from importImage. Per
204
- // post: PATCH /blog/v3/draft-posts/{id} (NOT POST …/{id}/update — that 404s), setting
205
- // media.displayed:true + media.custom:true + wixMedia.image.id (the id ALONE is a silent
206
- // no-op), then RE-PUBLISH — the PATCH sets hasUnpublishedChanges, so the live post stays
207
- // cover-less until republished. Image failures never block the run.
208
- // docs: https://dev.wix.com/docs/api-reference/business-solutions/blog/draft-posts/update-draft-post.md
209
- // docs: https://dev.wix.com/docs/api-reference/business-solutions/blog/draft-posts/publish-draft-post.md
210
- export async function attachPostCovers(ctx, covers) {
211
- let attached = 0;
212
- for (const { postId, fileId } of covers) {
213
- try {
214
- await req(ctx, `/blog/v3/draft-posts/${postId}`, {
215
- method: "PATCH",
216
- body: { draftPost: { media: { displayed: true, custom: true, wixMedia: { image: { id: fileId } } } } },
217
- });
218
- await req(ctx, `/blog/v3/draft-posts/${postId}/publish`, { method: "POST" });
219
- attached++;
220
- } catch (e) {
221
- console.error(`cover attach skipped for post ${postId}: ${e.message}`);
222
- }
223
- }
224
- return attached;
225
- }
226
-
227
- /**
228
- * ONE-CALL seed: install → author memberId → categories/tags (names resolved to ids) →
229
- * published posts → covers, ids threaded in memory. The default path.
230
- */
231
- export async function setupBlog(ctx, { posts = [], categories = [], tags = [] } = {}) {
232
- await installBlogApp(ctx);
233
- await sleep(3000); // let a fresh Blog install settle so the first category/tag writes stick
234
- // (correctness is still guaranteed by ensureLabels' verify-retry).
235
- const memberId = await getAuthorMemberId(ctx);
236
-
237
- const catNames = [...new Set([...categories, ...posts.flatMap((p) => [].concat(p.category ?? [], p.categories ?? []))])];
238
- const tagNames = [...new Set([...tags, ...posts.flatMap((p) => [].concat(p.tags ?? []))])];
239
- const cats = catNames.length ? await createCategories(ctx, catNames) : [];
240
- const tgs = tagNames.length ? await createTags(ctx, tagNames) : [];
241
- const catId = new Map(cats.map((c) => [c.name, c.id]));
242
- const tagId = new Map(tgs.map((t) => [t.name, t.id]));
243
-
244
- const created = await createPosts(ctx, posts.map((p) => {
245
- const cn = [].concat(p.category ?? [], p.categories ?? []);
246
- const tn = [].concat(p.tags ?? []);
247
- return {
248
- ...p,
249
- ...(cn.length ? { categoryIds: cn.map((n) => catId.get(n)).filter(Boolean) } : {}),
250
- ...(tn.length ? { tagIds: tn.map((n) => tagId.get(n)).filter(Boolean) } : {}),
251
- };
252
- }), { memberId });
253
-
254
- // Pass 2 — covers: resolve (import by url / generate by prompt) in one parallel wave, then
255
- // attach (PATCH + re-publish per post). Failures leave the post text-only; the seed's exit
256
- // never depends on images.
257
- const files = await resolveItemImages(ctx, created.map((c, i) => (
258
- c?.id && c?.success
259
- ? { path: posts[i]?.coverImagePath, url: posts[i]?.coverImageUrl, prompt: posts[i]?.coverImagePrompt, displayName: `post-${i}.png` }
260
- : null
261
- )));
262
- const covers = created
263
- .map((c, i) => (files[i] ? { postId: c.id, fileId: files[i].id } : null))
264
- .filter(Boolean);
265
- const coversAttached = covers.length ? await attachPostCovers(ctx, covers) : 0;
266
-
267
- return { posts: created, categories: cats, tags: tgs, coversAttached };
268
- }
269
-
270
- // ---- CLI entry ----------------------------------------------------------------------------------
271
-
272
- const invokedDirectly = process.argv[1] && import.meta.url.endsWith(process.argv[1].split("/").pop());
273
- if (invokedDirectly) {
274
- const planPath = process.argv[2];
275
- if (!planPath) {
276
- console.error("usage: node seed-blog.mjs <plan.json> (run from the project root)");
277
- process.exit(1);
278
- }
279
- const plan = JSON.parse(readFileSync(planPath, "utf8"));
280
- const ctx = makeCtx();
281
- setupBlog(ctx, plan)
282
- .then((result) => console.log(JSON.stringify(result, null, 2)))
283
- .catch((e) => {
284
- console.error(e.message);
285
- process.exit(1);
286
- });
287
- }