@wix/himalaya-cli 0.1583.0 → 0.1584.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/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/blog-v3/src/extensions.d.ts +2 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/comments-v1/src/extensions.d.ts +2 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/events/src/index.d.ts +3 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/groups/src/extensions.d.ts +15 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/loyalty/src/extensions.d.ts +13 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/members-v1/src/index.d.ts +19 -4
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-comments.mjs +3 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-events.mjs +4 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-groups.mjs +5 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-loyalty.mjs +4 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-members.mjs +10 -3
- package/dist/cli.mjs +247 -186
- package/dist/preview-assets.generated.bin +0 -0
- package/fixtures/wix-canned.json +25 -0
- package/guides/one-app-to-himi-app.md +52 -1
- package/guides/sdk-reference.json +37 -9
- package/guides/wix-api-usage.md +9 -0
- package/package.json +2 -2
- package/templates/beauty-salon/config.ts +7 -0
- package/templates/beauty-salon/dev/index.ts +758 -352
- package/templates/beauty-salon/himalaya.content.json +3 -0
- package/templates/beauty-salon/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/beauty-salon/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/beauty-salon/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/beauty-salon/tier5-src/_shared/owner-editor-value.ts +164 -0
- package/templates/beauty-salon/tier5-src/_shared/store-product-info.ts +50 -0
- package/templates/beauty-salon/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/beauty-salon/tier5-src/himi-branded-lite-category/index.ts +3 -2
- package/templates/beauty-salon/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
- package/templates/beauty-salon/tier5-src/himi-branded-lite-plans/index.ts +2 -1
- package/templates/beauty-salon/tier5-src/himi-store-product/index.ts +14 -3
- package/templates/beauty-salon/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
- package/templates/beauty-salon/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/beauty-salon-owner/dev/index.ts +129 -66
- package/templates/beauty-salon-owner/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
- package/templates/branded-lite/config.ts +9 -0
- package/templates/branded-lite/dev/index.ts +4988 -3304
- package/templates/branded-lite/himalaya.content.json +3 -0
- package/templates/branded-lite/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/branded-lite/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/branded-lite/tier5-src/_shared/event-registration.ts +86 -0
- package/templates/branded-lite/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/branded-lite/tier5-src/_shared/owner-editor-value.ts +164 -0
- package/templates/branded-lite/tier5-src/_shared/store-product-info.ts +50 -0
- package/templates/branded-lite/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/branded-lite/tier5-src/himi-branded-lite-badges/index.ts +2 -1
- package/templates/branded-lite/tier5-src/himi-branded-lite-category/index.ts +3 -2
- package/templates/branded-lite/tier5-src/himi-branded-lite-feed/index.ts +4 -3
- package/templates/branded-lite/tier5-src/himi-branded-lite-group-about/index.ts +243 -0
- package/templates/branded-lite/tier5-src/himi-branded-lite-loyalty/index.ts +115 -49
- package/templates/branded-lite/tier5-src/himi-branded-lite-plans/index.ts +2 -1
- package/templates/branded-lite/tier5-src/himi-branded-lite-podcasts/index.ts +2 -1
- package/templates/branded-lite/tier5-src/himi-branded-lite-portfolio/index.ts +2 -1
- package/templates/branded-lite/tier5-src/himi-branded-lite-portfolio-project/index.ts +3 -2
- package/templates/branded-lite/tier5-src/himi-branded-lite-program/facts.ts +52 -0
- package/templates/branded-lite/tier5-src/himi-branded-lite-program/index.ts +21 -11
- package/templates/branded-lite/tier5-src/himi-branded-lite-video/index.ts +2 -1
- package/templates/branded-lite/tier5-src/himi-events-detail/index.ts +12 -86
- package/templates/branded-lite/tier5-src/himi-events-list/index.ts +47 -6
- package/templates/branded-lite/tier5-src/himi-store-product/index.ts +13 -3
- package/templates/branded-lite/tier5-src/wix-spaces-forum-post/index.ts +3 -2
- package/templates/branded-lite/tier5-src/wix-spaces-member-detail/index.ts +53 -37
- package/templates/branded-lite/tier5-src/wix-spaces-members/index.ts +100 -34
- package/templates/branded-lite/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
- package/templates/branded-lite/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/community-club/config.ts +16 -0
- package/templates/community-club/dev/index.ts +1930 -401
- package/templates/community-club/himalaya.content.json +6 -0
- package/templates/community-club/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/community-club/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/community-club/tier5-src/_shared/event-registration.ts +86 -0
- package/templates/community-club/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/community-club/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/community-club/tier5-src/himi-branded-lite-feed/index.ts +4 -3
- package/templates/community-club/tier5-src/himi-branded-lite-group-about/index.ts +243 -0
- package/templates/community-club/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
- package/templates/community-club/tier5-src/himi-events-detail/index.ts +12 -86
- package/templates/community-club/tier5-src/himi-events-list/index.ts +47 -6
- package/templates/community-club/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/community-club-owner/dev/index.ts +53 -1
- package/templates/community-club-owner/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/community-club-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
- package/templates/community-club-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
- package/templates/community-club-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
- package/templates/community-club-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/community-club-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
- package/templates/community-club-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
- package/templates/community-club-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
- package/templates/events-meetups/config.ts +16 -0
- package/templates/events-meetups/dev/index.ts +1930 -401
- package/templates/events-meetups/himalaya.content.json +6 -0
- package/templates/events-meetups/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/events-meetups/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/events-meetups/tier5-src/_shared/event-registration.ts +86 -0
- package/templates/events-meetups/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/events-meetups/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/events-meetups/tier5-src/himi-branded-lite-feed/index.ts +4 -3
- package/templates/events-meetups/tier5-src/himi-branded-lite-group-about/index.ts +243 -0
- package/templates/events-meetups/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
- package/templates/events-meetups/tier5-src/himi-events-detail/index.ts +12 -86
- package/templates/events-meetups/tier5-src/himi-events-list/index.ts +47 -6
- package/templates/events-meetups/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/events-meetups-owner/dev/index.ts +6 -0
- package/templates/events-meetups-owner/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/gym-fitness/config.ts +7 -0
- package/templates/gym-fitness/dev/index.ts +1115 -278
- package/templates/gym-fitness/himalaya.content.json +3 -0
- package/templates/gym-fitness/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/gym-fitness/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/gym-fitness/tier5-src/_shared/event-registration.ts +86 -0
- package/templates/gym-fitness/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/gym-fitness/tier5-src/_shared/owner-editor-value.ts +164 -0
- package/templates/gym-fitness/tier5-src/_shared/store-product-info.ts +50 -0
- package/templates/gym-fitness/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/gym-fitness/tier5-src/himi-branded-lite-category/index.ts +3 -2
- package/templates/gym-fitness/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
- package/templates/gym-fitness/tier5-src/himi-branded-lite-plans/index.ts +2 -1
- package/templates/gym-fitness/tier5-src/himi-events-detail/index.ts +12 -86
- package/templates/gym-fitness/tier5-src/himi-events-list/index.ts +47 -6
- package/templates/gym-fitness/tier5-src/himi-store-product/index.ts +14 -3
- package/templates/gym-fitness/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
- package/templates/gym-fitness/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/gym-fitness-owner/dev/index.ts +132 -66
- package/templates/gym-fitness-owner/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
- package/templates/nonprofit-cause/config.ts +16 -0
- package/templates/nonprofit-cause/dev/index.ts +1925 -396
- package/templates/nonprofit-cause/himalaya.content.json +6 -0
- package/templates/nonprofit-cause/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/nonprofit-cause/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/nonprofit-cause/tier5-src/_shared/event-registration.ts +86 -0
- package/templates/nonprofit-cause/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/nonprofit-cause/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/nonprofit-cause/tier5-src/himi-branded-lite-feed/index.ts +4 -3
- package/templates/nonprofit-cause/tier5-src/himi-branded-lite-group-about/index.ts +243 -0
- package/templates/nonprofit-cause/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
- package/templates/nonprofit-cause/tier5-src/himi-branded-lite-plans/index.ts +2 -1
- package/templates/nonprofit-cause/tier5-src/himi-events-detail/index.ts +12 -86
- package/templates/nonprofit-cause/tier5-src/himi-events-list/index.ts +47 -6
- package/templates/nonprofit-cause/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
- package/templates/nonprofit-cause/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/nonprofit-cause-owner/dev/index.ts +85 -65
- package/templates/nonprofit-cause-owner/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-rich-guard.ts +27 -0
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
- package/templates/owner-lite/dev/index.ts +132 -66
- package/templates/owner-lite/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/owner-lite/tier5-src/himi-owner-lite-event/index.ts +16 -8
- package/templates/owner-lite/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
- package/templates/owner-lite/tier5-src/himi-owner-lite-events/index.ts +4 -2
- package/templates/owner-lite/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/owner-lite/tier5-src/himi-owner-lite-product/index.ts +39 -6
- package/templates/owner-lite/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
- package/templates/owner-lite/tier5-src/himi-owner-lite-products/index.ts +7 -4
- package/templates/owner-lite/tier5-src/himi-owner-lite-service/index.ts +38 -7
- package/templates/owner-lite/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
- package/templates/owner-lite/tier5-src/himi-owner-lite-services/index.ts +4 -2
- package/templates/podcast-creator/config.ts +7 -0
- package/templates/podcast-creator/dev/index.ts +1051 -158
- package/templates/podcast-creator/himalaya.content.json +3 -0
- package/templates/podcast-creator/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/podcast-creator/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/podcast-creator/tier5-src/_shared/event-registration.ts +86 -0
- package/templates/podcast-creator/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/podcast-creator/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/podcast-creator/tier5-src/himi-branded-lite-feed/index.ts +4 -3
- package/templates/podcast-creator/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
- package/templates/podcast-creator/tier5-src/himi-branded-lite-plans/index.ts +2 -1
- package/templates/podcast-creator/tier5-src/himi-branded-lite-podcasts/index.ts +2 -1
- package/templates/podcast-creator/tier5-src/himi-events-detail/index.ts +12 -86
- package/templates/podcast-creator/tier5-src/himi-events-list/index.ts +47 -6
- package/templates/podcast-creator/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
- package/templates/podcast-creator/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/podcast-creator-owner/dev/index.ts +53 -1
- package/templates/podcast-creator-owner/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
- package/templates/portfolio-creative/config.ts +7 -0
- package/templates/portfolio-creative/dev/index.ts +1305 -468
- package/templates/portfolio-creative/himalaya.content.json +3 -0
- package/templates/portfolio-creative/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/portfolio-creative/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/portfolio-creative/tier5-src/_shared/event-registration.ts +86 -0
- package/templates/portfolio-creative/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/portfolio-creative/tier5-src/_shared/owner-editor-value.ts +164 -0
- package/templates/portfolio-creative/tier5-src/_shared/store-product-info.ts +50 -0
- package/templates/portfolio-creative/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/portfolio-creative/tier5-src/himi-branded-lite-category/index.ts +3 -2
- package/templates/portfolio-creative/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
- package/templates/portfolio-creative/tier5-src/himi-branded-lite-portfolio/index.ts +2 -1
- package/templates/portfolio-creative/tier5-src/himi-branded-lite-portfolio-project/index.ts +3 -2
- package/templates/portfolio-creative/tier5-src/himi-events-detail/index.ts +12 -86
- package/templates/portfolio-creative/tier5-src/himi-events-list/index.ts +47 -6
- package/templates/portfolio-creative/tier5-src/himi-store-product/index.ts +14 -3
- package/templates/portfolio-creative/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/portfolio-creative-owner/dev/index.ts +129 -66
- package/templates/portfolio-creative-owner/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
- package/templates/restaurant/config.ts +7 -0
- package/templates/restaurant/dev/index.ts +1051 -158
- package/templates/restaurant/himalaya.content.json +3 -0
- package/templates/restaurant/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/restaurant/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/restaurant/tier5-src/_shared/event-registration.ts +86 -0
- package/templates/restaurant/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/restaurant/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/restaurant/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
- package/templates/restaurant/tier5-src/himi-events-detail/index.ts +12 -86
- package/templates/restaurant/tier5-src/himi-events-list/index.ts +47 -6
- package/templates/restaurant/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/restaurant-owner/dev/index.ts +132 -66
- package/templates/restaurant-owner/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
- package/templates/retail-store/config.ts +7 -0
- package/templates/retail-store/dev/index.ts +597 -191
- package/templates/retail-store/himalaya.content.json +3 -0
- package/templates/retail-store/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/retail-store/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/retail-store/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/retail-store/tier5-src/_shared/owner-editor-value.ts +164 -0
- package/templates/retail-store/tier5-src/_shared/store-product-info.ts +50 -0
- package/templates/retail-store/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/retail-store/tier5-src/himi-branded-lite-category/index.ts +3 -2
- package/templates/retail-store/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
- package/templates/retail-store/tier5-src/himi-store-product/index.ts +13 -3
- package/templates/retail-store/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/retail-store-owner/dev/index.ts +50 -1
- package/templates/retail-store-owner/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
- package/templates/yoga-studio/config.ts +7 -0
- package/templates/yoga-studio/dev/index.ts +1107 -110
- package/templates/yoga-studio/himalaya.content.json +3 -0
- package/templates/yoga-studio/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/yoga-studio/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/yoga-studio/tier5-src/_shared/event-registration.ts +86 -0
- package/templates/yoga-studio/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/yoga-studio/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/yoga-studio/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
- package/templates/yoga-studio/tier5-src/himi-branded-lite-plans/index.ts +2 -1
- package/templates/yoga-studio/tier5-src/himi-branded-lite-program/facts.ts +52 -0
- package/templates/yoga-studio/tier5-src/himi-branded-lite-program/index.ts +21 -11
- package/templates/yoga-studio/tier5-src/himi-events-detail/index.ts +12 -86
- package/templates/yoga-studio/tier5-src/himi-events-list/index.ts +47 -6
- package/templates/yoga-studio/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
- package/templates/yoga-studio/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/yoga-studio-owner/dev/index.ts +85 -65
- package/templates/yoga-studio-owner/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/yoga-studio-owner/tier5-src/_shared/owner-rich-guard.ts +27 -0
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
|
@@ -35,8 +35,10 @@ import {
|
|
|
35
35
|
type EventRow,
|
|
36
36
|
} from "../_shared/himi-events";
|
|
37
37
|
import { stashCopy, copyParam } from "../_shared/himi-copy.js";
|
|
38
|
+
import { eventPageUrlOf, eventStatus, registrationKindOf, registrationUi, registrationUrlOf, type RegistrationKind } from "../_shared/event-registration.js";
|
|
39
|
+
export { eventPageUrlOf, registrationKindOf, registrationUrlOf, type RegistrationKind };
|
|
38
40
|
import { openRichLink } from "../_shared/rich-content-link.js";
|
|
39
|
-
import {
|
|
41
|
+
import { descriptionBody } from "../_shared/rich-body.js";
|
|
40
42
|
import { mayUseRegularTicketCheckout } from "../_shared/iap-attendance.js";
|
|
41
43
|
import { ATTENDANCE_INITIAL, ATTENDANCE_NOT_HYDRATED, createAttendancePurchase, type AttendancePurchaseFields } from "../_shared/iap-attendance-purchase.js";
|
|
42
44
|
import { resetUnhydratedKeysOnOlderRuntime } from "../_shared/iap-worker.js";
|
|
@@ -88,9 +90,6 @@ interface TicketTierRow {
|
|
|
88
90
|
notAvailable?: boolean;
|
|
89
91
|
}
|
|
90
92
|
|
|
91
|
-
/** Registration CTA kind derived from the event's registration/eventType. */
|
|
92
|
-
export type RegistrationKind = "rsvp" | "tickets" | "external" | "none";
|
|
93
|
-
|
|
94
93
|
// Offline-first (data-offline): the event detail is a read-through single-item read —
|
|
95
94
|
// it shares the `events` entity written by the list, and also write-throughs its own
|
|
96
95
|
// fetched row so a deep-linked detail is cached for the next offline open. On a failed
|
|
@@ -302,7 +301,7 @@ function loadedTiers(defs: WixAvailableTicket[]): { rows: TicketTierRow[]; ticke
|
|
|
302
301
|
const ticket = tickets.get(row.ticketDefinitionId ?? row.id);
|
|
303
302
|
if (!ticket) return { ...row, quantity: 0, description: "", feeNote: "", policy: "", noPolicy: true, notAvailable: !row.available, notGuestPrice: !row.isGuestPrice, maxQuantity: 0 };
|
|
304
303
|
const policy = (ticket as unknown as { policy?: string; policyText?: string }).policyText || (ticket as unknown as { policy?: string }).policy || "";
|
|
305
|
-
return { ...row, quantity: 0, description: ticket.description
|
|
304
|
+
return { ...row, quantity: 0, description: descriptionBody(ticket.description).bodyText, feeNote: ((ticket as unknown as { wixFeeConfig?: { type?: string }; feeType?: string }).wixFeeConfig?.type ?? (ticket as unknown as { feeType?: string }).feeType) === "FEE_ADDED_AT_CHECKOUT" ? detailCopy("event.serviceFee", "+ ticket service fee") : "", policy, noPolicy: !policy, notAvailable: !row.available, notGuestPrice: !row.isGuestPrice, priceAmount: row.priceAmount ?? Number(ticket.price?.amount ?? 0), rowLimit: row.available ? ticket.limitPerCheckout ?? 99 : 0, maxQuantity: row.available ? ticket.limitPerCheckout ?? 99 : 0 };
|
|
306
305
|
});
|
|
307
306
|
return { rows, tickets };
|
|
308
307
|
}
|
|
@@ -451,29 +450,6 @@ function calendarFallbackUrl(s: S, end: number): string {
|
|
|
451
450
|
* shortDescription: REGISTRATION fills eventType, which skips the query enrichment that used to supply them. */
|
|
452
451
|
export const EVENT_DETAIL_FIELDSETS: WixEventFieldset[] = ["DETAILS", "TEXTS", "REGISTRATION", "URLS", "FORM", "AGENDA"];
|
|
453
452
|
|
|
454
|
-
/** Map registration status and decoded eventType onto the CTA variant. The decoded
|
|
455
|
-
* `eventType` already folds registration.type / registration.initialType /
|
|
456
|
-
* the legacy flat `type` (decodeEvent, #478). Without a recognized type or
|
|
457
|
-
* status there is no registration action to offer. */
|
|
458
|
-
export function registrationKindOf(e: WixEvent): RegistrationKind {
|
|
459
|
-
const raw = e as unknown as { registration?: { type?: string; initialType?: string; status?: string } };
|
|
460
|
-
const value = (raw.registration?.type ?? e.eventType ?? raw.registration?.initialType ?? "").toUpperCase();
|
|
461
|
-
if (value === "NONE" || value.includes("NO_REGISTRATION")) return "none";
|
|
462
|
-
// Open statuses select the footer action, so they must also select the
|
|
463
|
-
// inventory read and action guards when type metadata is absent or stale.
|
|
464
|
-
switch (raw.registration?.status?.toUpperCase()) {
|
|
465
|
-
case "OPEN_TICKETS": return "tickets";
|
|
466
|
-
case "OPEN_EXTERNAL": return "external";
|
|
467
|
-
case "OPEN_RSVP":
|
|
468
|
-
case "OPEN_RSVP_WAITLIST_ONLY":
|
|
469
|
-
case "SCHEDULED_RSVP": return "rsvp";
|
|
470
|
-
}
|
|
471
|
-
if (value.includes("EXTERNAL")) return "external";
|
|
472
|
-
if (value.includes("TICKET")) return "tickets";
|
|
473
|
-
if (value.includes("RSVP")) return "rsvp";
|
|
474
|
-
return "none";
|
|
475
|
-
}
|
|
476
|
-
|
|
477
453
|
function detailCopy(key: string, fallback: string): string { return copyParam(key, fallback); }
|
|
478
454
|
|
|
479
455
|
function detailDate(e: WixEvent): { line: string; zone: string; start: number; end: number } {
|
|
@@ -536,69 +512,17 @@ function detailPlace(e: WixEvent): { value: string; mapUrl: string; hideMapTap:
|
|
|
536
512
|
return { value, mapUrl: mapped, hideMapTap: !mapped, icon: "location" };
|
|
537
513
|
}
|
|
538
514
|
|
|
539
|
-
function eventStatus(e: WixEvent): string {
|
|
540
|
-
const raw = e as unknown as { status?: string };
|
|
541
|
-
return (raw.status ?? e.eventStatus ?? "").toUpperCase();
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
function registrationUi(e: WixEvent, now: number): { state: string; label: string; action: string; caption: string; notice: string } {
|
|
545
|
-
const raw = e as unknown as { registration?: { status?: string; registrationPaused?: boolean; registrationDisabled?: boolean; allowedGuestTypes?: string; rsvp?: { startDate?: string }; tickets?: { soldOut?: boolean }; external?: { url?: string } }; form?: { messages?: { registrationClosed?: { message?: string; exploreEventsActionLabel?: string }; ticketsUnavailable?: { message?: string; exploreEventsActionLabel?: string } } } };
|
|
546
|
-
const r = raw.registration ?? {};
|
|
547
|
-
const status = eventStatus(e);
|
|
548
|
-
const type = registrationKindOf(e);
|
|
549
|
-
if (status === "CANCELED") return { state: "notice", label: "", action: "", caption: "", notice: detailCopy("event.canceledNotice", "This event was canceled.") };
|
|
550
|
-
if (status === "ENDED") return { state: "notice", label: "", action: "", caption: "", notice: detailCopy("event.endedNotice", "This event has ended.") };
|
|
551
|
-
if (type === "none" || r.registrationDisabled) return { state: "none", label: "", action: "", caption: "", notice: "" };
|
|
552
|
-
const ownerClosed = raw.form?.messages?.registrationClosed?.message;
|
|
553
|
-
const ownerSold = raw.form?.messages?.ticketsUnavailable?.message;
|
|
554
|
-
if (["CLOSED_AUTOMATICALLY", "CLOSED_MANUALLY"].includes(r.status || "") || r.registrationPaused) return { state: "notice", label: "", action: "", caption: "", notice: ownerClosed || detailCopy("event.closedNotice", "Registration is closed.") };
|
|
555
|
-
if (type === "tickets" && r.tickets?.soldOut) return { state: "notice", label: "", action: "", caption: "", notice: ownerSold || detailCopy("event.soldOutNotice", "Tickets are sold out.") };
|
|
556
|
-
if (r.status === "SCHEDULED_RSVP") return { state: "scheduled", label: detailCopy("event.rsvpCta", "RSVP"), action: "", caption: detailCopy("event.opensCaption", "RSVP opens {date}.").replace("{date}", r.rsvp?.startDate ? formatWeekdayDateTime(new Date(r.rsvp.startDate)) : ""), notice: "" };
|
|
557
|
-
if (r.status === "OPEN_RSVP_WAITLIST_ONLY") return { state: "waitlist", label: detailCopy("event.waitlistCta", "Join Waitlist"), action: "himi.open", caption: detailCopy("event.fullCaption", "This event is full."), notice: "" };
|
|
558
|
-
if (r.status === "OPEN_TICKETS" || type === "tickets") return { state: "tickets", label: detailCopy("event.ticketsCta", "Buy Tickets"), action: "openTickets", caption: "", notice: "" };
|
|
559
|
-
if (r.status === "OPEN_EXTERNAL" || type === "external") return registrationUrlOf(e)
|
|
560
|
-
? { state: "external", label: detailCopy("event.externalCta", "Register"), action: "openRegistration", caption: "", notice: "" }
|
|
561
|
-
: { state: "none", label: "", action: "", caption: "", notice: "" };
|
|
562
|
-
if (type === "rsvp" && r.status === "OPEN_RSVP") return { state: "rsvp", label: detailCopy("event.rsvpCta", "RSVP"), action: "himi.open", caption: "", notice: "" };
|
|
563
|
-
if (r.status === "OPEN_RSVP" || (type === "rsvp" && !r.status)) return { state: "rsvp", label: detailCopy("event.rsvpCta", "RSVP"), action: "himi.open", caption: "", notice: "" };
|
|
564
|
-
void now;
|
|
565
|
-
return { state: "none", label: "", action: "", caption: "", notice: "" };
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
/** External registration URL / event page URL from the raw payload ("" when absent). */
|
|
569
|
-
export function registrationUrlOf(e: WixEvent): string {
|
|
570
|
-
const raw = e as unknown as {
|
|
571
|
-
registration?: { external?: { registration?: string; url?: string } };
|
|
572
|
-
eventPageUrl?: { base?: string; path?: string } | string;
|
|
573
|
-
};
|
|
574
|
-
const external = raw.registration?.external?.registration ?? raw.registration?.external?.url;
|
|
575
|
-
if (typeof external === "string" && /^https?:\/\//i.test(external)) return external;
|
|
576
|
-
return eventPageUrlOf(e);
|
|
577
|
-
}
|
|
578
|
-
|
|
579
515
|
/** Event slug for createRedirectSession({ eventsCheckout }) — "" when absent. */
|
|
580
516
|
export function eventSlugOf(e: WixEvent): string {
|
|
581
517
|
const slug = e.slug ?? (e as unknown as { slug?: string }).slug;
|
|
582
518
|
return typeof slug === "string" ? slug.trim() : "";
|
|
583
519
|
}
|
|
584
520
|
|
|
585
|
-
/** The event's public page URL when the payload carries one ("" otherwise). */
|
|
586
|
-
export function eventPageUrlOf(e: WixEvent): string {
|
|
587
|
-
const raw = e as unknown as { eventPageUrl?: { base?: string; path?: string } | string };
|
|
588
|
-
const page = raw.eventPageUrl;
|
|
589
|
-
if (typeof page === "string" && /^https?:\/\//i.test(page)) return page;
|
|
590
|
-
if (page && typeof page === "object" && typeof page.base === "string" && page.base) {
|
|
591
|
-
const path = typeof page.path === "string" ? page.path : "";
|
|
592
|
-
return `${page.base.replace(/\/$/, "")}${path && !path.startsWith("/") ? "/" : ""}${path}`;
|
|
593
|
-
}
|
|
594
|
-
return "";
|
|
595
|
-
}
|
|
596
|
-
|
|
597
521
|
/** The description pair: the v3 Ricos `description` for RichContent, and its plain text. A string description
|
|
598
522
|
* (or none) keeps `eventDescription`'s legacy read, with no document. */
|
|
599
523
|
function eventBody(e: WixEvent): { description: string; descriptionJson: string } {
|
|
600
|
-
const legacy = eventDescription(e);
|
|
601
|
-
const { bodyJson, bodyText } =
|
|
524
|
+
const legacy = eventDescription({ ...e, description: undefined });
|
|
525
|
+
const { bodyJson, bodyText } = descriptionBody((e as unknown as { description?: unknown }).description, descriptionBody(legacy).bodyText);
|
|
602
526
|
return { description: bodyText, descriptionJson: bodyJson };
|
|
603
527
|
}
|
|
604
528
|
|
|
@@ -1132,6 +1056,8 @@ const svc: ReturnType<typeof defineService<S, DetailActions>> = defineService<S,
|
|
|
1132
1056
|
}).sort((a, b) => (eventStartMillis(a) ?? 0) - (eventStartMillis(b) ?? 0)).map((item) => ({ id: item.id ?? "", date: eventWhen(item) })).filter((item) => !!item.id);
|
|
1133
1057
|
} catch { moreDates = []; optionalReadFailed = true; }
|
|
1134
1058
|
}
|
|
1059
|
+
const body = eventBody(e);
|
|
1060
|
+
const shortDescription = descriptionBody(rawEvent.shortDescription).bodyText;
|
|
1135
1061
|
const readyState = derive({
|
|
1136
1062
|
...s,
|
|
1137
1063
|
status: "ready",
|
|
@@ -1153,9 +1079,9 @@ const svc: ReturnType<typeof defineService<S, DetailActions>> = defineService<S,
|
|
|
1153
1079
|
price,
|
|
1154
1080
|
zone: dates.zone,
|
|
1155
1081
|
mapUrl: place.mapUrl,
|
|
1156
|
-
shortDescription
|
|
1157
|
-
noShortDescription: !
|
|
1158
|
-
noDescription: !
|
|
1082
|
+
shortDescription,
|
|
1083
|
+
noShortDescription: !shortDescription || shortDescription === body.description,
|
|
1084
|
+
noDescription: !body.description && !body.descriptionJson,
|
|
1159
1085
|
noDate: !dates.line,
|
|
1160
1086
|
registrationState: registration.state,
|
|
1161
1087
|
footerLabel: registration.label,
|
|
@@ -1177,7 +1103,7 @@ const svc: ReturnType<typeof defineService<S, DetailActions>> = defineService<S,
|
|
|
1177
1103
|
noMoreDates: moreDates.length === 0,
|
|
1178
1104
|
// The Ricos description when the event has one (its own text is the plain copy); the legacy
|
|
1179
1105
|
// string fields otherwise.
|
|
1180
|
-
...
|
|
1106
|
+
...body,
|
|
1181
1107
|
image,
|
|
1182
1108
|
hasImage: !!image,
|
|
1183
1109
|
noImage: !image,
|
|
@@ -5,6 +5,8 @@ import { getAll, upsert, type DbEntity } from "@himalaya/local-db";
|
|
|
5
5
|
import { normalizeEvent, type EventRow } from "../_shared/himi-events";
|
|
6
6
|
import { offsetPage } from "../_shared/offset-page.js";
|
|
7
7
|
import { copyParam } from "../_shared/himi-copy.js";
|
|
8
|
+
import { eventPageUrlOf, registrationUi } from "../_shared/event-registration.js";
|
|
9
|
+
import { share as shareSheet } from "@himalaya/share";
|
|
8
10
|
|
|
9
11
|
// Offline-first (data-offline): the public events list is a read-through catalog —
|
|
10
12
|
// paint the last-synced rows from the on-device store first (instant, works offline),
|
|
@@ -13,8 +15,37 @@ import { copyParam } from "../_shared/himi-copy.js";
|
|
|
13
15
|
// (+ declared the `events` entity in its dataSchema) just falls back to today's
|
|
14
16
|
// online-only path — the try/catch is the seam that keeps this shared bundle safe.
|
|
15
17
|
const ENTITY = "events";
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
interface ListEventRow extends EventRow {
|
|
19
|
+
dateBadge: string; noDateBadge: boolean;
|
|
20
|
+
/** This card's verb (Register / RSVP / Buy Tickets / Join Waitlist) from the SAME rule the detail uses; hidden when none applies. */
|
|
21
|
+
actionLabel: string; noAction: boolean;
|
|
22
|
+
/** The event page URL (when the payload carries one) for Share. */
|
|
23
|
+
shareUrl: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// The day monogram is a title initial for undated events. Only an actual calendar
|
|
27
|
+
// date becomes a badge; derive it for old cached rows too, without a cache migration.
|
|
28
|
+
// The month must be the three-letter abbreviation: rows cached by an older worker on an
|
|
29
|
+
// Intl-less engine can hold a whole "11/10/2030, 12:00:00 PM" there.
|
|
30
|
+
function withDateBadge(row: EventRow): ListEventRow {
|
|
31
|
+
const dated = typeof row.month === "string" && /^[A-Z]{3}$/.test(row.month)
|
|
32
|
+
&& /^(?:[1-9]|[12]\d|3[01])$/.test(row.day);
|
|
33
|
+
const known = row as Partial<ListEventRow>;
|
|
34
|
+
// Rows cached by an older build carry no registration data: they show no verb until a refresh, never a wrong one.
|
|
35
|
+
return { ...row, dateBadge: dated ? `${row.day}\n${row.month}` : "", noDateBadge: !dated,
|
|
36
|
+
actionLabel: known.actionLabel ?? "", noAction: known.noAction ?? true, shareUrl: known.shareUrl ?? "" };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** The card's action, from the event's own registration (REGISTRATION + URLS fieldsets). Cancelled, ended,
|
|
40
|
+
* closed, sold-out and registration-less events offer none, so a card never promises "Register" the detail refuses. */
|
|
41
|
+
function withRegistration(raw: WixEvent, row: ListEventRow): ListEventRow {
|
|
42
|
+
const ui = registrationUi(raw, Date.now());
|
|
43
|
+
const offers = ui.state !== "notice" && ui.state !== "none" && ui.state !== "scheduled" && !!ui.label;
|
|
44
|
+
return { ...row, actionLabel: offers ? ui.label : "", noAction: !offers, shareUrl: eventPageUrlOf(raw) };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function readCached(): Promise<ListEventRow[]> {
|
|
48
|
+
try { return ((await getAll(ENTITY)) as unknown as EventRow[]).map(withDateBadge); } catch { return []; }
|
|
18
49
|
}
|
|
19
50
|
async function writeCached(rows: EventRow[]): Promise<void> {
|
|
20
51
|
try { for (const r of rows) await upsert(ENTITY, r as unknown as DbEntity); } catch { /* capability not granted → online-only */ }
|
|
@@ -22,12 +53,12 @@ async function writeCached(rows: EventRow[]): Promise<void> {
|
|
|
22
53
|
|
|
23
54
|
interface S {
|
|
24
55
|
status: "loading" | "ready";
|
|
25
|
-
query: string; all:
|
|
56
|
+
query: string; all: ListEventRow[]; results: ListEventRow[]; emptyText: string; countLabel: string;
|
|
26
57
|
errored: boolean; notErrored: boolean; isLoading: boolean; notLoading: boolean; noEmpty: boolean;
|
|
27
58
|
nextCursor?: string; complete?: boolean; total?: number; loadingMore?: boolean; pageError?: boolean; fromCache?: boolean;
|
|
28
59
|
}
|
|
29
60
|
let queryNow = new Date().toISOString();
|
|
30
|
-
const svc = defineBackendCollection<S,
|
|
61
|
+
const svc = defineBackendCollection<S, ListEventRow>("himiEvents", {
|
|
31
62
|
restorePagesOnLoad: true,
|
|
32
63
|
state: { status: "loading", query: "", all: [], results: [], emptyText: "", countLabel: "", errored: false, notErrored: true,
|
|
33
64
|
isLoading: true, notLoading: false, noEmpty: true },
|
|
@@ -62,10 +93,10 @@ const svc = defineBackendCollection<S, EventRow>("himiEvents", {
|
|
|
62
93
|
];
|
|
63
94
|
}
|
|
64
95
|
if (criteria.filter === "value:Past") filter["dateAndTimeSettings.startDate"] = { $lt: queryNow };
|
|
65
|
-
const res = await queryEvents({ limit: 50, offset: Number(cursor || 0), query: { filter,
|
|
96
|
+
const res = await queryEvents({ limit: 50, offset: Number(cursor || 0), fields: ["DETAILS", "REGISTRATION", "URLS"], query: { filter,
|
|
66
97
|
sort: [{ fieldName: criteria.sort === "default" ? "dateAndTimeSettings.startDate" : "title", order: criteria.sort === "za" ? "DESC" : "ASC" }, { fieldName: "id", order: "ASC" }] } });
|
|
67
98
|
const raw = res.events ?? [];
|
|
68
|
-
const items = raw.filter(row => !!row.id).map(normalizeEvent);
|
|
99
|
+
const items = raw.filter(row => !!row.id).map(row => withRegistration(row, withDateBadge(normalizeEvent(row))));
|
|
69
100
|
await writeCached(items);
|
|
70
101
|
const metadata = (res as { pagingMetadata?: { total?: number } }).pagingMetadata;
|
|
71
102
|
return { items, ...offsetPage(cursor, raw.length, 50, metadata), metadata: { fromCache: false } };
|
|
@@ -78,6 +109,16 @@ const svc = defineBackendCollection<S, EventRow>("himiEvents", {
|
|
|
78
109
|
fromCache: page.metadata?.fromCache === true, errored, notErrored: !errored, isLoading: loading, notLoading: !loading,
|
|
79
110
|
noEmpty: true, countLabel: "", emptyText: errored ? copyParam("events.errorText", "Events could not be loaded.") : "" };
|
|
80
111
|
},
|
|
112
|
+
actions: {
|
|
113
|
+
// Share a card's event: its title and date line, plus the event page when the payload carried one.
|
|
114
|
+
share: async (s, arg) => {
|
|
115
|
+
const id = typeof arg === "string" ? arg : String((arg as { id?: unknown } | undefined)?.id ?? "");
|
|
116
|
+
const row = s.results.find(item => item.id === id);
|
|
117
|
+
if (!row) return undefined;
|
|
118
|
+
try { await shareSheet({ subject: row.title, text: [row.title, row.dateLine].filter(Boolean).join(" — "), ...(row.shareUrl ? { url: row.shareUrl } : {}) }); } catch { /* the sheet is best-effort: nothing to undo */ }
|
|
119
|
+
return undefined;
|
|
120
|
+
},
|
|
121
|
+
},
|
|
81
122
|
});
|
|
82
123
|
svc.load();
|
|
83
124
|
export { svc };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { descriptionBody } from "../_shared/rich-body.js";
|
|
1
2
|
// Tier-5 bundle: Wix Spaces clone — Pricing plan detail (ON-DEVICE, site-scoped).
|
|
2
3
|
// himalaya.input.id carries the plan id.
|
|
3
4
|
//
|
|
@@ -53,7 +54,7 @@ const svc = defineService<S, { load: (s: S) => Promise<S> }>("spacesPlanDetail",
|
|
|
53
54
|
const p = await readPlan(id);
|
|
54
55
|
if (!p) return { ...s, status: "ready", ...presence("missing") };
|
|
55
56
|
const perks = (p.perks?.values ?? []).map((v) => `• ${v}`).join("\n");
|
|
56
|
-
return { status: "ready", name: p.name || "Plan", price: priceOf(p), description: p.description
|
|
57
|
+
return { status: "ready", name: p.name || "Plan", price: priceOf(p), description: descriptionBody(p.description).bodyText, perks, ...presence("found") };
|
|
57
58
|
} catch (e) { return { ...s, status: "ready", ...presenceAfterError(e) }; }
|
|
58
59
|
},
|
|
59
60
|
},
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { descriptionBody } from "../_shared/rich-body.js";
|
|
1
2
|
// Tier-5 bundle: Wix Spaces clone — What's New (ON-DEVICE, account-level).
|
|
2
3
|
import { defineService } from "@himalaya/state";
|
|
3
4
|
import { withEmptyFlags } from "../_shared/empty-flags.js";
|
|
@@ -8,7 +9,7 @@ interface S { status: "loading" | "ready"; items: Row[]; emptyText: string; /**
|
|
|
8
9
|
|
|
9
10
|
function norm(a: WixAnnouncement, i: number): Row {
|
|
10
11
|
const aa = a as unknown as { id?: string; title?: string; bodyText?: string; description?: string };
|
|
11
|
-
return { id: aa.id || `a${i}`, name: aa.title || "Announcement", subtitle: aa.description
|
|
12
|
+
return { id: aa.id || `a${i}`, name: aa.title || "Announcement", subtitle: descriptionBody(aa.description, descriptionBody(aa.bodyText).bodyText).bodyText };
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
const svc = defineService<S, { load: (s: S) => Promise<S> }>("spacesWhatsNew", withEmptyFlags({
|
|
@@ -76892,6 +76892,35 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
76892
76892
|
}
|
|
76893
76893
|
}
|
|
76894
76894
|
},
|
|
76895
|
+
{
|
|
76896
|
+
"id": "service_form.description_note",
|
|
76897
|
+
"body": {
|
|
76898
|
+
"package": "himalaya",
|
|
76899
|
+
"type": "Text",
|
|
76900
|
+
"props": {
|
|
76901
|
+
"text": "$service:himiOwnerLiteServiceForm.descriptionNote",
|
|
76902
|
+
"style": "footnote",
|
|
76903
|
+
"color": "textSecondary",
|
|
76904
|
+
"collapseWhenEmpty": true
|
|
76905
|
+
}
|
|
76906
|
+
}
|
|
76907
|
+
},
|
|
76908
|
+
{
|
|
76909
|
+
"id": "service_form.description_preview",
|
|
76910
|
+
"body": {
|
|
76911
|
+
"package": "himalaya",
|
|
76912
|
+
"type": "Text",
|
|
76913
|
+
"props": {
|
|
76914
|
+
"text": "$service:himiOwnerLiteServiceForm.description",
|
|
76915
|
+
"style": "body",
|
|
76916
|
+
"maxLines": 8,
|
|
76917
|
+
"collapseWhenEmpty": true
|
|
76918
|
+
}
|
|
76919
|
+
},
|
|
76920
|
+
"modifiers": {
|
|
76921
|
+
"hiddenPath": "$service:himiOwnerLiteServiceForm.descriptionEditable"
|
|
76922
|
+
}
|
|
76923
|
+
},
|
|
76895
76924
|
{
|
|
76896
76925
|
"id": "service_form.form",
|
|
76897
76926
|
"body": {
|
|
@@ -76936,6 +76965,9 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
76936
76965
|
"multilineMaxLines": 3
|
|
76937
76966
|
}
|
|
76938
76967
|
}
|
|
76968
|
+
},
|
|
76969
|
+
"modifiers": {
|
|
76970
|
+
"hiddenPath": "$service:himiOwnerLiteServiceForm.descriptionProtected"
|
|
76939
76971
|
}
|
|
76940
76972
|
}
|
|
76941
76973
|
],
|
|
@@ -78252,6 +78284,51 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
78252
78284
|
}
|
|
78253
78285
|
}
|
|
78254
78286
|
},
|
|
78287
|
+
{
|
|
78288
|
+
"id": "service_body",
|
|
78289
|
+
"body": {
|
|
78290
|
+
"package": "himalaya",
|
|
78291
|
+
"type": "RichContent",
|
|
78292
|
+
"props": {
|
|
78293
|
+
"documentJsonPath": "$service:himiOwnerLiteService.bodyJson",
|
|
78294
|
+
"onLink": {
|
|
78295
|
+
"actionId": "tier5.himiOwnerLiteService.openLink"
|
|
78296
|
+
},
|
|
78297
|
+
"fallback": {
|
|
78298
|
+
"id": "",
|
|
78299
|
+
"body": {
|
|
78300
|
+
"package": "himalaya",
|
|
78301
|
+
"type": "Text",
|
|
78302
|
+
"props": {
|
|
78303
|
+
"text": "$service:himiOwnerLiteService.bodyText",
|
|
78304
|
+
"style": "body",
|
|
78305
|
+
"color": "textPrimary",
|
|
78306
|
+
"collapseWhenEmpty": true
|
|
78307
|
+
}
|
|
78308
|
+
}
|
|
78309
|
+
}
|
|
78310
|
+
}
|
|
78311
|
+
},
|
|
78312
|
+
"modifiers": {
|
|
78313
|
+
"hiddenPath": "$service:himiOwnerLiteService.noBodyJson"
|
|
78314
|
+
}
|
|
78315
|
+
},
|
|
78316
|
+
{
|
|
78317
|
+
"id": "service_body_text",
|
|
78318
|
+
"body": {
|
|
78319
|
+
"package": "himalaya",
|
|
78320
|
+
"type": "Text",
|
|
78321
|
+
"props": {
|
|
78322
|
+
"text": "$service:himiOwnerLiteService.bodyText",
|
|
78323
|
+
"style": "body",
|
|
78324
|
+
"color": "textPrimary",
|
|
78325
|
+
"collapseWhenEmpty": true
|
|
78326
|
+
}
|
|
78327
|
+
},
|
|
78328
|
+
"modifiers": {
|
|
78329
|
+
"hiddenPath": "$service:himiOwnerLiteService.hasBodyJson"
|
|
78330
|
+
}
|
|
78331
|
+
},
|
|
78255
78332
|
{
|
|
78256
78333
|
"id": "service_info_card",
|
|
78257
78334
|
"body": {
|
|
@@ -78439,70 +78516,6 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
78439
78516
|
"modifiers": {
|
|
78440
78517
|
"hiddenPath": "$service:himiOwnerLiteService.capacityBlank"
|
|
78441
78518
|
}
|
|
78442
|
-
},
|
|
78443
|
-
{
|
|
78444
|
-
"id": "",
|
|
78445
|
-
"body": {
|
|
78446
|
-
"package": "himalaya",
|
|
78447
|
-
"type": "Divider",
|
|
78448
|
-
"props": {}
|
|
78449
|
-
},
|
|
78450
|
-
"modifiers": {
|
|
78451
|
-
"hiddenPath": "$service:himiOwnerLiteService.descriptionNoDivider"
|
|
78452
|
-
}
|
|
78453
|
-
},
|
|
78454
|
-
{
|
|
78455
|
-
"id": "service_row_description",
|
|
78456
|
-
"body": {
|
|
78457
|
-
"package": "himalaya",
|
|
78458
|
-
"type": "HStack",
|
|
78459
|
-
"props": {
|
|
78460
|
-
"spacing": 0,
|
|
78461
|
-
"children": [
|
|
78462
|
-
{
|
|
78463
|
-
"id": "",
|
|
78464
|
-
"body": {
|
|
78465
|
-
"package": "himalaya",
|
|
78466
|
-
"type": "Text",
|
|
78467
|
-
"props": {
|
|
78468
|
-
"text": "What the class is for",
|
|
78469
|
-
"style": "footnote",
|
|
78470
|
-
"color": "textSecondary"
|
|
78471
|
-
}
|
|
78472
|
-
},
|
|
78473
|
-
"modifiers": {
|
|
78474
|
-
"padding": {
|
|
78475
|
-
"trailing": 10
|
|
78476
|
-
}
|
|
78477
|
-
}
|
|
78478
|
-
},
|
|
78479
|
-
{
|
|
78480
|
-
"id": "",
|
|
78481
|
-
"body": {
|
|
78482
|
-
"package": "himalaya",
|
|
78483
|
-
"type": "Spacer",
|
|
78484
|
-
"props": {}
|
|
78485
|
-
}
|
|
78486
|
-
},
|
|
78487
|
-
{
|
|
78488
|
-
"id": "",
|
|
78489
|
-
"body": {
|
|
78490
|
-
"package": "himalaya",
|
|
78491
|
-
"type": "Text",
|
|
78492
|
-
"props": {
|
|
78493
|
-
"text": "$service:himiOwnerLiteService.description",
|
|
78494
|
-
"style": "bodyEmphasis",
|
|
78495
|
-
"maxLines": 1,
|
|
78496
|
-
"collapseWhenEmpty": true
|
|
78497
|
-
}
|
|
78498
|
-
}
|
|
78499
|
-
}
|
|
78500
|
-
]
|
|
78501
|
-
}
|
|
78502
|
-
},
|
|
78503
|
-
"modifiers": {
|
|
78504
|
-
"hiddenPath": "$service:himiOwnerLiteService.descriptionBlank"
|
|
78505
|
-
}
|
|
78506
78519
|
}
|
|
78507
78520
|
]
|
|
78508
78521
|
}
|
|
@@ -78623,7 +78636,8 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
78623
78636
|
"contentType": "application/javascript+ts-bundle",
|
|
78624
78637
|
"declaredCapabilities": [
|
|
78625
78638
|
"wix_api",
|
|
78626
|
-
"local_database"
|
|
78639
|
+
"local_database",
|
|
78640
|
+
"open_url"
|
|
78627
78641
|
],
|
|
78628
78642
|
"minBinaryVersion": "0.1.0",
|
|
78629
78643
|
"bundleVersion": "0.0.1"
|
|
@@ -79088,6 +79102,9 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
79088
79102
|
}
|
|
79089
79103
|
}
|
|
79090
79104
|
}
|
|
79105
|
+
},
|
|
79106
|
+
"modifiers": {
|
|
79107
|
+
"hiddenPath": "$service:himiOwnerLiteEvent.noBodyJson"
|
|
79091
79108
|
}
|
|
79092
79109
|
},
|
|
79093
79110
|
{
|
|
@@ -80097,6 +80114,9 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
80097
80114
|
}
|
|
80098
80115
|
}
|
|
80099
80116
|
}
|
|
80117
|
+
},
|
|
80118
|
+
"modifiers": {
|
|
80119
|
+
"hiddenPath": "$service:himiOwnerLitePost.noBodyJson"
|
|
80100
80120
|
}
|
|
80101
80121
|
},
|
|
80102
80122
|
{
|
|
@@ -19,6 +19,8 @@ export interface CollectionConfig {
|
|
|
19
19
|
/** Numeric 0–5 row field rendered as a Rating (accessible "N out of 5") instead of
|
|
20
20
|
* folding a "★★★★☆" glyph string into the metadata line, so screen readers get a value. */
|
|
21
21
|
rating?: string;
|
|
22
|
+
/** Domain-provided calendar text and its unavailable flag, kept separate from media. */
|
|
23
|
+
dateBadge?: { text: string; hidden: string };
|
|
22
24
|
sectioned?: boolean;
|
|
23
25
|
view: 'list' | 'grid';
|
|
24
26
|
backendQuery?: boolean;
|
|
@@ -38,7 +40,13 @@ export interface CollectionConfig {
|
|
|
38
40
|
/** The card's primary verb, shown as a visible button beside the overflow.
|
|
39
41
|
* `screenId` opens that screen with the row id; without it the verb reuses the
|
|
40
42
|
* row's own tap action (the detail screen that owns the verb). */
|
|
41
|
-
primaryVerb?: { label: string; screenId?: string
|
|
43
|
+
primaryVerb?: { label: string; screenId?: string;
|
|
44
|
+
/** A row field holding THIS row's verb label (Register, RSVP, Buy Tickets…); `label` stays the fallback copy. */
|
|
45
|
+
labelPath?: string;
|
|
46
|
+
/** A row boolean that hides the verb on rows that offer no action (an event with no registration). */
|
|
47
|
+
hiddenPath?: string };
|
|
48
|
+
/** The worker action that shares a row (`tier5.<service>.<name>` with `{ id }`): adds Share to the card's overflow menu. */
|
|
49
|
+
shareAction?: string;
|
|
42
50
|
/** A TIME-BOUND entity (an event, a booking, a reservation): the boolean row field the
|
|
43
51
|
* DOMAIN sets once the record has finished — computed by the same rule as the row's own
|
|
44
52
|
* "Past" label, in the same place, so the two cannot disagree. A finished
|
|
@@ -73,7 +81,7 @@ export const COLLECTIONS: Record<string, CollectionConfig> = {
|
|
|
73
81
|
himiBookingBookings: { rows: 'rows', title: 'title', subtitle: 'subtitle', metadata: ['status'], view: 'list', backendQuery: true,
|
|
74
82
|
defaultFilter: 'value:Upcoming', searchPlaceholder: 'Search by booking ID', countNoun: ['booking', 'bookings'], filterValues: ['Upcoming', 'Past', 'Cancelled'],
|
|
75
83
|
sortLabels: { default: 'Soonest', az: 'Oldest', za: 'Latest' } },
|
|
76
|
-
himiEvents: { rows: 'results', title: 'title', subtitle: 'dateLine', image: 'image', view: 'grid', backendQuery: true, defaultFilter: 'value:Upcoming', searchPlaceholder: 'Search events', countNoun: ['event', 'events'], filterValues: ['Upcoming', 'Past'], sortLabels: { default: 'Date', az: 'Title A–Z', za: 'Title Z–A' }, primaryVerb: { label: 'Register' }, endedWhen: 'isPast' },
|
|
84
|
+
himiEvents: { rows: 'results', title: 'title', subtitle: 'dateLine', image: 'image', dateBadge: { text: 'dateBadge', hidden: 'noDateBadge' }, gridColumns: 1, view: 'grid', backendQuery: true, defaultFilter: 'value:Upcoming', searchPlaceholder: 'Search events', countNoun: ['event', 'events'], filterValues: ['Upcoming', 'Past'], sortLabels: { default: 'Date', az: 'Title A–Z', za: 'Title Z–A' }, primaryVerb: { label: 'Register', labelPath: 'actionLabel', hiddenPath: 'noAction' }, shareAction: 'share', endedWhen: 'isPast' },
|
|
77
85
|
himiBlogFeed: { rows: 'posts', title: 'title', subtitle: 'excerpt', image: 'image', filter: 'category', filterValuesFrom: 'categories', view: 'grid', narrowedBy: 'selectedCategoryId' },
|
|
78
86
|
himiOwnerLiteProducts: { rows: 'products', title: 'name', subtitle: 'price', image: 'image', view: 'grid', backendQuery: true, countNoun: ['product', 'products'] },
|
|
79
87
|
himiOwnerModules: { instanceInput: 'module', rows: 'rows', title: 'title', subtitle: 'subtitle', image: 'image', filter: 'statusLabel', view: 'list', paged: true, reviewAction: 'prepareRecord', reviewSelectedAction: 'prepareSelected' },
|
|
@@ -208,7 +216,15 @@ export function projectCollection(source: CollectionRow[], config: CollectionCon
|
|
|
208
216
|
...(config.endedWhen ? (() => {
|
|
209
217
|
const ended = row[config.endedWhen] === true || (config.endedWhen === 'isPast' && row.statusLabel === 'Past');
|
|
210
218
|
return { collectionEnded: ended, collectionNotEnded: !ended };
|
|
211
|
-
})() : {})
|
|
219
|
+
})() : {}),
|
|
220
|
+
// A row restored from state saved by an older build has no badge flag. An unset hidden flag
|
|
221
|
+
// fails open and would paint an empty chip, so it reads as "no badge" until a refresh.
|
|
222
|
+
...(config.dateBadge && typeof row[config.dateBadge.hidden] !== 'boolean'
|
|
223
|
+
? { [config.dateBadge.text]: '', [config.dateBadge.hidden]: true } : {}),
|
|
224
|
+
// Same for a per-row verb: an unset hidden flag fails open and would show a verb with an unresolved
|
|
225
|
+
// label, so a row without the flag offers no action until a refresh establishes one.
|
|
226
|
+
...(config.primaryVerb?.hiddenPath && typeof row[config.primaryVerb.hiddenPath] !== 'boolean'
|
|
227
|
+
? { ...(config.primaryVerb.labelPath ? { [config.primaryVerb.labelPath]: '' } : {}), [config.primaryVerb.hiddenPath]: true } : {}) })),
|
|
212
228
|
filters, loaded: rows.length,
|
|
213
229
|
};
|
|
214
230
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// May a plain owner form round-trip this body? The Ricos and HTML checks are @himalaya/wix-rich-content's;
|
|
2
|
+
// this file adds the read-only previews the forms show for a locked body, and the FAQ's legacy DraftJS answer.
|
|
3
|
+
// Inside the platform source this import is a relative path, so node test runs resolve it; an app's copy
|
|
4
|
+
// imports "@himalaya/wix-rich-content".
|
|
5
|
+
import { htmlIsTrivial } from "@himalaya/wix-rich-content";
|
|
6
|
+
|
|
7
|
+
export { htmlIsTrivial };
|
|
8
|
+
|
|
9
|
+
const ENTITIES: Record<string, string> = { " ": " ", "&": "&", "<": "<", ">": ">", """: "\"", "'": "'" };
|
|
10
|
+
|
|
11
|
+
/** Read-only preview text for an HTML body: block closes become lines, tags are stripped (a bare
|
|
12
|
+
* `<` in prose is kept), the basic entities decode, and blank lines drop. */
|
|
13
|
+
export function htmlPreviewText(html: string | null | undefined): string {
|
|
14
|
+
return (html ?? "").replace(/<br\s*\/?>/gi, "\n").replace(/<\/(p|h[1-6]|li|div|blockquote|pre|tr)>/gi, "\n")
|
|
15
|
+
.replace(/<\/?[a-z!?][^>]*>/gi, "").replace(/&(nbsp|amp|lt|gt|quot|#39);/g, (m) => ENTITIES[m] ?? m)
|
|
16
|
+
.split("\n").map((l) => l.replace(/\s+/g, " ").trim()).filter(Boolean).join("\n");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Preview text for a legacy DraftJS document: its `blocks[].text` joined by a blank line, or ""
|
|
20
|
+
* when the payload is not DraftJS JSON (never a throw). */
|
|
21
|
+
export function draftjsText(raw: string | null | undefined): string {
|
|
22
|
+
try {
|
|
23
|
+
const doc = JSON.parse(raw ?? "") as { blocks?: Array<{ text?: unknown }> } | null;
|
|
24
|
+
const blocks = Array.isArray(doc?.blocks) ? doc.blocks : [];
|
|
25
|
+
return blocks.map((b) => (typeof b?.text === "string" ? b.text : "")).join("\n\n").trim();
|
|
26
|
+
} catch { return ""; }
|
|
27
|
+
}
|