@wix/agent-skills 1.20.1 → 1.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/wix-app/SKILL.md +71 -113
- package/skills/wix-app/references/APP_TOOLS.md +2 -1
- package/skills/wix-app/references/BACKEND_EVENT.md +3 -3
- package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +41 -152
- package/skills/wix-app/references/DASHBOARD_MODAL.md +4 -4
- package/skills/wix-app/references/DASHBOARD_PAGE.md +11 -25
- package/skills/wix-app/references/DATA_COLLECTION.md +16 -219
- package/skills/wix-app/references/SDK_MODULE_MAP.md +44 -0
- package/skills/wix-app/references/SITE_PLUGIN.md +36 -190
- package/skills/wix-app/references/app-tools/TOOLS.md +3 -1
- package/skills/wix-app/references/custom-element-widget/SETTINGS_PANEL.md +21 -0
- package/skills/wix-app/references/dashboard-page/DATA_SOURCES.md +182 -0
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE.md +97 -0
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_COLLECTION.md +184 -0
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_ROUTER.md +203 -0
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_SETTINGS.md +44 -0
- package/skills/wix-app/references/dashboard-page/ECOM_NAVIGATION.md +17 -0
- package/skills/wix-app/references/dashboard-page/QUERY_AND_PAGING.md +182 -0
- package/skills/wix-app/references/dashboard-page/TABLE_STATE.md +133 -0
- package/skills/wix-app/references/dashboard-page/UX_SUCCESS_MODEL.md +10 -5
- package/skills/wix-app/references/dashboard-plugin/SLOTS.md +4 -18
- package/skills/wix-app/references/data-collection/LIFECYCLE.md +68 -0
- package/skills/wix-app/references/data-collection/PERMISSIONS.md +47 -0
- package/skills/wix-app/references/data-collection/SCHEMA.md +181 -0
- package/skills/wix-app/references/data-collection/WIX_DATA.md +38 -66
- package/skills/wix-app/references/site-plugin/EXAMPLES.md +1 -1
- package/skills/wix-headless-fast/SKILL.md +144 -221
- package/skills/wix-headless-fast/cold-start/bootstrap.mjs +156 -0
- package/skills/wix-headless-fast/{entry/skill.md → cold-start/cold-start.md} +15 -15
- package/skills/wix-headless-fast/guides/existing-site.md +76 -0
- package/skills/wix-headless-fast/guides/reference-mode.md +97 -0
- package/skills/wix-headless-fast/install/AGENTS.md +35 -0
- package/skills/wix-headless-fast/install/agents-md.mjs +39 -0
- package/skills/wix-headless-fast/install/attach.mjs +161 -86
- package/skills/wix-headless-fast/install/deploy.mjs +21 -60
- package/skills/wix-headless-fast/install/lock.mjs +55 -0
- package/skills/wix-headless-fast/install/setup.mjs +259 -0
- package/skills/wix-headless-fast/install/templates.mjs +168 -0
- package/skills/wix-manage/references/ecommerce/pricing-promotions/ecom-pricing-create-coupon.md +10 -19
- package/skills/wix-manage/references/events/create-wix-event.md +5 -1
- package/skills/wix-manage/references/google-ads/google-ads-dashboard-navigation.md +27 -0
- package/skills/wix-manage/references/google-ads/manage-campaign-success-guide.md +83 -37
- package/skills/wix-headless-fast/install/fast-path.mjs +0 -181
- package/skills/wix-headless-fast/references/blog/INSTRUCTIONS.md +0 -301
- package/skills/wix-headless-fast/references/blog/app/components/blog/BlogFeedView.tsx +0 -136
- package/skills/wix-headless-fast/references/blog/app/components/blog/PostView.tsx +0 -112
- package/skills/wix-headless-fast/references/blog/app/components/blog/RichContent.tsx +0 -42
- package/skills/wix-headless-fast/references/blog/app/hooks/blog/useBlogFeed.ts +0 -31
- package/skills/wix-headless-fast/references/blog/app/hooks/blog/usePost.ts +0 -22
- package/skills/wix-headless-fast/references/blog/app/wix/blog/blog-feed-store.ts +0 -137
- package/skills/wix-headless-fast/references/blog/app/wix/blog/post-store.ts +0 -78
- package/skills/wix-headless-fast/references/blog/app/wix/blog/posts-core.ts +0 -117
- package/skills/wix-headless-fast/references/blog/app/wix/blog/posts.ts +0 -52
- package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy-core.ts +0 -47
- package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy.ts +0 -58
- package/skills/wix-headless-fast/references/blog/app/wix/blog/types.ts +0 -62
- package/skills/wix-headless-fast/references/blog/app-astro/layouts/SiteLayout.astro +0 -40
- package/skills/wix-headless-fast/references/blog/app-astro/pages/blog/[...slug].astro +0 -97
- package/skills/wix-headless-fast/references/blog/app-astro/pages/blog.astro +0 -24
- package/skills/wix-headless-fast/references/blog/lock/astro/package-lock.json +0 -16156
- package/skills/wix-headless-fast/references/blog/rest/posts.ts +0 -42
- package/skills/wix-headless-fast/references/blog/rest/taxonomy.ts +0 -62
- package/skills/wix-headless-fast/references/blog/seed/SEED.md +0 -81
- package/skills/wix-headless-fast/references/blog/seed/seed-blog.mjs +0 -287
- package/skills/wix-headless-fast/references/bookings/INSTRUCTIONS.md +0 -275
- package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServiceBookingView.tsx +0 -144
- package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServicesView.tsx +0 -119
- package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useBookingFlow.ts +0 -32
- package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useServices.ts +0 -23
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-core.ts +0 -218
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-flow-store.ts +0 -169
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking.ts +0 -121
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-core.ts +0 -92
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-store.ts +0 -90
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services.ts +0 -57
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/types.ts +0 -72
- package/skills/wix-headless-fast/references/bookings/app-astro/layouts/SiteLayout.astro +0 -40
- package/skills/wix-headless-fast/references/bookings/app-astro/pages/services/[slug].astro +0 -76
- package/skills/wix-headless-fast/references/bookings/app-astro/pages/services.astro +0 -22
- package/skills/wix-headless-fast/references/bookings/lock/astro/package-lock.json +0 -11962
- package/skills/wix-headless-fast/references/bookings/rest/booking.ts +0 -113
- package/skills/wix-headless-fast/references/bookings/rest/services.ts +0 -55
- package/skills/wix-headless-fast/references/bookings/seed/SEED.md +0 -71
- package/skills/wix-headless-fast/references/bookings/seed/seed-bookings.mjs +0 -302
- package/skills/wix-headless-fast/references/cms/INSTRUCTIONS.md +0 -353
- package/skills/wix-headless-fast/references/cms/app/hooks/cms/useCollection.ts +0 -50
- package/skills/wix-headless-fast/references/cms/app/hooks/cms/useItem.ts +0 -37
- package/skills/wix-headless-fast/references/cms/app/wix/cms/collection-store.ts +0 -158
- package/skills/wix-headless-fast/references/cms/app/wix/cms/item-store.ts +0 -93
- package/skills/wix-headless-fast/references/cms/app/wix/cms/items-core.ts +0 -177
- package/skills/wix-headless-fast/references/cms/app/wix/cms/items.ts +0 -123
- package/skills/wix-headless-fast/references/cms/app/wix/cms/types.ts +0 -75
- package/skills/wix-headless-fast/references/cms/app-astro/layouts/SiteLayout.astro +0 -41
- package/skills/wix-headless-fast/references/cms/lock/astro/package-lock.json +0 -11262
- package/skills/wix-headless-fast/references/cms/rest/items.ts +0 -125
- package/skills/wix-headless-fast/references/cms/seed/SEED.md +0 -112
- package/skills/wix-headless-fast/references/cms/seed/seed-cms.mjs +0 -324
- package/skills/wix-headless-fast/references/events/INSTRUCTIONS.md +0 -305
- package/skills/wix-headless-fast/references/events/app/components/events/EventConfirmationView.tsx +0 -66
- package/skills/wix-headless-fast/references/events/app/components/events/EventRegistrationView.tsx +0 -178
- package/skills/wix-headless-fast/references/events/app/components/events/EventsView.tsx +0 -118
- package/skills/wix-headless-fast/references/events/app/hooks/events/useEventRegistration.ts +0 -35
- package/skills/wix-headless-fast/references/events/app/hooks/events/useEvents.ts +0 -24
- package/skills/wix-headless-fast/references/events/app/wix/events/events-core.ts +0 -130
- package/skills/wix-headless-fast/references/events/app/wix/events/events-store.ts +0 -97
- package/skills/wix-headless-fast/references/events/app/wix/events/events.ts +0 -55
- package/skills/wix-headless-fast/references/events/app/wix/events/registration-core.ts +0 -113
- package/skills/wix-headless-fast/references/events/app/wix/events/registration-store.ts +0 -156
- package/skills/wix-headless-fast/references/events/app/wix/events/registration.ts +0 -97
- package/skills/wix-headless-fast/references/events/app/wix/events/types.ts +0 -61
- package/skills/wix-headless-fast/references/events/app-astro/layouts/SiteLayout.astro +0 -40
- package/skills/wix-headless-fast/references/events/app-astro/pages/event-confirmation.astro +0 -12
- package/skills/wix-headless-fast/references/events/app-astro/pages/events/[slug].astro +0 -80
- package/skills/wix-headless-fast/references/events/app-astro/pages/events.astro +0 -21
- package/skills/wix-headless-fast/references/events/lock/astro/package-lock.json +0 -11884
- package/skills/wix-headless-fast/references/events/rest/events.ts +0 -57
- package/skills/wix-headless-fast/references/events/rest/registration.ts +0 -83
- package/skills/wix-headless-fast/references/events/seed/SEED.md +0 -95
- package/skills/wix-headless-fast/references/events/seed/seed-events.mjs +0 -276
- package/skills/wix-headless-fast/references/forms/INSTRUCTIONS.md +0 -338
- package/skills/wix-headless-fast/references/forms/app/hooks/forms/useWixForm.ts +0 -85
- package/skills/wix-headless-fast/references/forms/app/wix/forms/form-store.ts +0 -332
- package/skills/wix-headless-fast/references/forms/app/wix/forms/forms-core.ts +0 -238
- package/skills/wix-headless-fast/references/forms/app/wix/forms/forms.ts +0 -54
- package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions-core.ts +0 -216
- package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions.ts +0 -59
- package/skills/wix-headless-fast/references/forms/app/wix/forms/types.ts +0 -135
- package/skills/wix-headless-fast/references/forms/lock/astro/package-lock.json +0 -10593
- package/skills/wix-headless-fast/references/forms/rest/forms.ts +0 -34
- package/skills/wix-headless-fast/references/forms/rest/submissions.ts +0 -56
- package/skills/wix-headless-fast/references/forms/seed/SEED.md +0 -116
- package/skills/wix-headless-fast/references/forms/seed/seed-forms.mjs +0 -327
- package/skills/wix-headless-fast/references/members/INSTRUCTIONS.md +0 -314
- package/skills/wix-headless-fast/references/members/app/components/members/AccountView.tsx +0 -60
- package/skills/wix-headless-fast/references/members/app/components/members/LoginForm.tsx +0 -155
- package/skills/wix-headless-fast/references/members/app/components/members/MemberMenu.tsx +0 -78
- package/skills/wix-headless-fast/references/members/app/components/members/RequireAuth.tsx +0 -47
- package/skills/wix-headless-fast/references/members/app/hooks/members/useMember.ts +0 -66
- package/skills/wix-headless-fast/references/members/app/wix/members/auth-core.ts +0 -105
- package/skills/wix-headless-fast/references/members/app/wix/members/auth.ts +0 -59
- package/skills/wix-headless-fast/references/members/app/wix/members/client.ts +0 -53
- package/skills/wix-headless-fast/references/members/app/wix/members/member-store.ts +0 -122
- package/skills/wix-headless-fast/references/members/app/wix/members/members-core.ts +0 -43
- package/skills/wix-headless-fast/references/members/app/wix/members/members.ts +0 -29
- package/skills/wix-headless-fast/references/members/app/wix/members/types.ts +0 -21
- package/skills/wix-headless-fast/references/members/app-astro/layouts/SiteLayout.astro +0 -42
- package/skills/wix-headless-fast/references/members/app-astro/pages/account.astro +0 -10
- package/skills/wix-headless-fast/references/members/app-astro/pages/login.astro +0 -11
- package/skills/wix-headless-fast/references/members/lock/astro/package-lock.json +0 -10329
- package/skills/wix-headless-fast/references/members/rest/auth.ts +0 -215
- package/skills/wix-headless-fast/references/members/rest/members.ts +0 -26
- package/skills/wix-headless-fast/references/members/seed/SEED.md +0 -39
- package/skills/wix-headless-fast/references/members/seed/seed-members.mjs +0 -94
- package/skills/wix-headless-fast/references/portfolio/INSTRUCTIONS.md +0 -313
- package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionProjectsView.tsx +0 -110
- package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionsView.tsx +0 -90
- package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/GalleryMedia.tsx +0 -35
- package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/ProjectDetailView.tsx +0 -85
- package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollectionProjects.ts +0 -32
- package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollections.ts +0 -21
- package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useProjectDetail.ts +0 -31
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collection-projects-store.ts +0 -82
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collections-store.ts +0 -58
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio-core.ts +0 -177
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio.ts +0 -78
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/project-detail-store.ts +0 -81
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/types.ts +0 -55
- package/skills/wix-headless-fast/references/portfolio/app-astro/layouts/SiteLayout.astro +0 -40
- package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio/[slug].astro +0 -30
- package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio.astro +0 -21
- package/skills/wix-headless-fast/references/portfolio/app-astro/pages/projects/[slug].astro +0 -29
- package/skills/wix-headless-fast/references/portfolio/lock/astro/package-lock.json +0 -10197
- package/skills/wix-headless-fast/references/portfolio/rest/portfolio.ts +0 -75
- package/skills/wix-headless-fast/references/portfolio/seed/SEED.md +0 -86
- package/skills/wix-headless-fast/references/portfolio/seed/seed-portfolio.mjs +0 -258
- package/skills/wix-headless-fast/references/pricing-plans/INSTRUCTIONS.md +0 -294
- package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlanDetailView.tsx +0 -47
- package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlansView.tsx +0 -101
- package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/SubscribeButton.tsx +0 -41
- package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlanPurchase.ts +0 -16
- package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlans.ts +0 -22
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plan-purchase-store.ts +0 -54
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-core.ts +0 -106
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-store.ts +0 -64
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans.ts +0 -27
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase-core.ts +0 -43
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase.ts +0 -22
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/types.ts +0 -30
- package/skills/wix-headless-fast/references/pricing-plans/app-astro/layouts/SiteLayout.astro +0 -41
- package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans/[slug].astro +0 -40
- package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans.astro +0 -21
- package/skills/wix-headless-fast/references/pricing-plans/lock/astro/package-lock.json +0 -11226
- package/skills/wix-headless-fast/references/pricing-plans/rest/plans.ts +0 -31
- package/skills/wix-headless-fast/references/pricing-plans/rest/purchase.ts +0 -20
- package/skills/wix-headless-fast/references/pricing-plans/seed/SEED.md +0 -79
- package/skills/wix-headless-fast/references/pricing-plans/seed/seed-pricing-plans.mjs +0 -279
- package/skills/wix-headless-fast/references/restaurants/INSTRUCTIONS.md +0 -358
- package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/MenuView.tsx +0 -142
- package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartButton.tsx +0 -26
- package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartDrawer.tsx +0 -121
- package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/ReservationView.tsx +0 -155
- package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useMenus.ts +0 -34
- package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useOrderCart.ts +0 -43
- package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useReservation.ts +0 -34
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-core.ts +0 -155
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-store.ts +0 -89
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu.ts +0 -71
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/order-store.ts +0 -103
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering-core.ts +0 -124
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering.ts +0 -185
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservation-store.ts +0 -193
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations-core.ts +0 -94
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations.ts +0 -74
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/types.ts +0 -168
- package/skills/wix-headless-fast/references/restaurants/app-astro/layouts/SiteLayout.astro +0 -47
- package/skills/wix-headless-fast/references/restaurants/app-astro/pages/menu.astro +0 -22
- package/skills/wix-headless-fast/references/restaurants/app-astro/pages/reservations.astro +0 -12
- package/skills/wix-headless-fast/references/restaurants/lock/astro/package-lock.json +0 -12560
- package/skills/wix-headless-fast/references/restaurants/rest/menu.ts +0 -60
- package/skills/wix-headless-fast/references/restaurants/rest/ordering.ts +0 -169
- package/skills/wix-headless-fast/references/restaurants/rest/reservations.ts +0 -68
- package/skills/wix-headless-fast/references/restaurants/seed/SEED.md +0 -89
- package/skills/wix-headless-fast/references/restaurants/seed/seed-restaurants.mjs +0 -479
- package/skills/wix-headless-fast/references/shared/CONTENT.md +0 -22
- package/skills/wix-headless-fast/references/shared/CUSTOM_OPERATIONS.md +0 -73
- package/skills/wix-headless-fast/references/shared/DESIGN.md +0 -26
- package/skills/wix-headless-fast/references/shared/SUPPLIED-CONTENT.md +0 -23
- package/skills/wix-headless-fast/references/shared/app/styles/global.css +0 -52
- package/skills/wix-headless-fast/references/shared/app/wix/config.ts +0 -15
- package/skills/wix-headless-fast/references/shared/app/wix/media.ts +0 -81
- package/skills/wix-headless-fast/references/shared/app/wix/money.ts +0 -24
- package/skills/wix-headless-fast/references/shared/app/wix/sdk.ts +0 -89
- package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app/wix/media-upload/client.ts +0 -46
- package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app-astro/pages/api/wix/media-upload.ts +0 -46
- package/skills/wix-headless-fast/references/shared/rest/client.ts +0 -155
- package/skills/wix-headless-fast/references/shared/rest/config.ts +0 -3
- package/skills/wix-headless-fast/references/shared/rest/media.ts +0 -65
- package/skills/wix-headless-fast/references/shared/seed/images.mjs +0 -145
- package/skills/wix-headless-fast/references/storefront/INSTRUCTIONS.md +0 -608
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartButton.tsx +0 -26
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartDrawer.tsx +0 -155
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/FilterPanel.tsx +0 -266
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/OptionPicker.tsx +0 -95
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/QuickAdd.tsx +0 -136
- package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useCart.ts +0 -48
- package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useProductDetail.ts +0 -39
- package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useShop.ts +0 -34
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-core.ts +0 -121
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-store.ts +0 -107
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart.ts +0 -138
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog-core.ts +0 -309
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog.ts +0 -133
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/product-detail-store.ts +0 -147
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/shop-store.ts +0 -289
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/types.ts +0 -167
- package/skills/wix-headless-fast/references/storefront/app-astro/layouts/SiteLayout.astro +0 -65
- package/skills/wix-headless-fast/references/storefront/lock/astro/package-lock.json +0 -12247
- package/skills/wix-headless-fast/references/storefront/rest/cart.ts +0 -132
- package/skills/wix-headless-fast/references/storefront/rest/catalog.ts +0 -123
- package/skills/wix-headless-fast/references/storefront/seed/SEED.md +0 -124
- package/skills/wix-headless-fast/references/storefront/seed/seed-store.mjs +0 -525
|
@@ -1,479 +0,0 @@
|
|
|
1
|
-
// Restaurants seed — a BUILD-TIME script, never shipped in the app. Run from the project
|
|
2
|
-
// root (where wix.config.json lives) with a plan file:
|
|
3
|
-
//
|
|
4
|
-
// node <SKILL_ROOT>/references/restaurants/seed/seed-restaurants.mjs plan.json
|
|
5
|
-
//
|
|
6
|
-
// It mints its own site token via the Wix CLI, installs the Wix Restaurants Menus app (plus
|
|
7
|
-
// Orders / Table Reservations when the plan asks), builds each menu BOTTOM-UP (bulk items →
|
|
8
|
-
// bulk sections → menu — every child exists before its parent, visible:true at every level),
|
|
9
|
-
// imports+attaches item images, and configures the add-ons. Prints a JSON result to stdout.
|
|
10
|
-
//
|
|
11
|
-
// Plan shape (see SEED.md):
|
|
12
|
-
// { "menus": [{ "name", "description"?, "sections": [{ "name", "description"?,
|
|
13
|
-
// "items": [{ "name", "description"?, "price", "imageUrl"? | "imagePrompt"? }] }] }],
|
|
14
|
-
// "ordering"?: true | { "address"? }, // menu-first add-on; address is STEP 0
|
|
15
|
-
// "reservations"?: true | { "partySize"? { "min","max" }, "address"? } }
|
|
16
|
-
//
|
|
17
|
-
// Seeding is ADDITIVE — with ONE recipe-sanctioned exception: when THIS run installs the
|
|
18
|
-
// Menus app onto a site that didn't have it, the install's own sample "Dinner Menu" is
|
|
19
|
-
// removed (it's provably not owner content). Nothing else is ever deleted. Unexpected
|
|
20
|
-
// shapes → read the live API reference; authoritative source recipes:
|
|
21
|
-
// wix-headless/references/inline-recipes/setup-restaurants.md, setup-restaurant-orders.md,
|
|
22
|
-
// setup-restaurant-reservations.md.
|
|
23
|
-
import { execFileSync } from "node:child_process";
|
|
24
|
-
import { readFileSync } from "node:fs";
|
|
25
|
-
import { resolveItemImages } from "../../shared/seed/images.mjs";
|
|
26
|
-
|
|
27
|
-
const API = "https://www.wixapis.com";
|
|
28
|
-
const MENUS_APP_ID = "b278a256-2757-4f19-9313-c05c783bec92";
|
|
29
|
-
const ORDERS_APP_ID = "9a5d83fd-8570-482e-81ab-cfa88942ee60";
|
|
30
|
-
const TABLE_RESERVATIONS_APP_ID = "f9c07de2-5341-40c6-b096-8eb39de391fb";
|
|
31
|
-
|
|
32
|
-
export function makeCtx({ cwd = process.cwd() } = {}) {
|
|
33
|
-
const config = JSON.parse(readFileSync(`${cwd}/wix.config.json`, "utf8"));
|
|
34
|
-
const siteId = config.siteId ?? config.projectId;
|
|
35
|
-
if (!siteId) throw new Error("wix.config.json has no siteId — is this a Wix CLI project?");
|
|
36
|
-
const token = execFileSync("npx", ["@wix/cli@latest", "token", "--site", siteId], {
|
|
37
|
-
encoding: "utf8",
|
|
38
|
-
cwd,
|
|
39
|
-
}).trim();
|
|
40
|
-
if (!token) throw new Error("The Wix CLI returned no token — run `npx @wix/cli@latest login` first.");
|
|
41
|
-
return { token, siteId };
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async function req(ctx, path, { method = "POST", body } = {}) {
|
|
45
|
-
const res = await fetch(API + path, {
|
|
46
|
-
method,
|
|
47
|
-
headers: {
|
|
48
|
-
Authorization: `Bearer ${ctx.token}`,
|
|
49
|
-
"wix-site-id": ctx.siteId,
|
|
50
|
-
"Content-Type": "application/json",
|
|
51
|
-
},
|
|
52
|
-
body: body ? JSON.stringify(body) : undefined,
|
|
53
|
-
});
|
|
54
|
-
const json = await res.json().catch(() => ({}));
|
|
55
|
-
if (!res.ok) throw new Error(`${method} ${path} -> ${res.status}: ${JSON.stringify(json).slice(0, 400)}`);
|
|
56
|
-
return json;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
60
|
-
|
|
61
|
-
// ---- app installs --------------------------------------------------------------------------------
|
|
62
|
-
|
|
63
|
-
// docs: https://dev.wix.com/docs/api-reference/articles/work-with-wix-apis/platform/about-apps-created-by-wix.md
|
|
64
|
-
async function installApp(ctx, appDefId) {
|
|
65
|
-
try {
|
|
66
|
-
await req(ctx, "/apps-installer-service/v1/app-instance/install", { body: {
|
|
67
|
-
tenant: { tenantType: "SITE", id: ctx.siteId },
|
|
68
|
-
appInstance: { appDefId, enabled: true },
|
|
69
|
-
} });
|
|
70
|
-
} catch {
|
|
71
|
-
/* already installed is fine */
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
export async function installMenusApp(ctx) { return installApp(ctx, MENUS_APP_ID); }
|
|
75
|
-
export async function installOrdersApp(ctx) { return installApp(ctx, ORDERS_APP_ID); }
|
|
76
|
-
export async function installTableReservationsApp(ctx) { return installApp(ctx, TABLE_RESERVATIONS_APP_ID); }
|
|
77
|
-
|
|
78
|
-
/** True when the Menus API answers — i.e. the app is already on the site. */
|
|
79
|
-
// docs: https://dev.wix.com/docs/api-reference/business-solutions/restaurants/menus/menus/list-menus.md
|
|
80
|
-
export async function menusAppPresent(ctx) {
|
|
81
|
-
try {
|
|
82
|
-
await req(ctx, "/restaurants/menus/v1/menus", { method: "GET" });
|
|
83
|
-
return true;
|
|
84
|
-
} catch {
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// ---- menu (setup-restaurants.md) -----------------------------------------------------------------
|
|
90
|
-
// Everything is Restaurants Menus V1 on /restaurants/menus/v1/... . REST flattens the
|
|
91
|
-
// protobuf wrappers: plain values ("visible": true), never {"value": …}.
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Recipe STEP 0 — a FRESH Menus-app install ships a populated sample "Dinner Menu"
|
|
95
|
-
* (~4 sections, ~21 items) that would render next to the seeded menu. Call ONLY when this
|
|
96
|
-
* run installed the app onto a site that didn't have it (menusAppPresent was false) — then
|
|
97
|
-
* everything present is provably the install's own sample. Polls briefly (the sample
|
|
98
|
-
* provisions async), then deletes children before parents. No-op when nothing appears.
|
|
99
|
-
* docs: https://dev.wix.com/docs/api-reference/business-solutions/restaurants/menus/items/items/list-items.md
|
|
100
|
-
* docs: https://dev.wix.com/docs/api-reference/business-solutions/restaurants/menus/sections/list-sections.md
|
|
101
|
-
* docs: https://dev.wix.com/docs/api-reference/business-solutions/restaurants/menus/items/items/bulk-delete-items.md
|
|
102
|
-
* docs: https://dev.wix.com/docs/api-reference/business-solutions/restaurants/menus/sections/bulk-delete-sections.md
|
|
103
|
-
* docs: https://dev.wix.com/docs/api-reference/business-solutions/restaurants/menus/menus/delete-menu.md
|
|
104
|
-
*/
|
|
105
|
-
export async function removeSampleMenu(ctx, { tries = 8, delayMs = 2000 } = {}) {
|
|
106
|
-
let menus = [];
|
|
107
|
-
for (let i = 0; i < tries; i++) {
|
|
108
|
-
const r = await req(ctx, "/restaurants/menus/v1/menus", { method: "GET" });
|
|
109
|
-
menus = r.menus ?? [];
|
|
110
|
-
if (menus.length) break;
|
|
111
|
-
if (i < tries - 1) await sleep(delayMs);
|
|
112
|
-
}
|
|
113
|
-
if (!menus.length) return { removed: false };
|
|
114
|
-
|
|
115
|
-
const itemsRes = await req(ctx, "/restaurants/menus/v1/items", { method: "GET" });
|
|
116
|
-
const sectionsRes = await req(ctx, "/restaurants/menus/v1/sections", { method: "GET" });
|
|
117
|
-
const itemIds = (itemsRes.items ?? []).map((it) => it.id).filter(Boolean);
|
|
118
|
-
const sectionIds = (sectionsRes.sections ?? []).map((s) => s.id).filter(Boolean);
|
|
119
|
-
if (itemIds.length) {
|
|
120
|
-
await req(ctx, "/restaurants/menus/v1/bulk/items/delete", { method: "DELETE", body: { ids: itemIds } });
|
|
121
|
-
}
|
|
122
|
-
if (sectionIds.length) {
|
|
123
|
-
await req(ctx, "/restaurants/menus/v1/bulk/sections/delete", { method: "DELETE", body: { ids: sectionIds } });
|
|
124
|
-
}
|
|
125
|
-
for (const m of menus) {
|
|
126
|
-
await req(ctx, `/restaurants/menus/v1/menus/${m.id}`, { method: "DELETE" }); // no bulk delete for menus
|
|
127
|
-
}
|
|
128
|
-
return { removed: true, menus: menus.map((m) => m.name) };
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Build ONE menu BOTTOM-UP (items → sections → menu) in three bulk phases.
|
|
133
|
-
* price -> priceInfo.price as a decimal STRING; currency is the site's (send none).
|
|
134
|
-
* visible:true is baked in at every level — required to render on the live site.
|
|
135
|
-
* Returns { menuId, name, sectionIds, itemIds, items: [{ id, revision, price }] } — the
|
|
136
|
-
* per-item revision/price feed the image pass (Update Item is a full replace).
|
|
137
|
-
* docs: https://dev.wix.com/docs/api-reference/business-solutions/restaurants/menus/items/items/bulk-create-items.md
|
|
138
|
-
* docs: https://dev.wix.com/docs/api-reference/business-solutions/restaurants/menus/sections/bulk-create-sections.md
|
|
139
|
-
* docs: https://dev.wix.com/docs/api-reference/business-solutions/restaurants/menus/menus/create-menu.md
|
|
140
|
-
*/
|
|
141
|
-
export async function createMenu(ctx, menu) {
|
|
142
|
-
// STEP 1 — bulk-create every item across all sections in ONE request.
|
|
143
|
-
const flat = [];
|
|
144
|
-
menu.sections.forEach((sec, si) => (sec.items || []).forEach((it) => flat.push({ ...it, _section: si })));
|
|
145
|
-
const itemRes = await req(ctx, "/restaurants/menus/v1/bulk/items/create", {
|
|
146
|
-
body: {
|
|
147
|
-
items: flat.map((it) => ({
|
|
148
|
-
name: it.name,
|
|
149
|
-
...(it.description ? { description: it.description } : {}),
|
|
150
|
-
priceInfo: { price: String(it.price) },
|
|
151
|
-
visible: true,
|
|
152
|
-
})),
|
|
153
|
-
returnEntity: true,
|
|
154
|
-
},
|
|
155
|
-
});
|
|
156
|
-
// created items are under results[].item (results[].itemMetadata.success is the per-item flag)
|
|
157
|
-
const createdItems = (itemRes.results ?? []).map((r) => r.item);
|
|
158
|
-
const itemIdsBySection = menu.sections.map(() => []);
|
|
159
|
-
flat.forEach((it, i) => {
|
|
160
|
-
const id = createdItems[i]?.id;
|
|
161
|
-
if (id) itemIdsBySection[it._section].push(id);
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
// STEP 2 — bulk-create sections, each carrying the itemIds of its items in display order.
|
|
165
|
-
const secRes = await req(ctx, "/restaurants/menus/v1/bulk/sections/create", {
|
|
166
|
-
body: {
|
|
167
|
-
sections: menu.sections.map((sec, si) => ({
|
|
168
|
-
name: sec.name,
|
|
169
|
-
...(sec.description ? { description: sec.description } : {}),
|
|
170
|
-
visible: true,
|
|
171
|
-
itemIds: itemIdsBySection[si],
|
|
172
|
-
})),
|
|
173
|
-
returnEntity: true,
|
|
174
|
-
},
|
|
175
|
-
});
|
|
176
|
-
const sectionIds = (secRes.results ?? []).map((r) => r.item?.id);
|
|
177
|
-
|
|
178
|
-
// STEP 3 — create the menu (single create wraps in `menu`), carrying its sectionIds.
|
|
179
|
-
// businessLocationId omitted -> binds to the site's default (main) location.
|
|
180
|
-
const menuRes = await req(ctx, "/restaurants/menus/v1/menus", {
|
|
181
|
-
body: {
|
|
182
|
-
menu: {
|
|
183
|
-
name: menu.name,
|
|
184
|
-
...(menu.description ? { description: menu.description } : {}),
|
|
185
|
-
visible: true,
|
|
186
|
-
sectionIds,
|
|
187
|
-
},
|
|
188
|
-
},
|
|
189
|
-
});
|
|
190
|
-
return {
|
|
191
|
-
menuId: menuRes.menu?.id,
|
|
192
|
-
name: menu.name,
|
|
193
|
-
sectionIds,
|
|
194
|
-
itemIds: createdItems.map((it) => it?.id),
|
|
195
|
-
items: createdItems.map((it, i) => ({ id: it?.id, revision: it?.revision, price: flat[i]?.price })),
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// Restaurants binds an item image by Wix Media file ID — an external url must be imported
|
|
200
|
-
// first; a plan `imagePrompt` is generated (Wix AI, 1 credit) then imported. Both live in the
|
|
201
|
-
// shared util (parallel, resilient, never blocks the seed).
|
|
202
|
-
export { importImage } from "../../shared/seed/images.mjs";
|
|
203
|
-
|
|
204
|
-
// Image pass. Update Item is a FULL-ENTITY REPLACE with NO field mask — each entry MUST echo
|
|
205
|
-
// the item's current `revision` AND `priceInfo`, or it fails 428 MISSING_ITEM_PRICING and the
|
|
206
|
-
// image does NOT apply. `image` is an OBJECT { id, url, height, width } (never a bare string);
|
|
207
|
-
// the binding field is the Wix Media file `id`.
|
|
208
|
-
// items: [{ id, revision, price, image: { id, url, height, width } }]
|
|
209
|
-
// docs: https://dev.wix.com/docs/api-reference/business-solutions/restaurants/menus/items/items/bulk-update-item.md
|
|
210
|
-
export async function attachItemImages(ctx, items) {
|
|
211
|
-
return req(ctx, "/restaurants/menus/v1/bulk/items/update", {
|
|
212
|
-
body: {
|
|
213
|
-
items: items.map((it) => ({
|
|
214
|
-
item: {
|
|
215
|
-
id: it.id,
|
|
216
|
-
revision: it.revision,
|
|
217
|
-
priceInfo: { price: String(it.price) },
|
|
218
|
-
image: it.image,
|
|
219
|
-
},
|
|
220
|
-
})),
|
|
221
|
-
},
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// ---- business location (shared STEP 0 for ordering + reservations) ------------------------------
|
|
226
|
-
// Update Location is a FULL OVERRIDE — send the WHOLE `location` object (omitted fields are
|
|
227
|
-
// wiped), echo `default:true` (omitting it 400s CHANGE_DEFAULT_FORBIDDEN) and the current
|
|
228
|
-
// `revision`. address.country is a 2-letter ISO code. Without a real address, ordering is
|
|
229
|
-
// "testing only" and checkout breaks — a placeholder must be flagged to the owner.
|
|
230
|
-
// location: { name, timeZone, email?, phone?, address: { country, subdivision, city,
|
|
231
|
-
// postalCode, streetAddress: { number, name }, formattedAddress } }
|
|
232
|
-
// docs: https://dev.wix.com/docs/api-reference/business-management/locations/list-locations.md
|
|
233
|
-
// docs: https://dev.wix.com/docs/api-reference/business-management/locations/create-location.md
|
|
234
|
-
// docs: https://dev.wix.com/docs/api-reference/business-management/locations/update-location.md
|
|
235
|
-
export async function setBusinessLocation(ctx, location) {
|
|
236
|
-
const list = await req(ctx, "/locations/v1/locations", { method: "GET" });
|
|
237
|
-
const def = (list.locations ?? []).find((l) => l.default);
|
|
238
|
-
if (!def) {
|
|
239
|
-
// No default location at all (a bare site can have none) -> CREATE one; operations
|
|
240
|
-
// auto-bind on first-location-add.
|
|
241
|
-
const r = await req(ctx, "/locations/v1/locations", { body: { location: { ...location, default: true } } });
|
|
242
|
-
return r.location;
|
|
243
|
-
}
|
|
244
|
-
const r = await req(ctx, `/locations/v1/locations/${def.id}`, {
|
|
245
|
-
method: "PUT",
|
|
246
|
-
body: { location: { ...location, id: def.id, revision: def.revision, default: true } },
|
|
247
|
-
});
|
|
248
|
-
return r.location;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// ---- online ordering (setup-restaurant-orders.md) ------------------------------------------------
|
|
252
|
-
// The Orders-app install AUTO-provisions a working setup (an ENABLED operation with Pickup +
|
|
253
|
-
// Delivery attached, every menu ordering-enabled) — these helpers VERIFY it; they never POST
|
|
254
|
-
// an operation. Each micro-service is on its OWN host prefix — do not normalize.
|
|
255
|
-
|
|
256
|
-
// docs: https://dev.wix.com/docs/api-reference/business-solutions/restaurants/online-orders/operations/list-operations.md
|
|
257
|
-
export async function listOperations(ctx) {
|
|
258
|
-
const r = await req(ctx, "/restaurants-operations/v1/operations", { method: "GET" });
|
|
259
|
-
return r.operations ?? [];
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// A fresh install provisions the operation ASYNC — poll until it lands.
|
|
263
|
-
export async function listOperationsWithRetry(ctx, { tries = 15, delayMs = 2000 } = {}) {
|
|
264
|
-
for (let i = 0; i < tries; i++) {
|
|
265
|
-
const ops = await listOperations(ctx).catch(() => []);
|
|
266
|
-
if (ops.length) return ops;
|
|
267
|
-
if (i < tries - 1) await sleep(delayMs);
|
|
268
|
-
}
|
|
269
|
-
return [];
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// Normally already ENABLED — only PATCH when DISABLED/PAUSED_UNTIL. revision mandatory + current.
|
|
273
|
-
// docs: https://dev.wix.com/docs/api-reference/business-solutions/restaurants/online-orders/operations/update-operation.md
|
|
274
|
-
export async function enableOperation(ctx, operationId, revision) {
|
|
275
|
-
return req(ctx, `/restaurants-operations/v1/operations/${operationId}`, {
|
|
276
|
-
method: "PATCH",
|
|
277
|
-
body: { operation: { revision, onlineOrderingStatus: "ENABLED" } },
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// docs: https://dev.wix.com/docs/api-reference/business-solutions/restaurants/online-orders/menu-ordering-settings/query-menu-ordering-settings.md
|
|
282
|
-
export async function queryMenuOrderingSettings(ctx) {
|
|
283
|
-
const r = await req(ctx, "/menu-ordering-settings/v1/menu-ordering-settings/query", { body: { query: {} } });
|
|
284
|
-
return r.menuOrderingSettings ?? [];
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// Only when an entry shows onlineOrderingEnabled:false / operationId:"none".
|
|
288
|
-
// docs: https://dev.wix.com/docs/api-reference/business-solutions/restaurants/online-orders/menu-ordering-settings/update-menu-ordering-settings.md
|
|
289
|
-
export async function updateMenuOrderingSettings(ctx, settingsId, patch) {
|
|
290
|
-
return req(ctx, `/menu-ordering-settings/v1/menu-ordering-settings/${settingsId}`, {
|
|
291
|
-
method: "PATCH",
|
|
292
|
-
body: { menuOrderingSettings: patch },
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
// ---- table reservations (setup-restaurant-reservations.md) ---------------------------------------
|
|
297
|
-
// The install AUTO-provisions one default reservation location with a complete config; the
|
|
298
|
-
// one thing OFF is onlineReservationsEnabled (premium-gated). A reservation location cannot
|
|
299
|
-
// be created via this API — discover, configure, enable. Post-Jan-2026 field names:
|
|
300
|
-
// partySize (not partiesSize), approval (not manualApproval).
|
|
301
|
-
|
|
302
|
-
// docs: https://dev.wix.com/docs/api-reference/business-solutions/restaurants/reservations/reservation-locations/list-reservation-locations.md
|
|
303
|
-
export async function listReservationLocations(ctx) {
|
|
304
|
-
const r = await req(ctx, "/table-reservations/reservation-locations/v1/reservation-locations", { method: "GET" });
|
|
305
|
-
return r.reservationLocations ?? [];
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
export async function listReservationLocationsWithRetry(ctx, { tries = 15, delayMs = 2000 } = {}) {
|
|
309
|
-
for (let i = 0; i < tries; i++) {
|
|
310
|
-
const locs = await listReservationLocations(ctx).catch(() => []);
|
|
311
|
-
if (locs.length) return locs;
|
|
312
|
-
if (i < tries - 1) await sleep(delayMs);
|
|
313
|
-
}
|
|
314
|
-
return [];
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// Partial PATCH; revision mandatory; works on a non-premium site. The `location` object
|
|
318
|
-
// (address/name) is IMMUTABLE here — only touch `configuration`.
|
|
319
|
-
// docs: https://dev.wix.com/docs/api-reference/business-solutions/restaurants/reservations/reservation-locations/update-reservation-location.md
|
|
320
|
-
export async function updateReservationLocation(ctx, reservationLocationId, revision, configuration) {
|
|
321
|
-
return req(ctx, `/table-reservations/reservation-locations/v1/reservation-locations/${reservationLocationId}`, {
|
|
322
|
-
method: "PATCH",
|
|
323
|
-
body: { reservationLocation: { id: reservationLocationId, revision, configuration } },
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
// PREMIUM-ONLY: on a non-premium site this THROWS `428 PREMIUM_ONLY` — expected and
|
|
328
|
-
// non-fatal; the caller records it and continues (never retry-spiral, never fail the seed).
|
|
329
|
-
// docs: https://dev.wix.com/docs/api-reference/business-solutions/restaurants/reservations/reservation-locations/update-reservation-location.md
|
|
330
|
-
export async function enableOnlineReservations(ctx, reservationLocationId, revision) {
|
|
331
|
-
return req(ctx, `/table-reservations/reservation-locations/v1/reservation-locations/${reservationLocationId}`, {
|
|
332
|
-
method: "PATCH",
|
|
333
|
-
body: {
|
|
334
|
-
reservationLocation: {
|
|
335
|
-
id: reservationLocationId,
|
|
336
|
-
revision,
|
|
337
|
-
configuration: { onlineReservations: { onlineReservationsEnabled: true } },
|
|
338
|
-
},
|
|
339
|
-
},
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
/**
|
|
344
|
-
* ONE-CALL seed: Menus install (+ sample cleanup when fresh) → menus bottom-up → images →
|
|
345
|
-
* ordering add-on → reservations add-on, ids threaded in memory. The default path.
|
|
346
|
-
*/
|
|
347
|
-
export async function setupRestaurants(ctx, plan) {
|
|
348
|
-
const menusPlan = plan.menus ?? [];
|
|
349
|
-
const wasPresent = await menusAppPresent(ctx);
|
|
350
|
-
await installMenusApp(ctx);
|
|
351
|
-
let sampleMenuRemoved = false;
|
|
352
|
-
if (!wasPresent) {
|
|
353
|
-
const r = await removeSampleMenu(ctx).catch(() => ({ removed: false }));
|
|
354
|
-
sampleMenuRemoved = r.removed === true;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
const createdMenus = [];
|
|
358
|
-
for (const m of menusPlan) createdMenus.push(await createMenu(ctx, m));
|
|
359
|
-
|
|
360
|
-
// image pass — resolve each item's image (import by url / generate by prompt) in ONE
|
|
361
|
-
// parallel wave (restaurants binds by file id), then bulk full-replace with revision +
|
|
362
|
-
// priceInfo echoed. Never block on image failure.
|
|
363
|
-
let imagesAttached = 0;
|
|
364
|
-
const imageItems = [];
|
|
365
|
-
menusPlan.forEach((m, mi) => {
|
|
366
|
-
const flat = m.sections.flatMap((s) => s.items || []);
|
|
367
|
-
flat.forEach((it, i) => {
|
|
368
|
-
const created = createdMenus[mi]?.items?.[i];
|
|
369
|
-
if ((it.imageUrl || it.imagePrompt) && created?.id) {
|
|
370
|
-
imageItems.push({ ...created, imageUrl: it.imageUrl, imagePrompt: it.imagePrompt, name: it.name });
|
|
371
|
-
}
|
|
372
|
-
});
|
|
373
|
-
});
|
|
374
|
-
const files = await resolveItemImages(ctx, imageItems.map((it) => ({
|
|
375
|
-
url: it.imageUrl,
|
|
376
|
-
path: it.imagePath,
|
|
377
|
-
prompt: it.imagePrompt,
|
|
378
|
-
displayName: `${it.name || "item"}.png`,
|
|
379
|
-
})));
|
|
380
|
-
const toAttach = imageItems
|
|
381
|
-
.map((it, i) => (files[i]
|
|
382
|
-
? { id: it.id, revision: it.revision ?? "1", price: it.price,
|
|
383
|
-
image: { id: files[i].id, url: files[i].url, width: 1024, height: 1024 } }
|
|
384
|
-
: null))
|
|
385
|
-
.filter(Boolean);
|
|
386
|
-
if (toAttach.length) {
|
|
387
|
-
try {
|
|
388
|
-
await attachItemImages(ctx, toAttach);
|
|
389
|
-
imagesAttached = toAttach.length;
|
|
390
|
-
} catch {
|
|
391
|
-
/* the items stay text-only */
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
// shared STEP 0 address — set once across both add-ons.
|
|
396
|
-
let locationSet = false;
|
|
397
|
-
const ensureLocation = async (address) => {
|
|
398
|
-
if (address && !locationSet) {
|
|
399
|
-
await setBusinessLocation(ctx, address);
|
|
400
|
-
locationSet = true;
|
|
401
|
-
}
|
|
402
|
-
};
|
|
403
|
-
|
|
404
|
-
const ordering = { enabled: false, addressSet: false };
|
|
405
|
-
if (plan.ordering) {
|
|
406
|
-
const cfg = typeof plan.ordering === "object" ? plan.ordering : {};
|
|
407
|
-
await installOrdersApp(ctx); // auto-provisions operation + methods + per-menu settings
|
|
408
|
-
await ensureLocation(cfg.address);
|
|
409
|
-
ordering.addressSet = locationSet;
|
|
410
|
-
const ops = await listOperationsWithRetry(ctx);
|
|
411
|
-
const op = ops.find((o) => o.default) ?? ops[0];
|
|
412
|
-
if (!op) throw new Error("No ordering operation appeared — the Orders app install may not have completed; re-run the seed.");
|
|
413
|
-
if (op.onlineOrderingStatus !== "ENABLED") await enableOperation(ctx, op.id, op.revision);
|
|
414
|
-
// confirm each menu is orderable (auto-created + auto-enabled per menu; PATCH only when off)
|
|
415
|
-
const settings = await queryMenuOrderingSettings(ctx);
|
|
416
|
-
for (const s of settings) {
|
|
417
|
-
if (s.onlineOrderingEnabled === false || s.operationId === "none") {
|
|
418
|
-
await updateMenuOrderingSettings(ctx, s.id, {
|
|
419
|
-
revision: s.revision,
|
|
420
|
-
operationId: op.id,
|
|
421
|
-
onlineOrderingEnabled: true,
|
|
422
|
-
availability: { type: "ALWAYS_AVAILABLE", timeZone: cfg.address?.timeZone ?? "America/New_York" },
|
|
423
|
-
}).catch(() => {});
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
ordering.enabled = true;
|
|
427
|
-
ordering.operationId = op.id;
|
|
428
|
-
if (!ordering.addressSet) ordering.note = "No address in the plan — ordering is 'testing only' until the owner sets the real business address.";
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
const reservations = { enabled: false };
|
|
432
|
-
if (plan.reservations) {
|
|
433
|
-
const cfg = typeof plan.reservations === "object" ? plan.reservations : {};
|
|
434
|
-
await installTableReservationsApp(ctx); // auto-provisions the default reservation location
|
|
435
|
-
await ensureLocation(cfg.address);
|
|
436
|
-
let [loc] = await listReservationLocationsWithRetry(ctx);
|
|
437
|
-
if (!loc) throw new Error("No reservation location appeared — the Table Reservations install may not have completed; re-run the seed.");
|
|
438
|
-
const configuration = cfg.configuration ?? (cfg.partySize ? { onlineReservations: { partySize: cfg.partySize } } : null);
|
|
439
|
-
if (configuration) {
|
|
440
|
-
await updateReservationLocation(ctx, loc.id, loc.revision, configuration);
|
|
441
|
-
[loc] = await listReservationLocations(ctx); // re-read for the bumped revision
|
|
442
|
-
}
|
|
443
|
-
reservations.reservationLocationId = loc.id;
|
|
444
|
-
try {
|
|
445
|
-
await enableOnlineReservations(ctx, loc.id, loc.revision);
|
|
446
|
-
reservations.enabled = true;
|
|
447
|
-
} catch {
|
|
448
|
-
// 428 PREMIUM_ONLY on a free site — expected; record, don't fail.
|
|
449
|
-
reservations.premiumRequired = true;
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
return {
|
|
454
|
-
menus: createdMenus.map(({ items, ...m }) => m),
|
|
455
|
-
imagesAttached,
|
|
456
|
-
sampleMenuRemoved,
|
|
457
|
-
ordering,
|
|
458
|
-
reservations,
|
|
459
|
-
};
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
// ---- CLI entry ----------------------------------------------------------------------------------
|
|
463
|
-
|
|
464
|
-
const invokedDirectly = process.argv[1] && import.meta.url.endsWith(process.argv[1].split("/").pop());
|
|
465
|
-
if (invokedDirectly) {
|
|
466
|
-
const planPath = process.argv[2];
|
|
467
|
-
if (!planPath) {
|
|
468
|
-
console.error("usage: node seed-restaurants.mjs <plan.json> (run from the project root)");
|
|
469
|
-
process.exit(1);
|
|
470
|
-
}
|
|
471
|
-
const plan = JSON.parse(readFileSync(planPath, "utf8"));
|
|
472
|
-
const ctx = makeCtx();
|
|
473
|
-
setupRestaurants(ctx, plan)
|
|
474
|
-
.then((result) => console.log(JSON.stringify(result, null, 2)))
|
|
475
|
-
.catch((e) => {
|
|
476
|
-
console.error(e.message);
|
|
477
|
-
process.exit(1);
|
|
478
|
-
});
|
|
479
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# Content floor — the copy you write on every authored surface
|
|
2
|
-
|
|
3
|
-
**A fallback, not an override.** If the user supplied copy, voice, or tone, use theirs. The
|
|
4
|
-
one exception is the first rule — a comprehension floor, not a style preference.
|
|
5
|
-
|
|
6
|
-
- **Say what the business is, literally, above the fold.** A first-time visitor must know
|
|
7
|
-
what the site *is* and can *do* from the hero alone. The business category ("ceramics
|
|
8
|
-
studio", "trattoria", "yoga studio") appears verbatim in the H1, the kicker above it, or
|
|
9
|
-
the first clause of the subtitle. A witty H1 is welcome — beside an explicit category,
|
|
10
|
-
never instead of one.
|
|
11
|
-
- **The subtitle leads with the offer** — the verb the visitor cares about comes early
|
|
12
|
-
("Book…", "Order…", "Browse…"), flavor after.
|
|
13
|
-
- **Kickers carry information or don't exist.** "Handmade in Portland · Since 2019" earns its
|
|
14
|
-
place; "The Collection" above a Collection heading doesn't. A voice-led H1 pairs with an
|
|
15
|
-
informative kicker (that's where the category goes).
|
|
16
|
-
- **Titles and subtitles end without a period.** Paragraphs keep theirs.
|
|
17
|
-
- **CTA labels are short, concrete, and not all-caps** — the actual action, matching the one
|
|
18
|
-
primary CTA per page (`DESIGN.md`).
|
|
19
|
-
- **No fluff.** Every line moves a visitor's understanding forward — the H1 and subtitle most
|
|
20
|
-
of all.
|
|
21
|
-
- **A caption describes what its image actually shows.** A slogan overlaid on a photo is not
|
|
22
|
-
a caption; if none is warranted, write none.
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
# Custom operations
|
|
2
|
-
|
|
3
|
-
Shipped vertical code covers its advertised contract. A brief can also require an operation
|
|
4
|
-
outside that contract: a member submission, a file derived in the browser, moderation, a
|
|
5
|
-
custom business write, or a third-party service.
|
|
6
|
-
|
|
7
|
-
## Decide the boundary first
|
|
8
|
-
|
|
9
|
-
1. **Caller-permitted Wix operation** — add one function to the appropriate `src/wix/<vertical>/`
|
|
10
|
-
data layer. Use the documented SDK method; components call that function, never the SDK.
|
|
11
|
-
2. **Privileged Wix operation** — on Wix-managed Astro, create a narrow `src/pages/api/` endpoint.
|
|
12
|
-
Authenticate/authorize the caller and validate the exact input before elevating the one SDK
|
|
13
|
-
call with `auth.elevate()`. On another stack, the equivalent belongs on a server using
|
|
14
|
-
server-only credentials. Never expose an elevated method or credential to the browser.
|
|
15
|
-
3. **No documented Wix path** — simplify the feature to a supported design. Do not infer a
|
|
16
|
-
contract from generated types, SDK implementation files, or `node_modules`.
|
|
17
|
-
|
|
18
|
-
## The research rule
|
|
19
|
-
|
|
20
|
-
Read the relevant shipped playbook first. For anything it doesn't cover, use `wix-docs` to
|
|
21
|
-
read the official method or feature guide, then implement that contract. One documentation
|
|
22
|
-
lookup and one type check are enough before coding. Investigate further only after a concrete error.
|
|
23
|
-
|
|
24
|
-
## User-created public content
|
|
25
|
-
|
|
26
|
-
Use the CMS vertical when a visitor or member submits content that the app must later list or
|
|
27
|
-
show publicly. Seed the collection with the appropriate permission preset and never trust the
|
|
28
|
-
browser to choose an owner, collection, or privileged action.
|
|
29
|
-
|
|
30
|
-
For a small browser-created artifact, the official Wix-managed Astro pattern is a validated
|
|
31
|
-
server endpoint that writes the contribution with elevation. For binary media, first confirm
|
|
32
|
-
the Media Files API's authorization requirements: generating a media upload URL requires
|
|
33
|
-
Manage Media Manager permission, so it is not a browser-side member call. Validate identity,
|
|
34
|
-
MIME type, size, and destination before any elevated call. The authoritative references are:
|
|
35
|
-
|
|
36
|
-
- `wix-docs`: **Upload Images to CMS** for the secure CMS contribution flow.
|
|
37
|
-
- `wix-docs`: **Generate File Upload URL** and **Upload API** for Media Manager files.
|
|
38
|
-
|
|
39
|
-
Keep the endpoint specific to the allowed contribution. An endpoint that accepts arbitrary
|
|
40
|
-
SDK method names, collection ids, or upload destinations is a privilege-escalation bug.
|
|
41
|
-
|
|
42
|
-
## Optional Media Upload capability
|
|
43
|
-
|
|
44
|
-
Use this only when a site actually needs a normal file upload (not a small canvas artifact
|
|
45
|
-
stored as a CMS data URL). Put the policy in the site plan; the Fast deployer ships the shared
|
|
46
|
-
client helper and Astro endpoint once, plus a generated read-only policy module:
|
|
47
|
-
|
|
48
|
-
```json
|
|
49
|
-
{
|
|
50
|
-
"capabilities": {
|
|
51
|
-
"mediaUpload": {
|
|
52
|
-
"policies": [{
|
|
53
|
-
"id": "gallery-artwork",
|
|
54
|
-
"accept": ["image/png", "image/jpeg"],
|
|
55
|
-
"maxBytes": 5242880
|
|
56
|
-
}]
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
The generated policy lives at `src/wix/media-upload/policies.generated.ts`; do not hand-edit
|
|
63
|
-
it. The shared browser helper is `src/wix/media-upload/client.ts`:
|
|
64
|
-
|
|
65
|
-
```ts
|
|
66
|
-
const media = await uploadMedia("gallery-artwork", pngBlob, "my-drawing.png");
|
|
67
|
-
// media.id and media.url are the Wix Media reference to store in the intended CMS image field.
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
The browser can select only the **named policy** and the bytes. The deployed API route fixes
|
|
71
|
-
the destination and elevates only `files.generateFileUploadUrl`. A vertical uses the same
|
|
72
|
-
capability by putting its own policy in its plan. Do not copy, fork, or widen the endpoint in
|
|
73
|
-
vertical code.
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# Design floor — every vertical, every surface you author
|
|
2
|
-
|
|
3
|
-
**A fallback, not an override.** These rules fill the gap when the user gave no design
|
|
4
|
-
direction. The moment the brief specifies a palette, a mood, a reference — their intent wins.
|
|
5
|
-
Two exceptions that hold regardless: the contrast floor (in `styles/global.css`, where you
|
|
6
|
-
choose the tokens), and the anti-genericism intent — derive the look from *this* brand even
|
|
7
|
-
when the user supplied the inputs.
|
|
8
|
-
|
|
9
|
-
Token judgment (polarity, palette, contrast, type floors) lives in the `@theme` header in
|
|
10
|
-
`styles/global.css` — you'll meet it when you set the tokens. This file governs the surfaces:
|
|
11
|
-
|
|
12
|
-
- **Full-bleed, not boxed.** Don't wrap pages in a narrow centered shell (`max-w-4xl mx-auto`
|
|
13
|
-
around everything). Design for the viewport; use peripheral space intentionally.
|
|
14
|
-
- **One primary CTA per page**, worded to the page's actual action — "Add to Cart",
|
|
15
|
-
"Book a Table", "Reserve Your Spot" — never "Submit" / "Click here" / "Learn more" as the
|
|
16
|
-
hero action.
|
|
17
|
-
- **Icons render bare on the surface** — no circle/square/pill shell behind nav or card
|
|
18
|
-
glyphs.
|
|
19
|
-
- **No emojis** in UI copy, headings, or empty states (unless the brief itself asks for
|
|
20
|
-
them).
|
|
21
|
-
- **Vary the look across projects.** Repeating the same palette/layout on unrelated brands is
|
|
22
|
-
a failure mode, not a shortcut — two sites with the same vertical and different briefs
|
|
23
|
-
should look nothing alike.
|
|
24
|
-
|
|
25
|
-
This constrains the *how*, not the *what* — the brief and the vertical decide what the pages
|
|
26
|
-
are; INSTRUCTIONS decides which surfaces exist.
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# Supplied content — when the user brings their own
|
|
2
|
-
|
|
3
|
-
When the brief supplies the content in any form — a CSV, JSON or spreadsheet, a list typed in the
|
|
4
|
-
prompt, a PDF or an image of a price list or a menu, a folder of photos with a text file beside
|
|
5
|
-
it, a link to a page that lists it — that source is the seed plan. The vertical's default count
|
|
6
|
-
("start with 3", "a few posts") applies only to catalogs you draft yourself.
|
|
7
|
-
|
|
8
|
-
Read it however it needs to be read: parse the file (a quoted comma inside a description is
|
|
9
|
-
common), open the PDF, fetch the page, look at the images. Then map, don't author:
|
|
10
|
-
|
|
11
|
-
- Every entry in the source becomes an entry in the plan. Names, titles, descriptions, prices,
|
|
12
|
-
dates verbatim; never rename, reprice, reword, reorder or add.
|
|
13
|
-
- Column and field names vary; map by meaning to the fields the vertical's `SEED.md` plan
|
|
14
|
-
shape defines. Anything the plan has no field for is dropped — say which columns you dropped.
|
|
15
|
-
- Their images only: an image URL column → the plan's image URL field, verified with `curl -sI`
|
|
16
|
-
→ 200; a local file → the plan's image path field. An entry with no image is seeded without one
|
|
17
|
-
and listed in your summary. **Never an `imagePrompt` beside supplied content** — these are their
|
|
18
|
-
things, not a mood board.
|
|
19
|
-
- Currency, time zone, address: only when the source or the brief states them.
|
|
20
|
-
- Show the user the count you read next to the count you seeded, and the mapping you applied.
|
|
21
|
-
|
|
22
|
-
The vertical's `SEED.md` says what an entry is for that vertical and which of its plan fields the
|
|
23
|
-
usual columns land in.
|