@wix/agent-skills 1.25.0 → 1.27.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/README.md +1 -0
- package/package.json +1 -1
- package/skills/wix-app/SKILL.md +18 -17
- package/skills/wix-app/references/BUSINESS_MANAGER_THEME.md +1 -2
- package/skills/wix-app/references/BUSINESS_MANAGER_TOKENS.md +1 -1
- package/skills/wix-app/references/DASHBOARD_PAGE.md +12 -12
- package/skills/wix-app/references/WIX_PATTERNS_DOCS.md +3 -2
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE.md +75 -66
- package/skills/wix-app/references/dashboard-page/UX_SUCCESS_MODEL.md +4 -5
- package/skills/wix-app/references/data-collection/LIFECYCLE.md +6 -4
- package/skills/wix-headless-kit/SKILL.md +31 -14
- package/skills/wix-headless-kit/guides/existing-site.md +12 -5
- package/skills/wix-headless-kit/install/attach.mjs +55 -10
- package/skills/wix-headless-kit/install/check.mjs +5 -5
- package/skills/wix-headless-kit/install/deploy.mjs +7 -3
- package/skills/wix-headless-kit/install/templates.mjs +21 -17
- package/skills/wix-headless-templates/SKILL.md +43 -0
- package/skills/wix-headless-templates/blank/project/README.md +15 -0
- package/skills/wix-headless-templates/blank/project/astro.config.mjs +20 -0
- package/skills/wix-headless-templates/blank/project/package.json +34 -0
- package/skills/wix-headless-templates/blank/project/public/favicon.svg +9 -0
- package/skills/wix-headless-templates/blank/project/src/assets/astro.svg +1 -0
- package/skills/wix-headless-templates/blank/project/src/assets/background.svg +1 -0
- package/skills/wix-headless-templates/blank/project/src/assets/wix.svg +18 -0
- package/skills/wix-headless-templates/blank/project/src/components/Hero.astro +77 -0
- package/skills/wix-headless-templates/blank/project/src/components/Welcome.astro +95 -0
- package/skills/wix-headless-templates/blank/project/src/layouts/Layout.astro +22 -0
- package/skills/wix-headless-templates/blank/project/src/pages/index.astro +8 -0
- package/skills/wix-headless-templates/blank/project/tsconfig.json +5 -0
- package/skills/wix-headless-templates/blog/INSTRUCTIONS.md +418 -0
- package/skills/wix-headless-templates/blog/app/components/blog/BlogFeedView.tsx +191 -0
- package/skills/wix-headless-templates/blog/app/components/blog/CommentsView.tsx +206 -0
- package/skills/wix-headless-templates/blog/app/components/blog/PostLikeButton.tsx +62 -0
- package/skills/wix-headless-templates/blog/app/components/blog/PostView.tsx +139 -0
- package/skills/wix-headless-templates/blog/app/components/blog/RichContent.tsx +42 -0
- package/skills/wix-headless-templates/blog/app/hooks/blog/useBlogFeed.ts +31 -0
- package/skills/wix-headless-templates/blog/app/hooks/blog/useComments.ts +26 -0
- package/skills/wix-headless-templates/blog/app/hooks/blog/usePost.ts +25 -0
- package/skills/wix-headless-templates/blog/app/wix/blog/authors-core.ts +51 -0
- package/skills/wix-headless-templates/blog/app/wix/blog/authors.ts +50 -0
- package/skills/wix-headless-templates/blog/app/wix/blog/blog-feed-store.ts +156 -0
- package/skills/wix-headless-templates/blog/app/wix/blog/comments-core.ts +189 -0
- package/skills/wix-headless-templates/blog/app/wix/blog/comments-store.ts +214 -0
- package/skills/wix-headless-templates/blog/app/wix/blog/comments.ts +84 -0
- package/skills/wix-headless-templates/blog/app/wix/blog/post-likes.ts +42 -0
- package/skills/wix-headless-templates/blog/app/wix/blog/post-store.ts +158 -0
- package/skills/wix-headless-templates/blog/app/wix/blog/posts-core.ts +347 -0
- package/skills/wix-headless-templates/blog/app/wix/blog/posts.ts +132 -0
- package/skills/wix-headless-templates/blog/app/wix/blog/taxonomy-core.ts +80 -0
- package/skills/wix-headless-templates/blog/app/wix/blog/taxonomy.ts +78 -0
- package/skills/wix-headless-templates/blog/app/wix/blog/types.ts +161 -0
- package/skills/wix-headless-templates/blog/app-astro/layouts/SiteLayout.astro +44 -0
- package/skills/wix-headless-templates/blog/app-astro/pages/blog/[...slug].astro +148 -0
- package/skills/wix-headless-templates/blog/app-astro/pages/blog/category/[slug].astro +97 -0
- package/skills/wix-headless-templates/blog/app-astro/pages/blog/tag/[slug].astro +51 -0
- package/skills/wix-headless-templates/blog/app-astro/pages/blog.astro +34 -0
- package/skills/wix-headless-templates/blog/project/README.md +15 -0
- package/skills/wix-headless-templates/blog/project/astro.config.mjs +22 -0
- package/skills/wix-headless-templates/blog/project/package-lock.json +14699 -0
- package/skills/wix-headless-templates/blog/project/package.json +39 -0
- package/skills/wix-headless-templates/blog/project/public/favicon.svg +9 -0
- package/skills/wix-headless-templates/blog/project/src/assets/astro.svg +1 -0
- package/skills/wix-headless-templates/blog/project/src/assets/background.svg +1 -0
- package/skills/wix-headless-templates/blog/project/src/assets/wix.svg +18 -0
- package/skills/wix-headless-templates/blog/project/src/components/Hero.astro +77 -0
- package/skills/wix-headless-templates/blog/project/src/components/Welcome.astro +95 -0
- package/skills/wix-headless-templates/blog/project/src/components/blog/BlogFeedView.tsx +191 -0
- package/skills/wix-headless-templates/blog/project/src/components/blog/CommentsView.tsx +206 -0
- package/skills/wix-headless-templates/blog/project/src/components/blog/PostLikeButton.tsx +62 -0
- package/skills/wix-headless-templates/blog/project/src/components/blog/PostView.tsx +139 -0
- package/skills/wix-headless-templates/blog/project/src/components/blog/RichContent.tsx +42 -0
- package/skills/wix-headless-templates/blog/project/src/hooks/blog/useBlogFeed.ts +31 -0
- package/skills/wix-headless-templates/blog/project/src/hooks/blog/useComments.ts +26 -0
- package/skills/wix-headless-templates/blog/project/src/hooks/blog/usePost.ts +25 -0
- package/skills/wix-headless-templates/blog/project/src/layouts/Layout.astro +22 -0
- package/skills/wix-headless-templates/blog/project/src/layouts/SiteLayout.astro +44 -0
- package/skills/wix-headless-templates/blog/project/src/pages/blog/[...slug].astro +148 -0
- package/skills/wix-headless-templates/blog/project/src/pages/blog/category/[slug].astro +97 -0
- package/skills/wix-headless-templates/blog/project/src/pages/blog/tag/[slug].astro +51 -0
- package/skills/wix-headless-templates/blog/project/src/pages/blog.astro +34 -0
- package/skills/wix-headless-templates/blog/project/src/pages/index.astro +8 -0
- package/skills/wix-headless-templates/blog/project/src/styles/global.css +57 -0
- package/skills/wix-headless-templates/blog/project/src/wix/blog/authors-core.ts +51 -0
- package/skills/wix-headless-templates/blog/project/src/wix/blog/authors.ts +50 -0
- package/skills/wix-headless-templates/blog/project/src/wix/blog/blog-feed-store.ts +156 -0
- package/skills/wix-headless-templates/blog/project/src/wix/blog/comments-core.ts +189 -0
- package/skills/wix-headless-templates/blog/project/src/wix/blog/comments-store.ts +214 -0
- package/skills/wix-headless-templates/blog/project/src/wix/blog/comments.ts +84 -0
- package/skills/wix-headless-templates/blog/project/src/wix/blog/post-likes.ts +42 -0
- package/skills/wix-headless-templates/blog/project/src/wix/blog/post-store.ts +158 -0
- package/skills/wix-headless-templates/blog/project/src/wix/blog/posts-core.ts +347 -0
- package/skills/wix-headless-templates/blog/project/src/wix/blog/posts.ts +132 -0
- package/skills/wix-headless-templates/blog/project/src/wix/blog/taxonomy-core.ts +80 -0
- package/skills/wix-headless-templates/blog/project/src/wix/blog/taxonomy.ts +78 -0
- package/skills/wix-headless-templates/blog/project/src/wix/blog/types.ts +161 -0
- package/skills/wix-headless-templates/blog/project/src/wix/config.ts +16 -0
- package/skills/wix-headless-templates/blog/project/src/wix/media.ts +106 -0
- package/skills/wix-headless-templates/blog/project/src/wix/money.ts +24 -0
- package/skills/wix-headless-templates/blog/project/src/wix/sdk.ts +89 -0
- package/skills/wix-headless-templates/blog/project/tsconfig.json +5 -0
- package/skills/wix-headless-templates/blog/rest/authors.ts +39 -0
- package/skills/wix-headless-templates/blog/rest/comments.ts +64 -0
- package/skills/wix-headless-templates/blog/rest/post-likes.ts +37 -0
- package/skills/wix-headless-templates/blog/rest/posts.ts +123 -0
- package/skills/wix-headless-templates/blog/rest/taxonomy.ts +79 -0
- package/skills/wix-headless-templates/blog/seed/SEED.md +81 -0
- package/skills/wix-headless-templates/blog/seed/read-site.mjs +33 -0
- package/skills/wix-headless-templates/blog/seed/seed-blog.mjs +337 -0
- package/skills/wix-headless-templates/bookings/INSTRUCTIONS.md +356 -0
- package/skills/wix-headless-templates/bookings/app/components/bookings/ServiceBookingView.tsx +369 -0
- package/skills/wix-headless-templates/bookings/app/components/bookings/ServicesView.tsx +193 -0
- package/skills/wix-headless-templates/bookings/app/hooks/bookings/useBookingFlow.ts +56 -0
- package/skills/wix-headless-templates/bookings/app/hooks/bookings/useServices.ts +23 -0
- package/skills/wix-headless-templates/bookings/app/wix/bookings/booking-core.ts +614 -0
- package/skills/wix-headless-templates/bookings/app/wix/bookings/booking-flow-store.ts +410 -0
- package/skills/wix-headless-templates/bookings/app/wix/bookings/booking.ts +227 -0
- package/skills/wix-headless-templates/bookings/app/wix/bookings/services-core.ts +366 -0
- package/skills/wix-headless-templates/bookings/app/wix/bookings/services-store.ts +213 -0
- package/skills/wix-headless-templates/bookings/app/wix/bookings/services.ts +100 -0
- package/skills/wix-headless-templates/bookings/app/wix/bookings/types.ts +236 -0
- package/skills/wix-headless-templates/bookings/app-astro/layouts/SiteLayout.astro +40 -0
- package/skills/wix-headless-templates/bookings/app-astro/pages/services/[slug].astro +81 -0
- package/skills/wix-headless-templates/bookings/app-astro/pages/services.astro +40 -0
- package/skills/wix-headless-templates/bookings/project/README.md +15 -0
- package/skills/wix-headless-templates/bookings/project/astro.config.mjs +22 -0
- package/skills/wix-headless-templates/bookings/project/package-lock.json +10546 -0
- package/skills/wix-headless-templates/bookings/project/package.json +41 -0
- package/skills/wix-headless-templates/bookings/project/public/favicon.svg +9 -0
- package/skills/wix-headless-templates/bookings/project/src/assets/astro.svg +1 -0
- package/skills/wix-headless-templates/bookings/project/src/assets/background.svg +1 -0
- package/skills/wix-headless-templates/bookings/project/src/assets/wix.svg +18 -0
- package/skills/wix-headless-templates/bookings/project/src/components/Hero.astro +77 -0
- package/skills/wix-headless-templates/bookings/project/src/components/Welcome.astro +95 -0
- package/skills/wix-headless-templates/bookings/project/src/components/bookings/ServiceBookingView.tsx +369 -0
- package/skills/wix-headless-templates/bookings/project/src/components/bookings/ServicesView.tsx +193 -0
- package/skills/wix-headless-templates/bookings/project/src/hooks/bookings/useBookingFlow.ts +56 -0
- package/skills/wix-headless-templates/bookings/project/src/hooks/bookings/useServices.ts +23 -0
- package/skills/wix-headless-templates/bookings/project/src/layouts/Layout.astro +22 -0
- package/skills/wix-headless-templates/bookings/project/src/layouts/SiteLayout.astro +40 -0
- package/skills/wix-headless-templates/bookings/project/src/pages/index.astro +8 -0
- package/skills/wix-headless-templates/bookings/project/src/pages/services/[slug].astro +81 -0
- package/skills/wix-headless-templates/bookings/project/src/pages/services.astro +40 -0
- package/skills/wix-headless-templates/bookings/project/src/styles/global.css +57 -0
- package/skills/wix-headless-templates/bookings/project/src/wix/bookings/booking-core.ts +614 -0
- package/skills/wix-headless-templates/bookings/project/src/wix/bookings/booking-flow-store.ts +410 -0
- package/skills/wix-headless-templates/bookings/project/src/wix/bookings/booking.ts +227 -0
- package/skills/wix-headless-templates/bookings/project/src/wix/bookings/services-core.ts +366 -0
- package/skills/wix-headless-templates/bookings/project/src/wix/bookings/services-store.ts +213 -0
- package/skills/wix-headless-templates/bookings/project/src/wix/bookings/services.ts +100 -0
- package/skills/wix-headless-templates/bookings/project/src/wix/bookings/types.ts +236 -0
- package/skills/wix-headless-templates/bookings/project/src/wix/config.ts +16 -0
- package/skills/wix-headless-templates/bookings/project/src/wix/media.ts +106 -0
- package/skills/wix-headless-templates/bookings/project/src/wix/money.ts +24 -0
- package/skills/wix-headless-templates/bookings/project/src/wix/sdk.ts +89 -0
- package/skills/wix-headless-templates/bookings/project/tsconfig.json +5 -0
- package/skills/wix-headless-templates/bookings/rest/booking.ts +227 -0
- package/skills/wix-headless-templates/bookings/rest/services.ts +94 -0
- package/skills/wix-headless-templates/bookings/seed/SEED.md +109 -0
- package/skills/wix-headless-templates/bookings/seed/read-site.mjs +28 -0
- package/skills/wix-headless-templates/bookings/seed/seed-bookings.mjs +407 -0
- package/skills/wix-headless-templates/cms/INSTRUCTIONS.md +399 -0
- package/skills/wix-headless-templates/cms/app/hooks/cms/useCollection.ts +82 -0
- package/skills/wix-headless-templates/cms/app/hooks/cms/useItem.ts +37 -0
- package/skills/wix-headless-templates/cms/app/wix/cms/collection-store.ts +220 -0
- package/skills/wix-headless-templates/cms/app/wix/cms/collections-core.ts +41 -0
- package/skills/wix-headless-templates/cms/app/wix/cms/collections.ts +28 -0
- package/skills/wix-headless-templates/cms/app/wix/cms/item-store.ts +93 -0
- package/skills/wix-headless-templates/cms/app/wix/cms/items-core.ts +259 -0
- package/skills/wix-headless-templates/cms/app/wix/cms/items.ts +182 -0
- package/skills/wix-headless-templates/cms/app/wix/cms/types.ts +138 -0
- package/skills/wix-headless-templates/cms/app-astro/layouts/SiteLayout.astro +41 -0
- package/skills/wix-headless-templates/cms/project/README.md +15 -0
- package/skills/wix-headless-templates/cms/project/astro.config.mjs +22 -0
- package/skills/wix-headless-templates/cms/project/package-lock.json +9798 -0
- package/skills/wix-headless-templates/cms/project/package.json +37 -0
- package/skills/wix-headless-templates/cms/project/public/favicon.svg +9 -0
- package/skills/wix-headless-templates/cms/project/src/assets/astro.svg +1 -0
- package/skills/wix-headless-templates/cms/project/src/assets/background.svg +1 -0
- package/skills/wix-headless-templates/cms/project/src/assets/wix.svg +18 -0
- package/skills/wix-headless-templates/cms/project/src/components/Hero.astro +77 -0
- package/skills/wix-headless-templates/cms/project/src/components/Welcome.astro +95 -0
- package/skills/wix-headless-templates/cms/project/src/hooks/cms/useCollection.ts +82 -0
- package/skills/wix-headless-templates/cms/project/src/hooks/cms/useItem.ts +37 -0
- package/skills/wix-headless-templates/cms/project/src/layouts/Layout.astro +22 -0
- package/skills/wix-headless-templates/cms/project/src/layouts/SiteLayout.astro +41 -0
- package/skills/wix-headless-templates/cms/project/src/pages/index.astro +8 -0
- package/skills/wix-headless-templates/cms/project/src/styles/global.css +57 -0
- package/skills/wix-headless-templates/cms/project/src/wix/cms/collection-store.ts +220 -0
- package/skills/wix-headless-templates/cms/project/src/wix/cms/collections-core.ts +41 -0
- package/skills/wix-headless-templates/cms/project/src/wix/cms/collections.ts +28 -0
- package/skills/wix-headless-templates/cms/project/src/wix/cms/item-store.ts +93 -0
- package/skills/wix-headless-templates/cms/project/src/wix/cms/items-core.ts +259 -0
- package/skills/wix-headless-templates/cms/project/src/wix/cms/items.ts +182 -0
- package/skills/wix-headless-templates/cms/project/src/wix/cms/types.ts +138 -0
- package/skills/wix-headless-templates/cms/project/src/wix/config.ts +16 -0
- package/skills/wix-headless-templates/cms/project/src/wix/media.ts +106 -0
- package/skills/wix-headless-templates/cms/project/src/wix/money.ts +24 -0
- package/skills/wix-headless-templates/cms/project/src/wix/sdk.ts +89 -0
- package/skills/wix-headless-templates/cms/project/tsconfig.json +5 -0
- package/skills/wix-headless-templates/cms/rest/collections.ts +25 -0
- package/skills/wix-headless-templates/cms/rest/items.ts +189 -0
- package/skills/wix-headless-templates/cms/seed/SEED.md +116 -0
- package/skills/wix-headless-templates/cms/seed/read-site.mjs +20 -0
- package/skills/wix-headless-templates/cms/seed/seed-cms.mjs +321 -0
- package/skills/wix-headless-templates/compose.mjs +83 -0
- package/skills/wix-headless-templates/donations/INSTRUCTIONS.md +349 -0
- package/skills/wix-headless-templates/donations/app/components/donations/DonateForm.tsx +155 -0
- package/skills/wix-headless-templates/donations/app/components/donations/DonationReceipt.tsx +46 -0
- package/skills/wix-headless-templates/donations/app/components/donations/GoalProgress.tsx +49 -0
- package/skills/wix-headless-templates/donations/app/hooks/donations/useCampaigns.ts +21 -0
- package/skills/wix-headless-templates/donations/app/hooks/donations/useDonation.ts +27 -0
- package/skills/wix-headless-templates/donations/app/hooks/donations/useDonationReceipt.ts +19 -0
- package/skills/wix-headless-templates/donations/app/wix/donations/campaigns-store.ts +59 -0
- package/skills/wix-headless-templates/donations/app/wix/donations/campaigns.ts +83 -0
- package/skills/wix-headless-templates/donations/app/wix/donations/donate.ts +95 -0
- package/skills/wix-headless-templates/donations/app/wix/donations/donation-store.ts +163 -0
- package/skills/wix-headless-templates/donations/app/wix/donations/donations-core.ts +466 -0
- package/skills/wix-headless-templates/donations/app/wix/donations/receipt-store.ts +55 -0
- package/skills/wix-headless-templates/donations/app/wix/donations/types.ts +121 -0
- package/skills/wix-headless-templates/donations/app-astro/components/donations/CampaignPage.astro +43 -0
- package/skills/wix-headless-templates/donations/app-astro/layouts/SiteLayout.astro +45 -0
- package/skills/wix-headless-templates/donations/app-astro/pages/donate/[id].astro +28 -0
- package/skills/wix-headless-templates/donations/app-astro/pages/donate/index.astro +51 -0
- package/skills/wix-headless-templates/donations/app-astro/pages/donate/thank-you.astro +13 -0
- package/skills/wix-headless-templates/donations/project/README.md +15 -0
- package/skills/wix-headless-templates/donations/project/astro.config.mjs +22 -0
- package/skills/wix-headless-templates/donations/project/package-lock.json +10266 -0
- package/skills/wix-headless-templates/donations/project/package.json +39 -0
- package/skills/wix-headless-templates/donations/project/public/favicon.svg +9 -0
- package/skills/wix-headless-templates/donations/project/src/assets/astro.svg +1 -0
- package/skills/wix-headless-templates/donations/project/src/assets/background.svg +1 -0
- package/skills/wix-headless-templates/donations/project/src/assets/wix.svg +18 -0
- package/skills/wix-headless-templates/donations/project/src/components/Hero.astro +77 -0
- package/skills/wix-headless-templates/donations/project/src/components/Welcome.astro +95 -0
- package/skills/wix-headless-templates/donations/project/src/components/donations/CampaignPage.astro +43 -0
- package/skills/wix-headless-templates/donations/project/src/components/donations/DonateForm.tsx +155 -0
- package/skills/wix-headless-templates/donations/project/src/components/donations/DonationReceipt.tsx +46 -0
- package/skills/wix-headless-templates/donations/project/src/components/donations/GoalProgress.tsx +49 -0
- package/skills/wix-headless-templates/donations/project/src/hooks/donations/useCampaigns.ts +21 -0
- package/skills/wix-headless-templates/donations/project/src/hooks/donations/useDonation.ts +27 -0
- package/skills/wix-headless-templates/donations/project/src/hooks/donations/useDonationReceipt.ts +19 -0
- package/skills/wix-headless-templates/donations/project/src/layouts/Layout.astro +22 -0
- package/skills/wix-headless-templates/donations/project/src/layouts/SiteLayout.astro +45 -0
- package/skills/wix-headless-templates/donations/project/src/pages/donate/[id].astro +28 -0
- package/skills/wix-headless-templates/donations/project/src/pages/donate/index.astro +51 -0
- package/skills/wix-headless-templates/donations/project/src/pages/donate/thank-you.astro +13 -0
- package/skills/wix-headless-templates/donations/project/src/pages/index.astro +8 -0
- package/skills/wix-headless-templates/donations/project/src/styles/global.css +57 -0
- package/skills/wix-headless-templates/donations/project/src/wix/config.ts +16 -0
- package/skills/wix-headless-templates/donations/project/src/wix/donations/campaigns-store.ts +59 -0
- package/skills/wix-headless-templates/donations/project/src/wix/donations/campaigns.ts +83 -0
- package/skills/wix-headless-templates/donations/project/src/wix/donations/donate.ts +95 -0
- package/skills/wix-headless-templates/donations/project/src/wix/donations/donation-store.ts +163 -0
- package/skills/wix-headless-templates/donations/project/src/wix/donations/donations-core.ts +466 -0
- package/skills/wix-headless-templates/donations/project/src/wix/donations/receipt-store.ts +55 -0
- package/skills/wix-headless-templates/donations/project/src/wix/donations/types.ts +121 -0
- package/skills/wix-headless-templates/donations/project/src/wix/media.ts +106 -0
- package/skills/wix-headless-templates/donations/project/src/wix/money.ts +24 -0
- package/skills/wix-headless-templates/donations/project/src/wix/sdk.ts +89 -0
- package/skills/wix-headless-templates/donations/project/tsconfig.json +5 -0
- package/skills/wix-headless-templates/donations/rest/campaigns.ts +76 -0
- package/skills/wix-headless-templates/donations/rest/donate.ts +90 -0
- package/skills/wix-headless-templates/donations/seed/SEED.md +90 -0
- package/skills/wix-headless-templates/donations/seed/read-site.mjs +33 -0
- package/skills/wix-headless-templates/donations/seed/seed-donations.mjs +250 -0
- package/skills/wix-headless-templates/events/INSTRUCTIONS.md +387 -0
- package/skills/wix-headless-templates/events/app/components/events/EventConfirmationView.tsx +139 -0
- package/skills/wix-headless-templates/events/app/components/events/EventRegistrationView.tsx +375 -0
- package/skills/wix-headless-templates/events/app/components/events/EventsView.tsx +134 -0
- package/skills/wix-headless-templates/events/app/hooks/events/useEventConfirmation.ts +21 -0
- package/skills/wix-headless-templates/events/app/hooks/events/useEventRegistration.ts +40 -0
- package/skills/wix-headless-templates/events/app/hooks/events/useEvents.ts +24 -0
- package/skills/wix-headless-templates/events/app/wix/events/events-core.ts +379 -0
- package/skills/wix-headless-templates/events/app/wix/events/events-store.ts +175 -0
- package/skills/wix-headless-templates/events/app/wix/events/events.ts +124 -0
- package/skills/wix-headless-templates/events/app/wix/events/order-store.ts +143 -0
- package/skills/wix-headless-templates/events/app/wix/events/orders-core.ts +86 -0
- package/skills/wix-headless-templates/events/app/wix/events/orders.ts +30 -0
- package/skills/wix-headless-templates/events/app/wix/events/registration-core.ts +415 -0
- package/skills/wix-headless-templates/events/app/wix/events/registration-store.ts +237 -0
- package/skills/wix-headless-templates/events/app/wix/events/registration.ts +109 -0
- package/skills/wix-headless-templates/events/app/wix/events/types.ts +249 -0
- package/skills/wix-headless-templates/events/app-astro/layouts/SiteLayout.astro +40 -0
- package/skills/wix-headless-templates/events/app-astro/pages/event-confirmation.astro +12 -0
- package/skills/wix-headless-templates/events/app-astro/pages/events/[slug].astro +104 -0
- package/skills/wix-headless-templates/events/app-astro/pages/events.astro +23 -0
- package/skills/wix-headless-templates/events/project/README.md +15 -0
- package/skills/wix-headless-templates/events/project/astro.config.mjs +22 -0
- package/skills/wix-headless-templates/events/project/package-lock.json +10497 -0
- package/skills/wix-headless-templates/events/project/package.json +39 -0
- package/skills/wix-headless-templates/events/project/public/favicon.svg +9 -0
- package/skills/wix-headless-templates/events/project/src/assets/astro.svg +1 -0
- package/skills/wix-headless-templates/events/project/src/assets/background.svg +1 -0
- package/skills/wix-headless-templates/events/project/src/assets/wix.svg +18 -0
- package/skills/wix-headless-templates/events/project/src/components/Hero.astro +77 -0
- package/skills/wix-headless-templates/events/project/src/components/Welcome.astro +95 -0
- package/skills/wix-headless-templates/events/project/src/components/events/EventConfirmationView.tsx +139 -0
- package/skills/wix-headless-templates/events/project/src/components/events/EventRegistrationView.tsx +375 -0
- package/skills/wix-headless-templates/events/project/src/components/events/EventsView.tsx +134 -0
- package/skills/wix-headless-templates/events/project/src/hooks/events/useEventConfirmation.ts +21 -0
- package/skills/wix-headless-templates/events/project/src/hooks/events/useEventRegistration.ts +40 -0
- package/skills/wix-headless-templates/events/project/src/hooks/events/useEvents.ts +24 -0
- package/skills/wix-headless-templates/events/project/src/layouts/Layout.astro +22 -0
- package/skills/wix-headless-templates/events/project/src/layouts/SiteLayout.astro +40 -0
- package/skills/wix-headless-templates/events/project/src/pages/event-confirmation.astro +12 -0
- package/skills/wix-headless-templates/events/project/src/pages/events/[slug].astro +104 -0
- package/skills/wix-headless-templates/events/project/src/pages/events.astro +23 -0
- package/skills/wix-headless-templates/events/project/src/pages/index.astro +8 -0
- package/skills/wix-headless-templates/events/project/src/styles/global.css +57 -0
- package/skills/wix-headless-templates/events/project/src/wix/config.ts +16 -0
- package/skills/wix-headless-templates/events/project/src/wix/events/events-core.ts +379 -0
- package/skills/wix-headless-templates/events/project/src/wix/events/events-store.ts +175 -0
- package/skills/wix-headless-templates/events/project/src/wix/events/events.ts +124 -0
- package/skills/wix-headless-templates/events/project/src/wix/events/order-store.ts +143 -0
- package/skills/wix-headless-templates/events/project/src/wix/events/orders-core.ts +86 -0
- package/skills/wix-headless-templates/events/project/src/wix/events/orders.ts +30 -0
- package/skills/wix-headless-templates/events/project/src/wix/events/registration-core.ts +415 -0
- package/skills/wix-headless-templates/events/project/src/wix/events/registration-store.ts +237 -0
- package/skills/wix-headless-templates/events/project/src/wix/events/registration.ts +109 -0
- package/skills/wix-headless-templates/events/project/src/wix/events/types.ts +249 -0
- package/skills/wix-headless-templates/events/project/src/wix/media.ts +106 -0
- package/skills/wix-headless-templates/events/project/src/wix/money.ts +24 -0
- package/skills/wix-headless-templates/events/project/src/wix/sdk.ts +89 -0
- package/skills/wix-headless-templates/events/project/tsconfig.json +5 -0
- package/skills/wix-headless-templates/events/rest/events.ts +112 -0
- package/skills/wix-headless-templates/events/rest/orders.ts +28 -0
- package/skills/wix-headless-templates/events/rest/registration.ts +96 -0
- package/skills/wix-headless-templates/events/seed/SEED.md +115 -0
- package/skills/wix-headless-templates/events/seed/read-site.mjs +26 -0
- package/skills/wix-headless-templates/events/seed/seed-events.mjs +322 -0
- package/skills/wix-headless-templates/faq/INSTRUCTIONS.md +317 -0
- package/skills/wix-headless-templates/faq/app/components/faq/FaqAccordion.tsx +159 -0
- package/skills/wix-headless-templates/faq/app/components/faq/FaqCategoryNav.tsx +46 -0
- package/skills/wix-headless-templates/faq/app/components/faq/FaqSearch.tsx +56 -0
- package/skills/wix-headless-templates/faq/app/hooks/faq/useFaq.ts +53 -0
- package/skills/wix-headless-templates/faq/app/wix/faq/faq-core.ts +428 -0
- package/skills/wix-headless-templates/faq/app/wix/faq/faq-store.ts +212 -0
- package/skills/wix-headless-templates/faq/app/wix/faq/faq.ts +72 -0
- package/skills/wix-headless-templates/faq/app/wix/faq/types.ts +63 -0
- package/skills/wix-headless-templates/faq/app-astro/layouts/SiteLayout.astro +40 -0
- package/skills/wix-headless-templates/faq/app-astro/pages/faq.astro +39 -0
- package/skills/wix-headless-templates/faq/project/README.md +15 -0
- package/skills/wix-headless-templates/faq/project/astro.config.mjs +22 -0
- package/skills/wix-headless-templates/faq/project/package-lock.json +8837 -0
- package/skills/wix-headless-templates/faq/project/package.json +37 -0
- package/skills/wix-headless-templates/faq/project/public/favicon.svg +9 -0
- package/skills/wix-headless-templates/faq/project/src/assets/astro.svg +1 -0
- package/skills/wix-headless-templates/faq/project/src/assets/background.svg +1 -0
- package/skills/wix-headless-templates/faq/project/src/assets/wix.svg +18 -0
- package/skills/wix-headless-templates/faq/project/src/components/Hero.astro +77 -0
- package/skills/wix-headless-templates/faq/project/src/components/Welcome.astro +95 -0
- package/skills/wix-headless-templates/faq/project/src/components/faq/FaqAccordion.tsx +159 -0
- package/skills/wix-headless-templates/faq/project/src/components/faq/FaqCategoryNav.tsx +46 -0
- package/skills/wix-headless-templates/faq/project/src/components/faq/FaqSearch.tsx +56 -0
- package/skills/wix-headless-templates/faq/project/src/hooks/faq/useFaq.ts +53 -0
- package/skills/wix-headless-templates/faq/project/src/layouts/Layout.astro +22 -0
- package/skills/wix-headless-templates/faq/project/src/layouts/SiteLayout.astro +40 -0
- package/skills/wix-headless-templates/faq/project/src/pages/faq.astro +39 -0
- package/skills/wix-headless-templates/faq/project/src/pages/index.astro +8 -0
- package/skills/wix-headless-templates/faq/project/src/styles/global.css +57 -0
- package/skills/wix-headless-templates/faq/project/src/wix/config.ts +16 -0
- package/skills/wix-headless-templates/faq/project/src/wix/faq/faq-core.ts +428 -0
- package/skills/wix-headless-templates/faq/project/src/wix/faq/faq-store.ts +212 -0
- package/skills/wix-headless-templates/faq/project/src/wix/faq/faq.ts +72 -0
- package/skills/wix-headless-templates/faq/project/src/wix/faq/types.ts +63 -0
- package/skills/wix-headless-templates/faq/project/src/wix/media.ts +106 -0
- package/skills/wix-headless-templates/faq/project/src/wix/money.ts +24 -0
- package/skills/wix-headless-templates/faq/project/src/wix/sdk.ts +89 -0
- package/skills/wix-headless-templates/faq/project/tsconfig.json +5 -0
- package/skills/wix-headless-templates/faq/rest/faq.ts +71 -0
- package/skills/wix-headless-templates/faq/seed/SEED.md +104 -0
- package/skills/wix-headless-templates/faq/seed/read-site.mjs +23 -0
- package/skills/wix-headless-templates/faq/seed/seed-faq.mjs +302 -0
- package/skills/wix-headless-templates/forms/INSTRUCTIONS.md +417 -0
- package/skills/wix-headless-templates/forms/app/hooks/forms/useWixForm.ts +108 -0
- package/skills/wix-headless-templates/forms/app/wix/forms/address-templates.generated.ts +13 -0
- package/skills/wix-headless-templates/forms/app/wix/forms/form-store.ts +533 -0
- package/skills/wix-headless-templates/forms/app/wix/forms/forms-core.ts +671 -0
- package/skills/wix-headless-templates/forms/app/wix/forms/forms.ts +57 -0
- package/skills/wix-headless-templates/forms/app/wix/forms/submissions-core.ts +423 -0
- package/skills/wix-headless-templates/forms/app/wix/forms/submissions.ts +95 -0
- package/skills/wix-headless-templates/forms/app/wix/forms/types.ts +284 -0
- package/skills/wix-headless-templates/forms/project/README.md +15 -0
- package/skills/wix-headless-templates/forms/project/astro.config.mjs +22 -0
- package/skills/wix-headless-templates/forms/project/package-lock.json +9102 -0
- package/skills/wix-headless-templates/forms/project/package.json +37 -0
- package/skills/wix-headless-templates/forms/project/public/favicon.svg +9 -0
- package/skills/wix-headless-templates/forms/project/src/assets/astro.svg +1 -0
- package/skills/wix-headless-templates/forms/project/src/assets/background.svg +1 -0
- package/skills/wix-headless-templates/forms/project/src/assets/wix.svg +18 -0
- package/skills/wix-headless-templates/forms/project/src/components/Hero.astro +77 -0
- package/skills/wix-headless-templates/forms/project/src/components/Welcome.astro +95 -0
- package/skills/wix-headless-templates/forms/project/src/hooks/forms/useWixForm.ts +108 -0
- package/skills/wix-headless-templates/forms/project/src/layouts/Layout.astro +22 -0
- package/skills/wix-headless-templates/forms/project/src/pages/index.astro +8 -0
- package/skills/wix-headless-templates/forms/project/src/styles/global.css +57 -0
- package/skills/wix-headless-templates/forms/project/src/wix/config.ts +16 -0
- package/skills/wix-headless-templates/forms/project/src/wix/forms/address-templates.generated.ts +13 -0
- package/skills/wix-headless-templates/forms/project/src/wix/forms/form-store.ts +533 -0
- package/skills/wix-headless-templates/forms/project/src/wix/forms/forms-core.ts +671 -0
- package/skills/wix-headless-templates/forms/project/src/wix/forms/forms.ts +57 -0
- package/skills/wix-headless-templates/forms/project/src/wix/forms/submissions-core.ts +423 -0
- package/skills/wix-headless-templates/forms/project/src/wix/forms/submissions.ts +95 -0
- package/skills/wix-headless-templates/forms/project/src/wix/forms/types.ts +284 -0
- package/skills/wix-headless-templates/forms/project/src/wix/media.ts +106 -0
- package/skills/wix-headless-templates/forms/project/src/wix/money.ts +24 -0
- package/skills/wix-headless-templates/forms/project/src/wix/sdk.ts +89 -0
- package/skills/wix-headless-templates/forms/project/tsconfig.json +5 -0
- package/skills/wix-headless-templates/forms/rest/forms.ts +37 -0
- package/skills/wix-headless-templates/forms/rest/submissions.ts +83 -0
- package/skills/wix-headless-templates/forms/seed/SEED.md +225 -0
- package/skills/wix-headless-templates/forms/seed/read-site.mjs +53 -0
- package/skills/wix-headless-templates/forms/seed/seed-forms.mjs +574 -0
- package/skills/wix-headless-templates/forms/tooling/address-templates.mjs +96 -0
- package/skills/wix-headless-templates/members/INSTRUCTIONS.md +345 -0
- package/skills/wix-headless-templates/members/app/components/members/AccountPage.tsx +16 -0
- package/skills/wix-headless-templates/members/app/components/members/AccountView.tsx +60 -0
- package/skills/wix-headless-templates/members/app/components/members/LoginForm.tsx +165 -0
- package/skills/wix-headless-templates/members/app/components/members/MemberMenu.tsx +78 -0
- package/skills/wix-headless-templates/members/app/components/members/RequireAuth.tsx +47 -0
- package/skills/wix-headless-templates/members/app/hooks/members/useMember.ts +67 -0
- package/skills/wix-headless-templates/members/app/wix/members/auth-core.ts +160 -0
- package/skills/wix-headless-templates/members/app/wix/members/auth.ts +117 -0
- package/skills/wix-headless-templates/members/app/wix/members/client.ts +27 -0
- package/skills/wix-headless-templates/members/app/wix/members/member-store.ts +133 -0
- package/skills/wix-headless-templates/members/app/wix/members/members-core.ts +43 -0
- package/skills/wix-headless-templates/members/app/wix/members/members.ts +29 -0
- package/skills/wix-headless-templates/members/app/wix/members/types.ts +21 -0
- package/skills/wix-headless-templates/members/app-astro/layouts/SiteLayout.astro +42 -0
- package/skills/wix-headless-templates/members/app-astro/pages/account.astro +9 -0
- package/skills/wix-headless-templates/members/app-astro/pages/login.astro +11 -0
- package/skills/wix-headless-templates/members/project/README.md +15 -0
- package/skills/wix-headless-templates/members/project/astro.config.mjs +22 -0
- package/skills/wix-headless-templates/members/project/package-lock.json +8892 -0
- package/skills/wix-headless-templates/members/project/package.json +37 -0
- package/skills/wix-headless-templates/members/project/public/favicon.svg +9 -0
- package/skills/wix-headless-templates/members/project/src/assets/astro.svg +1 -0
- package/skills/wix-headless-templates/members/project/src/assets/background.svg +1 -0
- package/skills/wix-headless-templates/members/project/src/assets/wix.svg +18 -0
- package/skills/wix-headless-templates/members/project/src/components/Hero.astro +77 -0
- package/skills/wix-headless-templates/members/project/src/components/Welcome.astro +95 -0
- package/skills/wix-headless-templates/members/project/src/components/members/AccountPage.tsx +16 -0
- package/skills/wix-headless-templates/members/project/src/components/members/AccountView.tsx +60 -0
- package/skills/wix-headless-templates/members/project/src/components/members/LoginForm.tsx +165 -0
- package/skills/wix-headless-templates/members/project/src/components/members/MemberMenu.tsx +78 -0
- package/skills/wix-headless-templates/members/project/src/components/members/RequireAuth.tsx +47 -0
- package/skills/wix-headless-templates/members/project/src/hooks/members/useMember.ts +67 -0
- package/skills/wix-headless-templates/members/project/src/layouts/Layout.astro +22 -0
- package/skills/wix-headless-templates/members/project/src/layouts/SiteLayout.astro +42 -0
- package/skills/wix-headless-templates/members/project/src/pages/account.astro +9 -0
- package/skills/wix-headless-templates/members/project/src/pages/index.astro +8 -0
- package/skills/wix-headless-templates/members/project/src/pages/login.astro +11 -0
- package/skills/wix-headless-templates/members/project/src/styles/global.css +57 -0
- package/skills/wix-headless-templates/members/project/src/wix/config.ts +16 -0
- package/skills/wix-headless-templates/members/project/src/wix/media.ts +106 -0
- package/skills/wix-headless-templates/members/project/src/wix/members/auth-core.ts +160 -0
- package/skills/wix-headless-templates/members/project/src/wix/members/auth.ts +117 -0
- package/skills/wix-headless-templates/members/project/src/wix/members/client.ts +27 -0
- package/skills/wix-headless-templates/members/project/src/wix/members/member-store.ts +133 -0
- package/skills/wix-headless-templates/members/project/src/wix/members/members-core.ts +43 -0
- package/skills/wix-headless-templates/members/project/src/wix/members/members.ts +29 -0
- package/skills/wix-headless-templates/members/project/src/wix/members/types.ts +21 -0
- package/skills/wix-headless-templates/members/project/src/wix/money.ts +24 -0
- package/skills/wix-headless-templates/members/project/src/wix/sdk.ts +89 -0
- package/skills/wix-headless-templates/members/project/tsconfig.json +5 -0
- package/skills/wix-headless-templates/members/rest/auth.ts +224 -0
- package/skills/wix-headless-templates/members/rest/members.ts +26 -0
- package/skills/wix-headless-templates/members/seed/SEED.md +39 -0
- package/skills/wix-headless-templates/members/seed/read-site.mjs +15 -0
- package/skills/wix-headless-templates/members/seed/seed-members.mjs +91 -0
- package/skills/wix-headless-templates/portfolio/INSTRUCTIONS.md +315 -0
- package/skills/wix-headless-templates/portfolio/app/components/portfolio/CollectionProjectsView.tsx +110 -0
- package/skills/wix-headless-templates/portfolio/app/components/portfolio/CollectionsView.tsx +90 -0
- package/skills/wix-headless-templates/portfolio/app/components/portfolio/GalleryMedia.tsx +35 -0
- package/skills/wix-headless-templates/portfolio/app/components/portfolio/ProjectDetailView.tsx +85 -0
- package/skills/wix-headless-templates/portfolio/app/hooks/portfolio/useCollectionProjects.ts +32 -0
- package/skills/wix-headless-templates/portfolio/app/hooks/portfolio/useCollections.ts +21 -0
- package/skills/wix-headless-templates/portfolio/app/hooks/portfolio/useProjectDetail.ts +31 -0
- package/skills/wix-headless-templates/portfolio/app/wix/portfolio/collection-projects-store.ts +82 -0
- package/skills/wix-headless-templates/portfolio/app/wix/portfolio/collections-store.ts +58 -0
- package/skills/wix-headless-templates/portfolio/app/wix/portfolio/portfolio-core.ts +177 -0
- package/skills/wix-headless-templates/portfolio/app/wix/portfolio/portfolio.ts +78 -0
- package/skills/wix-headless-templates/portfolio/app/wix/portfolio/project-detail-store.ts +81 -0
- package/skills/wix-headless-templates/portfolio/app/wix/portfolio/types.ts +55 -0
- package/skills/wix-headless-templates/portfolio/app-astro/layouts/SiteLayout.astro +40 -0
- package/skills/wix-headless-templates/portfolio/app-astro/pages/portfolio/[slug].astro +30 -0
- package/skills/wix-headless-templates/portfolio/app-astro/pages/portfolio.astro +21 -0
- package/skills/wix-headless-templates/portfolio/app-astro/pages/projects/[slug].astro +29 -0
- package/skills/wix-headless-templates/portfolio/project/README.md +15 -0
- package/skills/wix-headless-templates/portfolio/project/astro.config.mjs +22 -0
- package/skills/wix-headless-templates/portfolio/project/package-lock.json +8760 -0
- package/skills/wix-headless-templates/portfolio/project/package.json +37 -0
- package/skills/wix-headless-templates/portfolio/project/public/favicon.svg +9 -0
- package/skills/wix-headless-templates/portfolio/project/src/assets/astro.svg +1 -0
- package/skills/wix-headless-templates/portfolio/project/src/assets/background.svg +1 -0
- package/skills/wix-headless-templates/portfolio/project/src/assets/wix.svg +18 -0
- package/skills/wix-headless-templates/portfolio/project/src/components/Hero.astro +77 -0
- package/skills/wix-headless-templates/portfolio/project/src/components/Welcome.astro +95 -0
- package/skills/wix-headless-templates/portfolio/project/src/components/portfolio/CollectionProjectsView.tsx +110 -0
- package/skills/wix-headless-templates/portfolio/project/src/components/portfolio/CollectionsView.tsx +90 -0
- package/skills/wix-headless-templates/portfolio/project/src/components/portfolio/GalleryMedia.tsx +35 -0
- package/skills/wix-headless-templates/portfolio/project/src/components/portfolio/ProjectDetailView.tsx +85 -0
- package/skills/wix-headless-templates/portfolio/project/src/hooks/portfolio/useCollectionProjects.ts +32 -0
- package/skills/wix-headless-templates/portfolio/project/src/hooks/portfolio/useCollections.ts +21 -0
- package/skills/wix-headless-templates/portfolio/project/src/hooks/portfolio/useProjectDetail.ts +31 -0
- package/skills/wix-headless-templates/portfolio/project/src/layouts/Layout.astro +22 -0
- package/skills/wix-headless-templates/portfolio/project/src/layouts/SiteLayout.astro +40 -0
- package/skills/wix-headless-templates/portfolio/project/src/pages/index.astro +8 -0
- package/skills/wix-headless-templates/portfolio/project/src/pages/portfolio/[slug].astro +30 -0
- package/skills/wix-headless-templates/portfolio/project/src/pages/portfolio.astro +21 -0
- package/skills/wix-headless-templates/portfolio/project/src/pages/projects/[slug].astro +29 -0
- package/skills/wix-headless-templates/portfolio/project/src/styles/global.css +57 -0
- package/skills/wix-headless-templates/portfolio/project/src/wix/config.ts +16 -0
- package/skills/wix-headless-templates/portfolio/project/src/wix/media.ts +106 -0
- package/skills/wix-headless-templates/portfolio/project/src/wix/money.ts +24 -0
- package/skills/wix-headless-templates/portfolio/project/src/wix/portfolio/collection-projects-store.ts +82 -0
- package/skills/wix-headless-templates/portfolio/project/src/wix/portfolio/collections-store.ts +58 -0
- package/skills/wix-headless-templates/portfolio/project/src/wix/portfolio/portfolio-core.ts +177 -0
- package/skills/wix-headless-templates/portfolio/project/src/wix/portfolio/portfolio.ts +78 -0
- package/skills/wix-headless-templates/portfolio/project/src/wix/portfolio/project-detail-store.ts +81 -0
- package/skills/wix-headless-templates/portfolio/project/src/wix/portfolio/types.ts +55 -0
- package/skills/wix-headless-templates/portfolio/project/src/wix/sdk.ts +89 -0
- package/skills/wix-headless-templates/portfolio/project/tsconfig.json +5 -0
- package/skills/wix-headless-templates/portfolio/rest/portfolio.ts +75 -0
- package/skills/wix-headless-templates/portfolio/seed/SEED.md +86 -0
- package/skills/wix-headless-templates/portfolio/seed/read-site.mjs +20 -0
- package/skills/wix-headless-templates/portfolio/seed/seed-portfolio.mjs +253 -0
- package/skills/wix-headless-templates/pricing-plans/INSTRUCTIONS.md +376 -0
- package/skills/wix-headless-templates/pricing-plans/app/components/pricing-plans/PlanDetailView.tsx +54 -0
- package/skills/wix-headless-templates/pricing-plans/app/components/pricing-plans/PlansView.tsx +108 -0
- package/skills/wix-headless-templates/pricing-plans/app/components/pricing-plans/RequirePlan.tsx +87 -0
- package/skills/wix-headless-templates/pricing-plans/app/components/pricing-plans/SubscribeButton.tsx +41 -0
- package/skills/wix-headless-templates/pricing-plans/app/hooks/pricing-plans/usePlanAccess.ts +31 -0
- package/skills/wix-headless-templates/pricing-plans/app/hooks/pricing-plans/usePlanPurchase.ts +16 -0
- package/skills/wix-headless-templates/pricing-plans/app/hooks/pricing-plans/usePlans.ts +22 -0
- package/skills/wix-headless-templates/pricing-plans/app/wix/pricing-plans/plan-access-core.ts +29 -0
- package/skills/wix-headless-templates/pricing-plans/app/wix/pricing-plans/plan-access-store.ts +92 -0
- package/skills/wix-headless-templates/pricing-plans/app/wix/pricing-plans/plan-access.ts +37 -0
- package/skills/wix-headless-templates/pricing-plans/app/wix/pricing-plans/plan-purchase-store.ts +54 -0
- package/skills/wix-headless-templates/pricing-plans/app/wix/pricing-plans/plans-core.ts +212 -0
- package/skills/wix-headless-templates/pricing-plans/app/wix/pricing-plans/plans-store.ts +64 -0
- package/skills/wix-headless-templates/pricing-plans/app/wix/pricing-plans/plans.ts +54 -0
- package/skills/wix-headless-templates/pricing-plans/app/wix/pricing-plans/purchase-core.ts +43 -0
- package/skills/wix-headless-templates/pricing-plans/app/wix/pricing-plans/purchase.ts +22 -0
- package/skills/wix-headless-templates/pricing-plans/app/wix/pricing-plans/types.ts +52 -0
- package/skills/wix-headless-templates/pricing-plans/app-astro/layouts/SiteLayout.astro +41 -0
- package/skills/wix-headless-templates/pricing-plans/app-astro/pages/plans/[slug].astro +43 -0
- package/skills/wix-headless-templates/pricing-plans/app-astro/pages/plans.astro +21 -0
- package/skills/wix-headless-templates/pricing-plans/project/README.md +15 -0
- package/skills/wix-headless-templates/pricing-plans/project/astro.config.mjs +22 -0
- package/skills/wix-headless-templates/pricing-plans/project/package-lock.json +9799 -0
- package/skills/wix-headless-templates/pricing-plans/project/package.json +38 -0
- package/skills/wix-headless-templates/pricing-plans/project/public/favicon.svg +9 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/assets/astro.svg +1 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/assets/background.svg +1 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/assets/wix.svg +18 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/components/Hero.astro +77 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/components/Welcome.astro +95 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/components/pricing-plans/PlanDetailView.tsx +54 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/components/pricing-plans/PlansView.tsx +108 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/components/pricing-plans/RequirePlan.tsx +87 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/components/pricing-plans/SubscribeButton.tsx +41 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/hooks/pricing-plans/usePlanAccess.ts +31 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/hooks/pricing-plans/usePlanPurchase.ts +16 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/hooks/pricing-plans/usePlans.ts +22 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/layouts/Layout.astro +22 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/layouts/SiteLayout.astro +41 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/pages/index.astro +8 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/pages/plans/[slug].astro +43 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/pages/plans.astro +21 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/styles/global.css +57 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/wix/config.ts +16 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/wix/media.ts +106 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/wix/money.ts +24 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/wix/pricing-plans/plan-access-core.ts +29 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/wix/pricing-plans/plan-access-store.ts +92 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/wix/pricing-plans/plan-access.ts +37 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/wix/pricing-plans/plan-purchase-store.ts +54 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/wix/pricing-plans/plans-core.ts +212 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/wix/pricing-plans/plans-store.ts +64 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/wix/pricing-plans/plans.ts +54 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/wix/pricing-plans/purchase-core.ts +43 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/wix/pricing-plans/purchase.ts +22 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/wix/pricing-plans/types.ts +52 -0
- package/skills/wix-headless-templates/pricing-plans/project/src/wix/sdk.ts +89 -0
- package/skills/wix-headless-templates/pricing-plans/project/tsconfig.json +5 -0
- package/skills/wix-headless-templates/pricing-plans/rest/plan-access.ts +31 -0
- package/skills/wix-headless-templates/pricing-plans/rest/plans.ts +58 -0
- package/skills/wix-headless-templates/pricing-plans/rest/purchase.ts +20 -0
- package/skills/wix-headless-templates/pricing-plans/seed/SEED.md +93 -0
- package/skills/wix-headless-templates/pricing-plans/seed/read-site.mjs +22 -0
- package/skills/wix-headless-templates/pricing-plans/seed/seed-pricing-plans.mjs +301 -0
- package/skills/wix-headless-templates/rentals/INSTRUCTIONS.md +309 -0
- package/skills/wix-headless-templates/rentals/app/components/rentals/RentalBookingView.tsx +195 -0
- package/skills/wix-headless-templates/rentals/app/components/rentals/RentalsView.tsx +89 -0
- package/skills/wix-headless-templates/rentals/app/hooks/rentals/useRentalFlow.ts +31 -0
- package/skills/wix-headless-templates/rentals/app/hooks/rentals/useRentals.ts +23 -0
- package/skills/wix-headless-templates/rentals/app/wix/rentals/rental-flow-store.ts +283 -0
- package/skills/wix-headless-templates/rentals/app/wix/rentals/rentals-core.ts +435 -0
- package/skills/wix-headless-templates/rentals/app/wix/rentals/rentals-store.ts +112 -0
- package/skills/wix-headless-templates/rentals/app/wix/rentals/rentals.ts +173 -0
- package/skills/wix-headless-templates/rentals/app/wix/rentals/types.ts +113 -0
- package/skills/wix-headless-templates/rentals/app-astro/layouts/SiteLayout.astro +40 -0
- package/skills/wix-headless-templates/rentals/app-astro/pages/rentals/[slug].astro +81 -0
- package/skills/wix-headless-templates/rentals/app-astro/pages/rentals.astro +24 -0
- package/skills/wix-headless-templates/rentals/project/README.md +15 -0
- package/skills/wix-headless-templates/rentals/project/astro.config.mjs +22 -0
- package/skills/wix-headless-templates/rentals/project/package-lock.json +10545 -0
- package/skills/wix-headless-templates/rentals/project/package.json +40 -0
- package/skills/wix-headless-templates/rentals/project/public/favicon.svg +9 -0
- package/skills/wix-headless-templates/rentals/project/src/assets/astro.svg +1 -0
- package/skills/wix-headless-templates/rentals/project/src/assets/background.svg +1 -0
- package/skills/wix-headless-templates/rentals/project/src/assets/wix.svg +18 -0
- package/skills/wix-headless-templates/rentals/project/src/components/Hero.astro +77 -0
- package/skills/wix-headless-templates/rentals/project/src/components/Welcome.astro +95 -0
- package/skills/wix-headless-templates/rentals/project/src/components/rentals/RentalBookingView.tsx +195 -0
- package/skills/wix-headless-templates/rentals/project/src/components/rentals/RentalsView.tsx +89 -0
- package/skills/wix-headless-templates/rentals/project/src/hooks/rentals/useRentalFlow.ts +31 -0
- package/skills/wix-headless-templates/rentals/project/src/hooks/rentals/useRentals.ts +23 -0
- package/skills/wix-headless-templates/rentals/project/src/layouts/Layout.astro +22 -0
- package/skills/wix-headless-templates/rentals/project/src/layouts/SiteLayout.astro +40 -0
- package/skills/wix-headless-templates/rentals/project/src/pages/index.astro +8 -0
- package/skills/wix-headless-templates/rentals/project/src/pages/rentals/[slug].astro +81 -0
- package/skills/wix-headless-templates/rentals/project/src/pages/rentals.astro +24 -0
- package/skills/wix-headless-templates/rentals/project/src/styles/global.css +57 -0
- package/skills/wix-headless-templates/rentals/project/src/wix/config.ts +16 -0
- package/skills/wix-headless-templates/rentals/project/src/wix/media.ts +106 -0
- package/skills/wix-headless-templates/rentals/project/src/wix/money.ts +24 -0
- package/skills/wix-headless-templates/rentals/project/src/wix/rentals/rental-flow-store.ts +283 -0
- package/skills/wix-headless-templates/rentals/project/src/wix/rentals/rentals-core.ts +435 -0
- package/skills/wix-headless-templates/rentals/project/src/wix/rentals/rentals-store.ts +112 -0
- package/skills/wix-headless-templates/rentals/project/src/wix/rentals/rentals.ts +173 -0
- package/skills/wix-headless-templates/rentals/project/src/wix/rentals/types.ts +113 -0
- package/skills/wix-headless-templates/rentals/project/src/wix/sdk.ts +89 -0
- package/skills/wix-headless-templates/rentals/project/tsconfig.json +5 -0
- package/skills/wix-headless-templates/rentals/rest/rentals.ts +153 -0
- package/skills/wix-headless-templates/rentals/seed/SEED.md +95 -0
- package/skills/wix-headless-templates/rentals/seed/read-site.mjs +34 -0
- package/skills/wix-headless-templates/rentals/seed/seed-rentals.mjs +321 -0
- package/skills/wix-headless-templates/restaurants/INSTRUCTIONS.md +468 -0
- package/skills/wix-headless-templates/restaurants/app/components/restaurants/MenuView.tsx +257 -0
- package/skills/wix-headless-templates/restaurants/app/components/restaurants/OrderCartButton.tsx +26 -0
- package/skills/wix-headless-templates/restaurants/app/components/restaurants/OrderCartDrawer.tsx +121 -0
- package/skills/wix-headless-templates/restaurants/app/components/restaurants/ReservationView.tsx +212 -0
- package/skills/wix-headless-templates/restaurants/app/hooks/restaurants/useMenus.ts +34 -0
- package/skills/wix-headless-templates/restaurants/app/hooks/restaurants/useOrderCart.ts +52 -0
- package/skills/wix-headless-templates/restaurants/app/hooks/restaurants/useReservation.ts +49 -0
- package/skills/wix-headless-templates/restaurants/app/wix/restaurants/menu-core.ts +333 -0
- package/skills/wix-headless-templates/restaurants/app/wix/restaurants/menu-store.ts +89 -0
- package/skills/wix-headless-templates/restaurants/app/wix/restaurants/menu.ts +109 -0
- package/skills/wix-headless-templates/restaurants/app/wix/restaurants/order-store.ts +141 -0
- package/skills/wix-headless-templates/restaurants/app/wix/restaurants/ordering-core.ts +287 -0
- package/skills/wix-headless-templates/restaurants/app/wix/restaurants/ordering.ts +237 -0
- package/skills/wix-headless-templates/restaurants/app/wix/restaurants/reservation-store.ts +279 -0
- package/skills/wix-headless-templates/restaurants/app/wix/restaurants/reservations-core.ts +218 -0
- package/skills/wix-headless-templates/restaurants/app/wix/restaurants/reservations.ts +109 -0
- package/skills/wix-headless-templates/restaurants/app/wix/restaurants/time-core.ts +118 -0
- package/skills/wix-headless-templates/restaurants/app/wix/restaurants/types.ts +337 -0
- package/skills/wix-headless-templates/restaurants/app-astro/layouts/SiteLayout.astro +47 -0
- package/skills/wix-headless-templates/restaurants/app-astro/pages/menu.astro +22 -0
- package/skills/wix-headless-templates/restaurants/app-astro/pages/reservations.astro +12 -0
- package/skills/wix-headless-templates/restaurants/project/README.md +15 -0
- package/skills/wix-headless-templates/restaurants/project/astro.config.mjs +22 -0
- package/skills/wix-headless-templates/restaurants/project/package-lock.json +11038 -0
- package/skills/wix-headless-templates/restaurants/project/package.json +40 -0
- package/skills/wix-headless-templates/restaurants/project/public/favicon.svg +9 -0
- package/skills/wix-headless-templates/restaurants/project/src/assets/astro.svg +1 -0
- package/skills/wix-headless-templates/restaurants/project/src/assets/background.svg +1 -0
- package/skills/wix-headless-templates/restaurants/project/src/assets/wix.svg +18 -0
- package/skills/wix-headless-templates/restaurants/project/src/components/Hero.astro +77 -0
- package/skills/wix-headless-templates/restaurants/project/src/components/Welcome.astro +95 -0
- package/skills/wix-headless-templates/restaurants/project/src/components/restaurants/MenuView.tsx +257 -0
- package/skills/wix-headless-templates/restaurants/project/src/components/restaurants/OrderCartButton.tsx +26 -0
- package/skills/wix-headless-templates/restaurants/project/src/components/restaurants/OrderCartDrawer.tsx +121 -0
- package/skills/wix-headless-templates/restaurants/project/src/components/restaurants/ReservationView.tsx +212 -0
- package/skills/wix-headless-templates/restaurants/project/src/hooks/restaurants/useMenus.ts +34 -0
- package/skills/wix-headless-templates/restaurants/project/src/hooks/restaurants/useOrderCart.ts +52 -0
- package/skills/wix-headless-templates/restaurants/project/src/hooks/restaurants/useReservation.ts +49 -0
- package/skills/wix-headless-templates/restaurants/project/src/layouts/Layout.astro +22 -0
- package/skills/wix-headless-templates/restaurants/project/src/layouts/SiteLayout.astro +47 -0
- package/skills/wix-headless-templates/restaurants/project/src/pages/index.astro +8 -0
- package/skills/wix-headless-templates/restaurants/project/src/pages/menu.astro +22 -0
- package/skills/wix-headless-templates/restaurants/project/src/pages/reservations.astro +12 -0
- package/skills/wix-headless-templates/restaurants/project/src/styles/global.css +57 -0
- package/skills/wix-headless-templates/restaurants/project/src/wix/config.ts +16 -0
- package/skills/wix-headless-templates/restaurants/project/src/wix/media.ts +106 -0
- package/skills/wix-headless-templates/restaurants/project/src/wix/money.ts +24 -0
- package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/menu-core.ts +333 -0
- package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/menu-store.ts +89 -0
- package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/menu.ts +109 -0
- package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/order-store.ts +141 -0
- package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/ordering-core.ts +287 -0
- package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/ordering.ts +237 -0
- package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/reservation-store.ts +279 -0
- package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/reservations-core.ts +218 -0
- package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/reservations.ts +109 -0
- package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/time-core.ts +118 -0
- package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/types.ts +337 -0
- package/skills/wix-headless-templates/restaurants/project/src/wix/sdk.ts +89 -0
- package/skills/wix-headless-templates/restaurants/project/tsconfig.json +5 -0
- package/skills/wix-headless-templates/restaurants/rest/menu.ts +96 -0
- package/skills/wix-headless-templates/restaurants/rest/ordering.ts +222 -0
- package/skills/wix-headless-templates/restaurants/rest/reservations.ts +102 -0
- package/skills/wix-headless-templates/restaurants/seed/SEED.md +118 -0
- package/skills/wix-headless-templates/restaurants/seed/read-site.mjs +25 -0
- package/skills/wix-headless-templates/restaurants/seed/seed-restaurants.mjs +577 -0
- package/skills/wix-headless-templates/shared/CONTENT.md +22 -0
- package/skills/wix-headless-templates/shared/CUSTOM_OPERATIONS.md +100 -0
- package/skills/wix-headless-templates/shared/DESIGN.md +37 -0
- package/skills/wix-headless-templates/shared/SUPPLIED-CONTENT.md +27 -0
- package/skills/wix-headless-templates/shared/app/styles/global.css +57 -0
- package/skills/wix-headless-templates/shared/app/wix/config.ts +16 -0
- package/skills/wix-headless-templates/shared/app/wix/media.ts +106 -0
- package/skills/wix-headless-templates/shared/app/wix/money.ts +24 -0
- package/skills/wix-headless-templates/shared/app/wix/sdk.ts +89 -0
- package/skills/wix-headless-templates/shared/capabilities/media-upload/app/wix/media-upload/client.ts +46 -0
- package/skills/wix-headless-templates/shared/capabilities/media-upload/app-astro/pages/api/wix/media-upload.ts +69 -0
- package/skills/wix-headless-templates/shared/capabilities/site-search/INSTRUCTIONS.md +194 -0
- package/skills/wix-headless-templates/shared/capabilities/site-search/app/components/site-search/SearchBox.tsx +136 -0
- package/skills/wix-headless-templates/shared/capabilities/site-search/app/components/site-search/SearchHit.tsx +50 -0
- package/skills/wix-headless-templates/shared/capabilities/site-search/app/components/site-search/SearchResults.tsx +300 -0
- package/skills/wix-headless-templates/shared/capabilities/site-search/app/hooks/site-search/useSearch.ts +31 -0
- package/skills/wix-headless-templates/shared/capabilities/site-search/app/hooks/site-search/useSuggest.ts +26 -0
- package/skills/wix-headless-templates/shared/capabilities/site-search/app/wix/site-search/search-core.ts +520 -0
- package/skills/wix-headless-templates/shared/capabilities/site-search/app/wix/site-search/search-store.ts +235 -0
- package/skills/wix-headless-templates/shared/capabilities/site-search/app/wix/site-search/search.ts +80 -0
- package/skills/wix-headless-templates/shared/capabilities/site-search/app/wix/site-search/suggest-store.ts +178 -0
- package/skills/wix-headless-templates/shared/capabilities/site-search/app/wix/site-search/types.ts +158 -0
- package/skills/wix-headless-templates/shared/capabilities/site-search/app-astro/pages/search.astro +33 -0
- package/skills/wix-headless-templates/shared/capabilities/site-search/rest/search.ts +82 -0
- package/skills/wix-headless-templates/shared/capabilities/site-search/seed/install.mjs +43 -0
- package/skills/wix-headless-templates/shared/rest/client.ts +155 -0
- package/skills/wix-headless-templates/shared/rest/config.ts +4 -0
- package/skills/wix-headless-templates/shared/rest/media.ts +92 -0
- package/skills/wix-headless-templates/shared/seed/images.mjs +183 -0
- package/skills/wix-headless-templates/shared/seed/read-site.mjs +97 -0
- package/skills/wix-headless-templates/shared/seed/site-context.mjs +70 -0
- package/skills/wix-headless-templates/shared/seed/site.mjs +48 -0
- package/skills/wix-headless-templates/shared/seed/wix-cli.mjs +44 -0
- package/skills/wix-headless-templates/storefront/INSTRUCTIONS.md +685 -0
- package/skills/wix-headless-templates/storefront/app/components/storefront/CartButton.tsx +26 -0
- package/skills/wix-headless-templates/storefront/app/components/storefront/CartDrawer.tsx +239 -0
- package/skills/wix-headless-templates/storefront/app/components/storefront/FilterPanel.tsx +267 -0
- package/skills/wix-headless-templates/storefront/app/components/storefront/OptionPicker.tsx +171 -0
- package/skills/wix-headless-templates/storefront/app/components/storefront/QuickAdd.tsx +148 -0
- package/skills/wix-headless-templates/storefront/app/hooks/storefront/useCart.ts +59 -0
- package/skills/wix-headless-templates/storefront/app/hooks/storefront/useProductDetail.ts +42 -0
- package/skills/wix-headless-templates/storefront/app/hooks/storefront/useShop.ts +34 -0
- package/skills/wix-headless-templates/storefront/app/wix/storefront/cart-core.ts +220 -0
- package/skills/wix-headless-templates/storefront/app/wix/storefront/cart-store.ts +134 -0
- package/skills/wix-headless-templates/storefront/app/wix/storefront/cart.ts +187 -0
- package/skills/wix-headless-templates/storefront/app/wix/storefront/catalog-core.ts +698 -0
- package/skills/wix-headless-templates/storefront/app/wix/storefront/catalog.ts +260 -0
- package/skills/wix-headless-templates/storefront/app/wix/storefront/product-detail-store.ts +280 -0
- package/skills/wix-headless-templates/storefront/app/wix/storefront/shop-store.ts +341 -0
- package/skills/wix-headless-templates/storefront/app/wix/storefront/types.ts +305 -0
- package/skills/wix-headless-templates/storefront/app-astro/layouts/SiteLayout.astro +65 -0
- package/skills/wix-headless-templates/storefront/project/README.md +15 -0
- package/skills/wix-headless-templates/storefront/project/astro.config.mjs +22 -0
- package/skills/wix-headless-templates/storefront/project/package-lock.json +10786 -0
- package/skills/wix-headless-templates/storefront/project/package.json +41 -0
- package/skills/wix-headless-templates/storefront/project/public/favicon.svg +9 -0
- package/skills/wix-headless-templates/storefront/project/src/assets/astro.svg +1 -0
- package/skills/wix-headless-templates/storefront/project/src/assets/background.svg +1 -0
- package/skills/wix-headless-templates/storefront/project/src/assets/wix.svg +18 -0
- package/skills/wix-headless-templates/storefront/project/src/components/Hero.astro +77 -0
- package/skills/wix-headless-templates/storefront/project/src/components/Welcome.astro +95 -0
- package/skills/wix-headless-templates/storefront/project/src/components/storefront/CartButton.tsx +26 -0
- package/skills/wix-headless-templates/storefront/project/src/components/storefront/CartDrawer.tsx +239 -0
- package/skills/wix-headless-templates/storefront/project/src/components/storefront/FilterPanel.tsx +267 -0
- package/skills/wix-headless-templates/storefront/project/src/components/storefront/OptionPicker.tsx +171 -0
- package/skills/wix-headless-templates/storefront/project/src/components/storefront/QuickAdd.tsx +148 -0
- package/skills/wix-headless-templates/storefront/project/src/hooks/storefront/useCart.ts +59 -0
- package/skills/wix-headless-templates/storefront/project/src/hooks/storefront/useProductDetail.ts +42 -0
- package/skills/wix-headless-templates/storefront/project/src/hooks/storefront/useShop.ts +34 -0
- package/skills/wix-headless-templates/storefront/project/src/layouts/Layout.astro +22 -0
- package/skills/wix-headless-templates/storefront/project/src/layouts/SiteLayout.astro +65 -0
- package/skills/wix-headless-templates/storefront/project/src/pages/index.astro +8 -0
- package/skills/wix-headless-templates/storefront/project/src/styles/global.css +57 -0
- package/skills/wix-headless-templates/storefront/project/src/wix/config.ts +16 -0
- package/skills/wix-headless-templates/storefront/project/src/wix/media.ts +106 -0
- package/skills/wix-headless-templates/storefront/project/src/wix/money.ts +24 -0
- package/skills/wix-headless-templates/storefront/project/src/wix/sdk.ts +89 -0
- package/skills/wix-headless-templates/storefront/project/src/wix/storefront/cart-core.ts +220 -0
- package/skills/wix-headless-templates/storefront/project/src/wix/storefront/cart-store.ts +134 -0
- package/skills/wix-headless-templates/storefront/project/src/wix/storefront/cart.ts +187 -0
- package/skills/wix-headless-templates/storefront/project/src/wix/storefront/catalog-core.ts +698 -0
- package/skills/wix-headless-templates/storefront/project/src/wix/storefront/catalog.ts +260 -0
- package/skills/wix-headless-templates/storefront/project/src/wix/storefront/product-detail-store.ts +280 -0
- package/skills/wix-headless-templates/storefront/project/src/wix/storefront/shop-store.ts +341 -0
- package/skills/wix-headless-templates/storefront/project/src/wix/storefront/types.ts +305 -0
- package/skills/wix-headless-templates/storefront/project/tsconfig.json +5 -0
- package/skills/wix-headless-templates/storefront/rest/cart.ts +183 -0
- package/skills/wix-headless-templates/storefront/rest/catalog.ts +267 -0
- package/skills/wix-headless-templates/storefront/seed/SEED.md +169 -0
- package/skills/wix-headless-templates/storefront/seed/read-site.mjs +38 -0
- package/skills/wix-headless-templates/storefront/seed/seed-store.mjs +839 -0
- package/skills/wix-manage/SKILL.md +11 -7
- package/skills/wix-manage/references/bookings/end-to-end-booking-flow.md +1 -1
- package/skills/wix-manage/references/custom-apps/use-app-skills-and-app-tools.md +206 -0
- package/skills/wix-manage/references/site-properties/change-payment-currency-site-properties.md +17 -24
- package/skills/wix-manage/references/sites/create-headless-site.md +2 -0
- package/skills/wix-manage/references/sites/upload-static-site.md +262 -171
- package/skills/wix-manage/references/stores/update-product-with-options.md +1 -1
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_COLLECTION.md +0 -184
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_ROUTER.md +0 -204
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_SETTINGS.md +0 -44
- package/skills/wix-headless/entry/bootstrap.mjs +0 -156
- package/skills/wix-headless/entry/skill.md +0 -78
- package/skills/wix-headless-kit/cold-start/bootstrap.mjs +0 -156
- package/skills/wix-headless-kit/cold-start/cold-start.md +0 -111
- package/skills/wix-manage/references/bookings/booking-system-integration-gaps.md +0 -423
|
@@ -0,0 +1,671 @@
|
|
|
1
|
+
// Form-schema rules and DTO mapping — transport-agnostic, imported by BOTH transports: ./forms.ts
|
|
2
|
+
// (the SDK, managed Astro and React) and the REST twin in templates/forms/rest/forms.ts (fetch, a
|
|
3
|
+
// static site or a port to another language). Every rule about how a raw Form Schemas v4 entity
|
|
4
|
+
// flattens into a FormDto lives HERE, once — and so does the evaluation of the owner's conditional
|
|
5
|
+
// rules, which the store re-runs on every value change. A raw form may come from the SDK (`_id`) or
|
|
6
|
+
// from REST (`id`); the mappers accept both. Imports are type-only so a strip to JS emits no imports.
|
|
7
|
+
// docs: https://dev.wix.com/docs/api-reference/crm/forms/form-schemas/about-form-fields.md
|
|
8
|
+
import { ADDRESS_TEMPLATES } from "./address-templates.generated";
|
|
9
|
+
import type {
|
|
10
|
+
FormAddressPart,
|
|
11
|
+
FormChoice,
|
|
12
|
+
FormControl,
|
|
13
|
+
FormDto,
|
|
14
|
+
FormFieldDto,
|
|
15
|
+
FormRule,
|
|
16
|
+
FormStep,
|
|
17
|
+
FormSuccess,
|
|
18
|
+
FormValidation,
|
|
19
|
+
FormValues,
|
|
20
|
+
RuleCondition,
|
|
21
|
+
RuleEffect,
|
|
22
|
+
AddressOverrides,
|
|
23
|
+
} from "./types";
|
|
24
|
+
|
|
25
|
+
/** A raw Form Schemas v4 entity as either transport returns it. */
|
|
26
|
+
export type Raw = Record<string, any>;
|
|
27
|
+
/** Media value + size → https URL. Injected: the SDK transport scales through @wix/sdk, REST through the URL form. */
|
|
28
|
+
export type ImgSrc = (value: any, width: number, height: number) => string;
|
|
29
|
+
|
|
30
|
+
/** The Wix Forms app namespace. Every form this vertical touches lives here. */
|
|
31
|
+
export const FORMS_NAMESPACE = "wix.form_app.form";
|
|
32
|
+
|
|
33
|
+
const id = (raw: Raw | undefined): string => raw?._id ?? raw?.id ?? "";
|
|
34
|
+
|
|
35
|
+
// A field's settings nest TWO levels deep, under blocks named after its own enums:
|
|
36
|
+
// inputOptions.<inputType block>.<componentType block>.label
|
|
37
|
+
// These tables resolve those names. Spelling them at a call site is one typo away from
|
|
38
|
+
// silently reading back no label at all — which is the whole reason this file exists.
|
|
39
|
+
const INPUT_BLOCK: Record<string, string> = {
|
|
40
|
+
STRING: "stringOptions",
|
|
41
|
+
NUMBER: "numberOptions",
|
|
42
|
+
BOOLEAN: "booleanOptions",
|
|
43
|
+
ARRAY: "arrayOptions",
|
|
44
|
+
ADDRESS: "addressOptions",
|
|
45
|
+
WIX_FILE: "wixFileOptions",
|
|
46
|
+
PAYMENT: "paymentOptions",
|
|
47
|
+
SCHEDULING: "schedulingOptions",
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const COMPONENT_BLOCK: Record<string, string> = {
|
|
51
|
+
TEXT_INPUT: "textInputOptions",
|
|
52
|
+
PASSWORD: "passwordOptions",
|
|
53
|
+
NUMBER_INPUT: "numberInputOptions",
|
|
54
|
+
RATING_INPUT: "ratingInputOptions",
|
|
55
|
+
PHONE_INPUT: "phoneInputOptions",
|
|
56
|
+
DATE_INPUT: "dateInputOptions",
|
|
57
|
+
DATE_PICKER: "datePickerOptions",
|
|
58
|
+
DATE_TIME: "dateTimeOptions",
|
|
59
|
+
TIME_INPUT: "timeInputOptions",
|
|
60
|
+
CHECKBOX: "checkboxOptions",
|
|
61
|
+
CHECKBOX_GROUP: "checkboxGroupOptions",
|
|
62
|
+
RADIO_GROUP: "radioGroupOptions",
|
|
63
|
+
DROPDOWN: "dropdownOptions",
|
|
64
|
+
TAGS: "tagsOptions",
|
|
65
|
+
MULTILINE_ADDRESS: "multilineAddressOptions",
|
|
66
|
+
FILE_UPLOAD: "fileUploadOptions",
|
|
67
|
+
SIGNATURE: "signatureOptions",
|
|
68
|
+
FIXED_PAYMENT: "fixedPaymentOptions",
|
|
69
|
+
PAYMENT_INPUT: "paymentInputOptions",
|
|
70
|
+
DONATION_INPUT: "donationInputOptions",
|
|
71
|
+
APPOINTMENT: "appointmentOptions",
|
|
72
|
+
SERVICES_DROPDOWN: "servicesDropdownOptions",
|
|
73
|
+
SERVICES_CHECKBOX_GROUP: "servicesCheckboxGroupOptions",
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// componentType → the control to render. Several field kinds share one component (short and
|
|
77
|
+
// long answer are both TEXT_INPUT), so `format`, `identifier` and `inputType` refine it below.
|
|
78
|
+
const CONTROL: Record<string, FormControl> = {
|
|
79
|
+
TEXT_INPUT: "text",
|
|
80
|
+
PASSWORD: "password",
|
|
81
|
+
NUMBER_INPUT: "number",
|
|
82
|
+
RATING_INPUT: "rating",
|
|
83
|
+
PHONE_INPUT: "phone",
|
|
84
|
+
DATE_INPUT: "date",
|
|
85
|
+
DATE_PICKER: "date",
|
|
86
|
+
DATE_TIME: "datetime",
|
|
87
|
+
TIME_INPUT: "time",
|
|
88
|
+
CHECKBOX: "checkbox",
|
|
89
|
+
CHECKBOX_GROUP: "checkboxGroup",
|
|
90
|
+
RADIO_GROUP: "radio",
|
|
91
|
+
DROPDOWN: "select",
|
|
92
|
+
TAGS: "tags",
|
|
93
|
+
MULTILINE_ADDRESS: "address",
|
|
94
|
+
FILE_UPLOAD: "file",
|
|
95
|
+
SIGNATURE: "signature",
|
|
96
|
+
FIXED_PAYMENT: "payment",
|
|
97
|
+
PAYMENT_INPUT: "payment",
|
|
98
|
+
DONATION_INPUT: "payment",
|
|
99
|
+
SERVICES_DROPDOWN: "select",
|
|
100
|
+
SERVICES_CHECKBOX_GROUP: "checkboxGroup",
|
|
101
|
+
APPOINTMENT: "appointment",
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
// `uploadFileFormats` family → the <input accept> list Wix's own uploader uses (form-fields
|
|
105
|
+
// file-format.tsx). Video/image/audio are wildcard mime types; documents and archives are
|
|
106
|
+
// extension lists because their mime types are inconsistent across browsers.
|
|
107
|
+
export const FILE_FORMAT_ACCEPT: Record<string, string> = {
|
|
108
|
+
VIDEO: "video/*",
|
|
109
|
+
IMAGE: "image/*",
|
|
110
|
+
AUDIO: "audio/*",
|
|
111
|
+
DOCUMENT:
|
|
112
|
+
".ai,.cdr,.csv,.doc,.docb,.docx,.dot,.dotx,.dwg,.eps,.epub,.fla,.gpx,.ical,.icalendar,.ics,.ifb,.indd,.ipynb,.key,.kml,.kmz,.mobi,.mtf,.mtx,.numbers,.odg,.odp,.ods,.odt,.otp,.ots,.ott,.oxps,.pages,.pdf,.pdn,.pkg,.pot,.potx,.pps,.ppsx,.ppt,.pptx,.psd,.pub,.rtf,.sldx,.txt,.json,.vcf,.xcf,.xls,.xlsx,.xlt,.xltx,.xlw,.xps,.xml,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel",
|
|
113
|
+
ARCHIVE: ".zip,.rar,.tar,.tar.gz,.gz,.gzip,.jar,.7z,.fgz,.webarchive",
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Every country an address may name when the owner set no `allowedCountries` — the list Wix's
|
|
118
|
+
* own address field enumerates (form-multiline-address country-codes.ts). ISO 3166-1 alpha-2.
|
|
119
|
+
*/
|
|
120
|
+
export const COUNTRY_CODES: readonly string[] = ["AD","AE","AF","AG","AI","AL","AM","AN","AO","AQ","AR","AS","AT","AU","AW","AX","AZ","BA","BB","BD","BE","BF","BG","BH","BI","BJ","BL","BM","BN","BO","BQ","BR","BS","BT","BV","BW","BY","BZ","CA","CC","CD","CF","CG","CH","CI","CK","CL","CM","CN","CO","CR","CV","CW","CX","CY","CZ","DE","DJ","DK","DM","DO","DZ","EC","EE","EG","EH","ER","ES","ET","FI","FJ","FK","FM","FO","FR","GA","GB","GD","GE","GF","GG","GH","GI","GL","GM","GN","GP","GQ","GR","GS","GT","GU","GW","GY","HK","HM","HN","HR","HT","HU","ID","IE","IL","IM","IN","IO","IQ","IS","IT","JE","JM","JO","JP","KE","KG","KH","KI","KM","KN","KR","KW","KY","KZ","LA","LB","LC","LI","LK","LR","LS","LT","LU","LV","LY","MA","MC","MD","ME","MF","MG","MH","MK","ML","MM","MN","MO","MP","MQ","MR","MS","MT","MU","MV","MW","MX","MY","MZ","NA","NC","NE","NF","NG","NI","NL","NO","NP","NR","NU","NZ","OM","PA","PE","PF","PG","PH","PK","PL","PM","PN","PR","PS","PT","PW","PY","QA","RE","RO","RS","RU","RW","SA","SB","SC","SD","SE","SG","SH","SI","SJ","SK","SL","SM","SN","SO","SR","SS","ST","SV","SX","SZ","TC","TD","TF","TG","TH","TJ","TK","TL","TM","TN","TO","TR","TT","TV","TW","TZ","UA","UG","UM","US","UY","UZ","VA","VC","VE","VG","VI","VN","VU","WF","WS","XK","YE","YT","ZA","ZM","ZW"];
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Every subfield an address can have. WHICH ones a given address shows is per country
|
|
124
|
+
* (`addressPartsForCountry`): Wix's address field loads one of twelve templates by country, and
|
|
125
|
+
* the submission API rejects any other key as "additional properties".
|
|
126
|
+
*/
|
|
127
|
+
export const ADDRESS_SUBFIELDS = ["country", "addressLine", "addressLine2", "streetName", "streetNumber", "city", "subdivision", "postalCode"] as const;
|
|
128
|
+
|
|
129
|
+
// An enum missing from a table means Wix added a type. Say so ONCE — a silent empty block
|
|
130
|
+
// renders a field labelled by its storage key with none of its settings.
|
|
131
|
+
const warned = new Set<string>();
|
|
132
|
+
function blockName(table: Record<string, string>, key: string | undefined, what: string): string | undefined {
|
|
133
|
+
const name = key ? table[key] : undefined;
|
|
134
|
+
if (!name && key && !warned.has(what + key)) {
|
|
135
|
+
warned.add(what + key);
|
|
136
|
+
console.warn(
|
|
137
|
+
`forms: no ${what} block mapped for "${key}" — that field renders without its label or ` +
|
|
138
|
+
`options. Add it to the table in wix/forms/forms-core.ts.`,
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
return name;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Ricos rich content → plain text. Labels, descriptions, the owner's thank-you and "form closed"
|
|
146
|
+
* messages all arrive as rich content; block nodes (paragraphs, headings, list items) become
|
|
147
|
+
* lines so a multi-paragraph thank-you keeps its breaks. Links and decorations are dropped.
|
|
148
|
+
*/
|
|
149
|
+
export function plainText(label: unknown): string {
|
|
150
|
+
if (typeof label === "string") return label;
|
|
151
|
+
const nodes = (label as Raw)?.nodes;
|
|
152
|
+
if (!Array.isArray(nodes)) return "";
|
|
153
|
+
const BLOCK = /^(PARAGRAPH|HEADING|LIST_ITEM|BLOCKQUOTE|CODE_BLOCK)$/;
|
|
154
|
+
const walk = (list: Raw[]): string =>
|
|
155
|
+
list
|
|
156
|
+
.map((n) => (n?.textData?.text ?? "") + (Array.isArray(n?.nodes) ? walk(n.nodes) : "") + (BLOCK.test(n?.type ?? "") ? "\n" : ""))
|
|
157
|
+
.join("");
|
|
158
|
+
return walk(nodes).replace(/\n{3,}/g, "\n\n").trim();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** `postalCode` → "Postal code". A subfield is a key; the schema carries no label for it. */
|
|
162
|
+
export function humanizeSub(sub: string): string {
|
|
163
|
+
const words = sub.replace(/([A-Z])|(\d+)/g, " $1$2").toLowerCase().trim();
|
|
164
|
+
return words.charAt(0).toUpperCase() + words.slice(1);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* "US" → "United States". From the shipped data first — the same string on the server and in the
|
|
169
|
+
* browser, which Intl.DisplayNames does not guarantee (Node and Chrome spell Hong Kong, Macao,
|
|
170
|
+
* Palestine and the Falklands differently, and a server-rendered list the browser disagrees with
|
|
171
|
+
* is a hydration mismatch). Intl for a code the data lacks; the code itself otherwise.
|
|
172
|
+
*/
|
|
173
|
+
export function countryName(code: string): string {
|
|
174
|
+
const known = ADDRESS_TEMPLATES.countryNames[code];
|
|
175
|
+
if (known) return known;
|
|
176
|
+
try {
|
|
177
|
+
const dn = (Intl as any).DisplayNames ? new (Intl as any).DisplayNames(["en"], { type: "region" }) : null;
|
|
178
|
+
return (dn?.of(code) as string | undefined) ?? code;
|
|
179
|
+
} catch {
|
|
180
|
+
return code;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const RELATIVE_DATE = /^\$now(?:([+-])(\d{1,2})([yMdmh]))?$/;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* A date bound or default as the schema stores it — an ISO string, or `$now`, `$now+2d`,
|
|
188
|
+
* `$now-1M` (units y M d m h; string-format-options-mapper.ts) — resolved to a static value in
|
|
189
|
+
* the field's own format: `YYYY-MM-DD` (date), `HH:mm:ss` (time), `YYYY-MM-DDTHH:mm:ss` (datetime).
|
|
190
|
+
* An ISO input is returned unchanged; anything else (an unsupported expression) is dropped.
|
|
191
|
+
*/
|
|
192
|
+
export function resolveDate(value: unknown, control: string, now: Date = new Date()): string | undefined {
|
|
193
|
+
if (typeof value !== "string" || !value) return undefined;
|
|
194
|
+
const m = value.match(RELATIVE_DATE);
|
|
195
|
+
if (!m) return /^\d{4}-\d{2}-\d{2}|^\d{2}:\d{2}/.test(value) ? value : undefined;
|
|
196
|
+
const d = new Date(now.getTime());
|
|
197
|
+
const sign = m[1] === "-" ? -1 : 1;
|
|
198
|
+
const n = m[2] ? sign * parseInt(m[2], 10) : 0;
|
|
199
|
+
switch (m[3]) {
|
|
200
|
+
case "y": d.setUTCFullYear(d.getUTCFullYear() + n); break;
|
|
201
|
+
case "M": d.setUTCMonth(d.getUTCMonth() + n); break;
|
|
202
|
+
case "d": d.setUTCDate(d.getUTCDate() + n); break;
|
|
203
|
+
case "h": d.setUTCHours(d.getUTCHours() + n); break;
|
|
204
|
+
case "m": d.setUTCMinutes(d.getUTCMinutes() + n); break;
|
|
205
|
+
}
|
|
206
|
+
const iso = d.toISOString(); // YYYY-MM-DDTHH:mm:ss.sssZ
|
|
207
|
+
if (control === "time") return iso.slice(11, 19);
|
|
208
|
+
if (control === "datetime") return iso.slice(0, 19);
|
|
209
|
+
return iso.slice(0, 10);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/** The submitted value of a choice field's free-text "Other" entry: `"<Other label>: <text>"` (radio-group-field-headless.tsx). */
|
|
213
|
+
export function otherValue(field: FormFieldDto, text: string): string {
|
|
214
|
+
return `${field.otherOption?.label ?? "Other"}: ${text}`;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** The visitor's text back out of an "Other" value, or null when the value is a listed choice. */
|
|
218
|
+
export function otherText(field: FormFieldDto, value: unknown): string | null {
|
|
219
|
+
if (!field.otherOption || typeof value !== "string" || !value) return null;
|
|
220
|
+
if (field.choices.some((c) => c.value === value)) return null;
|
|
221
|
+
const prefix = `${field.otherOption.label}: `;
|
|
222
|
+
return value.startsWith(prefix) ? value.slice(prefix.length) : value;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/** The owner's address settings, as `addressPartsForCountry` needs them. */
|
|
226
|
+
function addressOverrides(rules: Raw, component: Raw): AddressOverrides {
|
|
227
|
+
const fields: Raw = rules.fields ?? {};
|
|
228
|
+
const settings: Raw = component.fieldSettings ?? {};
|
|
229
|
+
return {
|
|
230
|
+
required: Object.fromEntries(Object.keys(fields).map((k) => [k, fields[k]?.required as boolean | undefined])),
|
|
231
|
+
show: Object.fromEntries(Object.keys(settings).map((k) => [k, settings[k]?.show as boolean | undefined])),
|
|
232
|
+
allowedCountries: Array.isArray(rules.allowedCountries) ? rules.allowedCountries.map(String) : [],
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* The subfields of an address for ONE country, in Wix's order: `country` first (Wix prepends it
|
|
238
|
+
* to every template and requires it exactly when the address is required, get-country-field.ts),
|
|
239
|
+
* then the country's template — Israel: street name, street number, city, postal code; the United
|
|
240
|
+
* States: address line, city, state, postal code — with the owner's `validation.fields` deciding
|
|
241
|
+
* requiredness and `fieldSettings` visibility over the template's defaults. A `subdivision` part
|
|
242
|
+
* carries the country's states / provinces / regions as `choices` (ISO 3166-2 codes) when Wix has
|
|
243
|
+
* them on record. No country yet → Wix's common template.
|
|
244
|
+
*/
|
|
245
|
+
export function addressPartsForCountry(country: string | undefined, o: AddressOverrides, required: boolean): FormAddressPart[] {
|
|
246
|
+
const code = country ? country.toUpperCase() : "";
|
|
247
|
+
const templateName = ADDRESS_TEMPLATES.byCountry[code] ?? ADDRESS_TEMPLATES.defaultTemplate;
|
|
248
|
+
const template = ADDRESS_TEMPLATES.templates[templateName] ?? ADDRESS_TEMPLATES.templates[ADDRESS_TEMPLATES.defaultTemplate] ?? [];
|
|
249
|
+
const allowed = o.allowedCountries.length ? o.allowedCountries : [...COUNTRY_CODES];
|
|
250
|
+
const parts: FormAddressPart[] = [{
|
|
251
|
+
sub: "country",
|
|
252
|
+
label: "Country",
|
|
253
|
+
required: o.required.country ?? required,
|
|
254
|
+
choices: allowed.map((c) => ({ value: c, label: countryName(c) })),
|
|
255
|
+
}];
|
|
256
|
+
const subdivisions = ADDRESS_TEMPLATES.subdivisions[code];
|
|
257
|
+
for (const t of template) {
|
|
258
|
+
if (!(o.show[t.sub] ?? !t.hidden)) continue;
|
|
259
|
+
const isSubdivision = t.sub === "subdivision";
|
|
260
|
+
parts.push({
|
|
261
|
+
sub: t.sub,
|
|
262
|
+
label: isSubdivision && subdivisions ? subdivisions.label : humanizeSub(t.sub),
|
|
263
|
+
required: o.required[t.sub] ?? t.required,
|
|
264
|
+
...(isSubdivision && subdivisions ? { choices: subdivisions.list.map(([k, name]) => ({ value: `${code}-${k}`, label: name })) } : {}),
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
return parts;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function addressParts(rules: Raw, component: Raw, required: boolean): FormAddressPart[] {
|
|
271
|
+
// The owner's pre-selected country when the field has one; else the common template until the
|
|
272
|
+
// visitor picks a country (the store recomputes the parts on every change).
|
|
273
|
+
const preset = component.defaultCountryConfig?.countryOptions;
|
|
274
|
+
return addressPartsForCountry(typeof preset === "string" ? preset : undefined, addressOverrides(rules, component), required);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export function toField(raw: Raw, imgSrc: ImgSrc, stepId: string): FormFieldDto {
|
|
278
|
+
const input = raw.inputOptions ?? {};
|
|
279
|
+
const inputType: string = input.inputType ?? "";
|
|
280
|
+
const optionsBlock: Raw = input[blockName(INPUT_BLOCK, inputType, "inputType") ?? ""] ?? {};
|
|
281
|
+
const componentType: string = optionsBlock.componentType ?? "";
|
|
282
|
+
const component: Raw = optionsBlock[blockName(COMPONENT_BLOCK, componentType, "componentType") ?? ""] ?? {};
|
|
283
|
+
const rules: Raw = optionsBlock.validation ?? {};
|
|
284
|
+
const identifier: string = raw.identifier ?? "";
|
|
285
|
+
const required: boolean = input.required ?? false;
|
|
286
|
+
|
|
287
|
+
let control: FormControl = CONTROL[componentType] ?? "unknown";
|
|
288
|
+
// A product list is a PAYMENT field wearing a CHECKBOX_GROUP component — typed by its
|
|
289
|
+
// component it would look like a multi-choice and be bound to an array of strings, when what
|
|
290
|
+
// it submits is a payment structure. The input type wins.
|
|
291
|
+
if (inputType === "PAYMENT") control = "payment";
|
|
292
|
+
if (control === "text") {
|
|
293
|
+
// A long answer is NOT flagged on the component (v4 TextInput has no `multiline` or
|
|
294
|
+
// `numberOfLines`); only `identifier: TEXT_AREA` says so.
|
|
295
|
+
if (identifier === "TEXT_AREA") control = "textarea";
|
|
296
|
+
else if (rules.format === "EMAIL") control = "email";
|
|
297
|
+
else if (rules.format === "URL") control = "url";
|
|
298
|
+
else if (rules.format === "PHONE") control = "phone";
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Date bounds live under the format's own options block; `$now±N` is resolved here, once, so
|
|
302
|
+
// the DTO carries a real ISO value for `min`/`max` attributes and for the client check.
|
|
303
|
+
const dateRules: Raw = rules.dateOptions ?? rules.dateTimeOptions ?? rules.timeOptions ?? rules.dateOptionalTimeOptions ?? {};
|
|
304
|
+
const fileFormats: string[] = Array.isArray(rules.uploadFileFormats) ? rules.uploadFileFormats : [];
|
|
305
|
+
const isBirthdate = identifier === "CONTACTS_BIRTHDATE";
|
|
306
|
+
const validation: FormValidation = {
|
|
307
|
+
...(rules.format ? { format: rules.format } : {}),
|
|
308
|
+
...(rules.minLength != null ? { minLength: rules.minLength } : {}),
|
|
309
|
+
...(rules.maxLength != null ? { maxLength: rules.maxLength } : {}),
|
|
310
|
+
...(rules.pattern ? { pattern: rules.pattern } : {}),
|
|
311
|
+
...(rules.validationMessages?.pattern ? { patternMessage: String(rules.validationMessages.pattern) } : {}),
|
|
312
|
+
...(rules.minimum != null ? { minimum: rules.minimum } : {}),
|
|
313
|
+
...(rules.maximum != null ? { maximum: rules.maximum } : {}),
|
|
314
|
+
...(rules.multipleOf != null ? { multipleOf: rules.multipleOf } : {}),
|
|
315
|
+
// CONTACTS_BIRTHDATE is bounded 1900-01-01..today by Wix's own field (contacts-birthdate-validation.tsx).
|
|
316
|
+
...(resolveDate(dateRules.minimum, control) || isBirthdate
|
|
317
|
+
? { minDate: resolveDate(dateRules.minimum, control) ?? "1900-01-01" } : {}),
|
|
318
|
+
...(resolveDate(dateRules.maximum, control) || isBirthdate
|
|
319
|
+
? { maxDate: resolveDate(dateRules.maximum, control) ?? resolveDate("$now", "date") } : {}),
|
|
320
|
+
...(rules.fileLimit != null ? { fileLimit: rules.fileLimit } : {}),
|
|
321
|
+
...(fileFormats.length
|
|
322
|
+
? { fileFormats, accept: fileFormats.map((f) => FILE_FORMAT_ACCEPT[f]).filter(Boolean).join(",") }
|
|
323
|
+
: control === "file" || control === "signature" ? { accept: "" } : {}),
|
|
324
|
+
...(rules.minItems != null ? { minItems: rules.minItems } : {}),
|
|
325
|
+
...(rules.maxItems != null ? { maxItems: rules.maxItems } : {}),
|
|
326
|
+
// "Must be checked" is a BOOLEAN enum of [true]; `required` alone only checks presence.
|
|
327
|
+
...(inputType === "BOOLEAN" && Array.isArray(rules.enum) && rules.enum.length === 1 && rules.enum[0] === true ? { mustBeTrue: true } : {}),
|
|
328
|
+
...(Array.isArray(rules.phoneOptions?.allowedCountryCodes) && rules.phoneOptions.allowedCountryCodes.length
|
|
329
|
+
? { allowedCountryCodes: [...rules.phoneOptions.allowedCountryCodes] } : {}),
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
const options: Raw[] = Array.isArray(component.options) ? component.options : [];
|
|
333
|
+
const choices: FormChoice[] = options.map((o: Raw) => ({
|
|
334
|
+
value: String(o.value),
|
|
335
|
+
label: String(o.label ?? o.value),
|
|
336
|
+
// IMAGE_CHOICE options carry `media.image` (a wix:image URI) — resolved to a URL here.
|
|
337
|
+
...(o.media ? { imageUrl: imgSrc(o.media, 400, 400) } : {}),
|
|
338
|
+
}));
|
|
339
|
+
|
|
340
|
+
const target: string = input.target ?? "";
|
|
341
|
+
const label = plainText(component.label) || target;
|
|
342
|
+
|
|
343
|
+
// Every control is controlled from the first render, so each field starts at a value of the
|
|
344
|
+
// right SHAPE. The prefill key differs per component (make-view-of-input-field.ts): choice
|
|
345
|
+
// components mark `options[].default`, a checkbox has `checked`, a rating `defaultValue`,
|
|
346
|
+
// text / number / date have `default` (a date default may be `$now+2d`).
|
|
347
|
+
const defaultValue =
|
|
348
|
+
control === "address" ? {} :
|
|
349
|
+
inputType === "ARRAY" ? options.filter((o) => o.default).map((o) => String(o.value)) :
|
|
350
|
+
inputType === "WIX_FILE" ? [] :
|
|
351
|
+
inputType === "BOOLEAN" ? component.checked === true :
|
|
352
|
+
control === "select" || control === "radio" ? String(options.find((o) => o.default)?.value ?? "") :
|
|
353
|
+
control === "rating" ? ((component.defaultValue as number | undefined) ?? "") :
|
|
354
|
+
control === "date" || control === "time" || control === "datetime" ? (resolveDate(component.default, control) ?? "") :
|
|
355
|
+
(component.default as string | number | undefined) ?? "";
|
|
356
|
+
|
|
357
|
+
return {
|
|
358
|
+
target,
|
|
359
|
+
label,
|
|
360
|
+
showLabel: component.showLabel !== false,
|
|
361
|
+
control,
|
|
362
|
+
required,
|
|
363
|
+
readOnly: input.readOnly === true,
|
|
364
|
+
hidden: raw.hidden === true,
|
|
365
|
+
stepId,
|
|
366
|
+
...(component.placeholder ? { placeholder: String(component.placeholder) } : {}),
|
|
367
|
+
...(component.description ? { description: plainText(component.description) } : {}),
|
|
368
|
+
defaultValue,
|
|
369
|
+
choices,
|
|
370
|
+
...(component.customOption
|
|
371
|
+
? { otherOption: { label: String(component.customOption.label ?? "Other"), ...(component.customOption.placeholder ? { placeholder: String(component.customOption.placeholder) } : {}) } }
|
|
372
|
+
: {}),
|
|
373
|
+
addressParts: control === "address" ? addressParts(rules, component, required) : [],
|
|
374
|
+
...(control === "address" ? { addressOverrides: addressOverrides(rules, component) } : {}),
|
|
375
|
+
validation,
|
|
376
|
+
...(component.defaultCountryCode ? { phoneCountry: String(component.defaultCountryCode) } : {}),
|
|
377
|
+
...(component.buttonText ? { buttonText: String(component.buttonText) } : {}),
|
|
378
|
+
...(component.explanationText ? { explanationText: String(component.explanationText) } : {}),
|
|
379
|
+
identifier,
|
|
380
|
+
inputType,
|
|
381
|
+
componentType,
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Display order comes from `steps[].layout`, NOT from `formFields[]` array order. Sort WITHIN
|
|
387
|
+
* each step and concatenate in step order: `row` restarts at 0 in every step, so one sort
|
|
388
|
+
* across the flattened list interleaves them. Wix reads the `large` layout (`small` only on a
|
|
389
|
+
* phone, when present) and does not render a field absent from it; a field the owner never
|
|
390
|
+
* placed sorts LAST here, on the last step — it still stores values. The submit button is
|
|
391
|
+
* `fieldType: "DISPLAY"`, so filtering to INPUT drops it automatically. A hidden step's fields
|
|
392
|
+
* are skipped.
|
|
393
|
+
*/
|
|
394
|
+
export function orderedInputs(raw: Raw): { field: Raw; stepId: string }[] {
|
|
395
|
+
const steps = ((raw.steps ?? []) as Raw[]).filter((s) => !s.hidden);
|
|
396
|
+
const placed = new Map<string, { order: number; stepId: string }>();
|
|
397
|
+
let i = 0;
|
|
398
|
+
for (const s of steps) {
|
|
399
|
+
const items = ((s.layout?.large?.items ?? s.layout?.small?.items ?? []) as Raw[]).slice().sort((a, b) => a.row - b.row || a.column - b.column);
|
|
400
|
+
for (const item of items) placed.set(item.fieldId as string, { order: i++, stepId: id(s) });
|
|
401
|
+
}
|
|
402
|
+
const lastStep = id(steps[steps.length - 1]);
|
|
403
|
+
return ((raw.formFields ?? []) as Raw[])
|
|
404
|
+
.filter((f) => f.fieldType === "INPUT")
|
|
405
|
+
.map((f) => ({ field: f, order: placed.get(id(f))?.order ?? Infinity, stepId: placed.get(id(f))?.stepId ?? lastStep }))
|
|
406
|
+
.sort((a, b) => a.order - b.order)
|
|
407
|
+
.map(({ field, stepId }) => ({ field, stepId }));
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// Legacy `rules[]` (json-rules-engine spelling, form-conditions/condition-operators.ts) → v4
|
|
411
|
+
// operator names. Unknown names pass through and evaluate to false.
|
|
412
|
+
const LEGACY_OPERATOR: Record<string, string> = {
|
|
413
|
+
equal: "EQUAL", notEqual: "NOT_EQUAL", empty: "EMPTY", notEmpty: "NOT_EMPTY",
|
|
414
|
+
contains: "CONTAINS", notContains: "NOT_CONTAINS",
|
|
415
|
+
greaterThan: "GREATER_THAN", greaterThanOrEqual: "GREATER_THAN_OR_EQUALS",
|
|
416
|
+
lessThan: "LESS_THAN", lessThanOrEqual: "LESS_THAN_OR_EQUALS",
|
|
417
|
+
after: "AFTER", afterOrEqual: "AFTER_OR_EQUAL", before: "BEFORE", beforeOrEqual: "BEFORE_OR_EQUAL",
|
|
418
|
+
between: "BETWEEN", any: "ANY", arrayEqual: "ARRAY_EQUAL", arrayNotEqual: "ARRAY_NOT_EQUAL",
|
|
419
|
+
checked: "CHECKED", notChecked: "NOT_CHECKED", in: "IN", notIn: "NOT_IN",
|
|
420
|
+
isDateNewerThan: "IS_DATE_NEWER_THAN", isDateOlderThan: "IS_DATE_OLDER_THAN",
|
|
421
|
+
isDateNewerThanOrEqual: "IS_DATE_NEWER_THAN_OR_EQUAL", isDateOlderThanOrEqual: "IS_DATE_OLDER_THAN_OR_EQUAL",
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* The owner's rules, normalized from both spellings the schema carries into one serializable
|
|
426
|
+
* shape keyed by TARGET (so the store never needs field ids):
|
|
427
|
+
* - `formRules[]` (v4 `Rule`): `expression` is a ConditionNode tree (and / or / condition
|
|
428
|
+
* {target, operator, value}); overrides are FIELD entries with fieldId + propertyType
|
|
429
|
+
* REQUIRED / HIDDEN / ALLOWED_VALUES.
|
|
430
|
+
* - `rules[]` (deprecated `FormRule`, still what the runtime evaluates): `condition` is a
|
|
431
|
+
* json-rules-engine tree ({and|or: [{fact: <field id>, operator, value}]}); overrides are
|
|
432
|
+
* `valueChanges` keyed by path (`hidden`, `validation.required`, `validation.string.enum`,
|
|
433
|
+
* `view.options`; transform-path-to-v2.ts).
|
|
434
|
+
* A rule referencing a field that no longer exists is dropped, as Wix does (isFormRuleValid).
|
|
435
|
+
*/
|
|
436
|
+
export function toRules(raw: Raw): FormRule[] {
|
|
437
|
+
const targetOf = new Map<string, string>(
|
|
438
|
+
((raw.formFields ?? []) as Raw[]).filter((f) => f.inputOptions?.target).map((f) => [id(f), f.inputOptions.target as string]),
|
|
439
|
+
);
|
|
440
|
+
const targets = new Set(targetOf.values());
|
|
441
|
+
const out: FormRule[] = [];
|
|
442
|
+
|
|
443
|
+
const v4Node = (n: Raw | undefined): RuleCondition | null => {
|
|
444
|
+
if (!n) return null;
|
|
445
|
+
if (n.and?.conditions) { const list = (n.and.conditions as Raw[]).map(v4Node); return list.every(Boolean) && list.length ? { and: list as RuleCondition[] } : null; }
|
|
446
|
+
if (n.or?.conditions) { const list = (n.or.conditions as Raw[]).map(v4Node); return list.every(Boolean) && list.length ? { or: list as RuleCondition[] } : null; }
|
|
447
|
+
const c = n.condition;
|
|
448
|
+
// A condition target may be dotted for a nested value (`address.city`); the root must be a field.
|
|
449
|
+
if (!c?.target || !c.operator || !targets.has(String(c.target).split(".")[0])) return null;
|
|
450
|
+
return { target: String(c.target), operator: String(c.operator), value: c.value };
|
|
451
|
+
};
|
|
452
|
+
for (const rule of (raw.formRules ?? []) as Raw[]) {
|
|
453
|
+
const when = v4Node(rule.expression);
|
|
454
|
+
const then: RuleEffect[] = ((rule.overrides ?? []) as Raw[]).flatMap((o): RuleEffect[] => {
|
|
455
|
+
const f = o.fieldOptions;
|
|
456
|
+
const target = f?.fieldId ? targetOf.get(f.fieldId) : undefined;
|
|
457
|
+
if (!target) return [];
|
|
458
|
+
if (f.propertyType === "HIDDEN") return [{ target, hidden: f.hiddenOptions?.hidden === true }];
|
|
459
|
+
if (f.propertyType === "REQUIRED") return [{ target, required: f.requiredOptions?.required === true }];
|
|
460
|
+
if (f.propertyType === "ALLOWED_VALUES") return [{ target, allowedValues: ((f.allowedValuesOptions?.allowedValues ?? []) as unknown[]).map(String) }];
|
|
461
|
+
return [];
|
|
462
|
+
});
|
|
463
|
+
if (when && then.length) out.push({ id: id(rule), when, then });
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
const legacyNode = (n: Raw | undefined): RuleCondition | null => {
|
|
467
|
+
if (!n) return null;
|
|
468
|
+
if (Array.isArray(n.and)) { const list = (n.and as Raw[]).map(legacyNode); return list.every(Boolean) && list.length ? { and: list as RuleCondition[] } : null; }
|
|
469
|
+
if (Array.isArray(n.or)) { const list = (n.or as Raw[]).map(legacyNode); return list.every(Boolean) && list.length ? { or: list as RuleCondition[] } : null; }
|
|
470
|
+
const target = n.fact ? targetOf.get(String(n.fact)) : undefined;
|
|
471
|
+
if (!target || !n.operator) return null;
|
|
472
|
+
return { target, operator: LEGACY_OPERATOR[String(n.operator)] ?? String(n.operator), value: n.value };
|
|
473
|
+
};
|
|
474
|
+
for (const rule of (raw.rules ?? []) as Raw[]) {
|
|
475
|
+
const when = legacyNode(rule.condition);
|
|
476
|
+
const then: RuleEffect[] = ((rule.overrides ?? []) as Raw[]).flatMap((o) => {
|
|
477
|
+
if (o.entityType !== "FIELD" || !o.entityId) return [];
|
|
478
|
+
const target = targetOf.get(String(o.entityId));
|
|
479
|
+
if (!target) return [];
|
|
480
|
+
const ch: Raw = o.valueChanges ?? {};
|
|
481
|
+
const effect: RuleEffect = { target };
|
|
482
|
+
if (typeof ch.hidden === "boolean") effect.hidden = ch.hidden;
|
|
483
|
+
if (typeof ch["validation.required"] === "boolean") effect.required = ch["validation.required"];
|
|
484
|
+
if (Array.isArray(ch["validation.string.enum"])) effect.allowedValues = (ch["validation.string.enum"] as unknown[]).map(String);
|
|
485
|
+
else if (Array.isArray(ch["view.options"])) effect.allowedValues = (ch["view.options"] as Raw[]).map((opt) => String(opt?.value ?? opt?.label ?? opt));
|
|
486
|
+
return Object.keys(effect).length > 1 ? [effect] : [];
|
|
487
|
+
});
|
|
488
|
+
if (when && then.length) out.push({ id: id(rule), when, then });
|
|
489
|
+
}
|
|
490
|
+
return out;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
// ---- rule evaluation (form-conditions operators, without the engine) -----------------------------
|
|
494
|
+
|
|
495
|
+
const missing = (v: unknown): boolean => v === undefined || v === null || v === "" || (Array.isArray(v) && v.length === 0);
|
|
496
|
+
const isObj = (v: unknown): v is Record<string, unknown> => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
497
|
+
|
|
498
|
+
/** A value as a number for ordering: numbers as they are, strings as timestamps (time-only gets a fixed day). */
|
|
499
|
+
function ordinal(v: unknown): number | null {
|
|
500
|
+
if (typeof v === "number") return v;
|
|
501
|
+
if (typeof v !== "string" || !v) return null;
|
|
502
|
+
const t = new Date(/^\d{2}:\d{2}(:\d{2})?$/.test(v) ? `2000-01-01 ${v}` : v).getTime();
|
|
503
|
+
return Number.isNaN(t) ? null : t;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
function dayDiff(given: unknown, spec: unknown, now: Date): { date: Date; pivot: Date } | null {
|
|
507
|
+
if (!Array.isArray(spec) || spec.length !== 2 || typeof given !== "string") return null;
|
|
508
|
+
const units = Number(spec[0]);
|
|
509
|
+
const unit = spec[1];
|
|
510
|
+
const date = new Date(given);
|
|
511
|
+
if (Number.isNaN(date.getTime()) || Number.isNaN(units) || (unit !== "day" && unit !== "month")) return null;
|
|
512
|
+
const pivot = new Date(now.getTime());
|
|
513
|
+
if (unit === "day") pivot.setDate(pivot.getDate() + units); else pivot.setMonth(pivot.getMonth() + units);
|
|
514
|
+
const day = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
515
|
+
return { date: day(date), pivot: day(pivot) };
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/** Evaluate one comparison exactly as Wix's operators do (form-conditions/src/lib/operators). */
|
|
519
|
+
export function holds(operator: string, given: unknown, expected: unknown, now: Date = new Date()): boolean {
|
|
520
|
+
const g = given, e = expected;
|
|
521
|
+
const contains = (): boolean => {
|
|
522
|
+
if (missing(g)) return false;
|
|
523
|
+
if (isObj(g)) return Object.values(g).includes(e);
|
|
524
|
+
if (Array.isArray(g) || typeof g === "string") return (g as any).indexOf(e) > -1;
|
|
525
|
+
return false;
|
|
526
|
+
};
|
|
527
|
+
const within = (): boolean => {
|
|
528
|
+
if (isObj(e)) return Object.values(e).includes(g);
|
|
529
|
+
if (Array.isArray(e) || typeof e === "string") return (e as any).indexOf(g) > -1;
|
|
530
|
+
return false;
|
|
531
|
+
};
|
|
532
|
+
const cmp = (op: (a: number, b: number) => boolean): boolean => {
|
|
533
|
+
if (missing(g)) return false;
|
|
534
|
+
const a = ordinal(g), b = ordinal(e);
|
|
535
|
+
return a !== null && b !== null && op(a, b);
|
|
536
|
+
};
|
|
537
|
+
const arrayEq = (): boolean => {
|
|
538
|
+
if (missing(g) || !Array.isArray(g) || !Array.isArray(e) || g.length !== e.length) return false;
|
|
539
|
+
return e.every((v) => g.includes(v));
|
|
540
|
+
};
|
|
541
|
+
switch (operator) {
|
|
542
|
+
case "EQUAL": return g === e;
|
|
543
|
+
case "NOT_EQUAL": return g !== e;
|
|
544
|
+
case "EMPTY": return missing(g);
|
|
545
|
+
case "NOT_EMPTY": return !missing(g);
|
|
546
|
+
case "CONTAINS": return contains();
|
|
547
|
+
case "NOT_CONTAINS": return !contains();
|
|
548
|
+
case "GREATER_THAN": case "AFTER": return cmp((a, b) => a > b);
|
|
549
|
+
case "GREATER_THAN_OR_EQUALS": case "AFTER_OR_EQUAL": return cmp((a, b) => a >= b);
|
|
550
|
+
case "LESS_THAN": case "BEFORE": return cmp((a, b) => a < b);
|
|
551
|
+
case "LESS_THAN_OR_EQUALS": case "BEFORE_OR_EQUAL": return cmp((a, b) => a <= b);
|
|
552
|
+
case "BETWEEN": {
|
|
553
|
+
if (missing(g) || !Array.isArray(e) || e.length !== 2) return false;
|
|
554
|
+
const a = ordinal(g), lo = ordinal(e[0]), hi = ordinal(e[1]);
|
|
555
|
+
return a !== null && lo !== null && hi !== null && a > Math.min(lo, hi) && a < Math.max(lo, hi);
|
|
556
|
+
}
|
|
557
|
+
case "ANY": {
|
|
558
|
+
if (missing(g) || !Array.isArray(e)) return false;
|
|
559
|
+
return (Array.isArray(g) ? g : [g]).some((v) => e.includes(v));
|
|
560
|
+
}
|
|
561
|
+
case "ARRAY_EQUAL": return arrayEq();
|
|
562
|
+
case "ARRAY_NOT_EQUAL": return !arrayEq();
|
|
563
|
+
case "CHECKED": return Boolean(g);
|
|
564
|
+
case "NOT_CHECKED": return !g;
|
|
565
|
+
case "IN": return within();
|
|
566
|
+
case "NOT_IN": return !within();
|
|
567
|
+
case "IS_DATE_NEWER_THAN": case "IS_DATE_NEWER_THAN_OR_EQUAL": {
|
|
568
|
+
const d = dayDiff(g, e, now);
|
|
569
|
+
return !!d && (operator.endsWith("OR_EQUAL") ? d.date >= d.pivot : d.date > d.pivot);
|
|
570
|
+
}
|
|
571
|
+
case "IS_DATE_OLDER_THAN": case "IS_DATE_OLDER_THAN_OR_EQUAL": {
|
|
572
|
+
const d = dayDiff(g, Array.isArray(e) ? [-Number(e[0]), e[1]] : e, now);
|
|
573
|
+
return !!d && (operator.endsWith("OR_EQUAL") ? d.date <= d.pivot : d.date < d.pivot);
|
|
574
|
+
}
|
|
575
|
+
default: return false;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
/** A dotted condition target (`address.city`) read out of the values. */
|
|
580
|
+
function valueAt(values: FormValues, target: string): unknown {
|
|
581
|
+
return target.split(".").reduce<unknown>((v, k) => (isObj(v) ? v[k] : undefined), values);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
export function conditionHolds(when: RuleCondition, values: FormValues, now: Date = new Date()): boolean {
|
|
585
|
+
if ("and" in when) return when.and.every((c) => conditionHolds(c, values, now));
|
|
586
|
+
if ("or" in when) return when.or.some((c) => conditionHolds(c, values, now));
|
|
587
|
+
return holds(when.operator, valueAt(values, when.target), when.value, now);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* The form's fields with every rule whose condition holds applied, in rule order (a later rule
|
|
592
|
+
* wins on the same property — apply-overrides.ts reduces the same way). Hidden / required flip;
|
|
593
|
+
* ALLOWED_VALUES narrows `choices` to the listed values. Pure: call it on every value change and
|
|
594
|
+
* render the result.
|
|
595
|
+
*/
|
|
596
|
+
export function applyRules(form: FormDto, values: FormValues, now: Date = new Date()): FormFieldDto[] {
|
|
597
|
+
if (!form.rules.length) return form.fields;
|
|
598
|
+
const byTarget = new Map(form.fields.map((f) => [f.target, { ...f }]));
|
|
599
|
+
for (const rule of form.rules) {
|
|
600
|
+
if (!conditionHolds(rule.when, values, now)) continue;
|
|
601
|
+
for (const effect of rule.then) {
|
|
602
|
+
const f = byTarget.get(effect.target);
|
|
603
|
+
if (!f) continue;
|
|
604
|
+
if (effect.hidden !== undefined) f.hidden = effect.hidden;
|
|
605
|
+
if (effect.required !== undefined) f.required = effect.required;
|
|
606
|
+
if (effect.allowedValues) {
|
|
607
|
+
const allowed = new Set(effect.allowedValues);
|
|
608
|
+
f.choices = f.choices.filter((c) => allowed.has(c.value));
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
return form.fields.map((f) => byTarget.get(f.target) as FormFieldDto);
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
function toSuccess(settings: Raw | undefined): FormSuccess {
|
|
616
|
+
const action: string = settings?.submitSuccessAction ?? "NO_ACTION";
|
|
617
|
+
const out: FormSuccess = { action };
|
|
618
|
+
if (action === "THANK_YOU_MESSAGE") {
|
|
619
|
+
const message = plainText(settings?.thankYouMessageOptions?.richContent);
|
|
620
|
+
if (message) out.message = message;
|
|
621
|
+
const seconds = Number(settings?.thankYouMessageOptions?.durationInSeconds ?? 0);
|
|
622
|
+
if (seconds > 0) out.durationSeconds = seconds;
|
|
623
|
+
}
|
|
624
|
+
if (action === "REDIRECT" && settings?.redirectOptions?.redirectUrl) {
|
|
625
|
+
// Wix strips any scheme and always opens https:// (use-submit/utils.ts redirectToExternalUrl).
|
|
626
|
+
out.redirectUrl = `https://${String(settings.redirectOptions.redirectUrl).replace(/^https?:\/\//, "")}`;
|
|
627
|
+
out.newTab = settings.redirectOptions.target !== "SELF";
|
|
628
|
+
}
|
|
629
|
+
return out;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
export function toForm(raw: Raw, imgSrc: ImgSrc): FormDto {
|
|
633
|
+
const submit = ((raw.formFields ?? []) as Raw[]).find((f) => f.identifier === "SUBMIT_BUTTON");
|
|
634
|
+
const nav: Raw = submit?.displayOptions?.pageNavigationOptions ?? {};
|
|
635
|
+
const ordered = orderedInputs(raw);
|
|
636
|
+
const fields = ordered.map(({ field, stepId }) => toField(field, imgSrc, stepId));
|
|
637
|
+
const steps: FormStep[] = ((raw.steps ?? []) as Raw[])
|
|
638
|
+
.filter((s) => !s.hidden)
|
|
639
|
+
.map((s) => ({ id: id(s), name: s.name ?? "", targets: fields.filter((f) => f.stepId === id(s)).map((f) => f.target) }));
|
|
640
|
+
const limitation: Raw = raw.limitationRule ?? {};
|
|
641
|
+
const deadline = limitation.dateTimeDeadline ? new Date(limitation.dateTimeDeadline).toISOString() : undefined;
|
|
642
|
+
const indicator: Raw = raw.requiredIndicatorProperties ?? {};
|
|
643
|
+
return {
|
|
644
|
+
id: id(raw),
|
|
645
|
+
name: raw.name ?? "",
|
|
646
|
+
fields,
|
|
647
|
+
steps: steps.length ? steps : [{ id: "", name: "", targets: fields.map((f) => f.target) }],
|
|
648
|
+
rules: toRules(raw),
|
|
649
|
+
// The button wording lives on a DISPLAY field, nested under pageNavigationOptions because
|
|
650
|
+
// one control drives both multi-page navigation and the final submit.
|
|
651
|
+
submitText: nav.submitText ?? "",
|
|
652
|
+
nextText: nav.nextPageText ?? "",
|
|
653
|
+
previousText: nav.previousPageText ?? "",
|
|
654
|
+
// `enabled` (default true) replaces the older `properties.disabled`; read both.
|
|
655
|
+
enabled: raw.enabled != null ? raw.enabled !== false : raw.properties?.disabled !== true,
|
|
656
|
+
disabledMessage: plainText(raw.disabledFormMessage),
|
|
657
|
+
limits: {
|
|
658
|
+
...(deadline ? { deadline } : {}),
|
|
659
|
+
...(limitation.maxAllowedSubmissions != null ? { maxSubmissions: Number(limitation.maxAllowedSubmissions) } : {}),
|
|
660
|
+
...(limitation.submissionLimitPerUser != null ? { perVisitor: Number(limitation.submissionLimitPerUser) } : {}),
|
|
661
|
+
},
|
|
662
|
+
requiredIndicator: indicator.requiredIndicator ?? "ASTERISK",
|
|
663
|
+
requiredIndicatorBefore: indicator.requiredIndicatorPlacement === "BEFORE_FIELD_TITLE",
|
|
664
|
+
success: toSuccess(raw.submitSettings),
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/** A form that is not accepting submissions: switched off, or past its deadline (form-validator.ts isFormDisabled). */
|
|
669
|
+
export function isClosed(form: FormDto, now: Date = new Date()): boolean {
|
|
670
|
+
return !form.enabled || (!!form.limits.deadline && new Date(form.limits.deadline).getTime() <= now.getTime());
|
|
671
|
+
}
|