@wix/himalaya-cli 0.1583.0 → 0.1585.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (313) hide show
  1. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/dev-server/src/app-module.d.ts +7 -4
  2. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/bindings.d.ts +7 -6
  3. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/blog-v3/src/extensions.d.ts +2 -0
  4. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/comments-v1/src/extensions.d.ts +2 -0
  5. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/events/src/index.d.ts +3 -0
  6. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/groups/src/extensions.d.ts +15 -0
  7. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/loyalty/src/extensions.d.ts +13 -0
  8. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/members-v1/src/index.d.ts +19 -4
  9. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/core.mjs +2 -2
  10. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/sdui.mjs +8 -2
  11. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-comments.mjs +3 -0
  12. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-events.mjs +4 -2
  13. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-groups.mjs +5 -0
  14. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-loyalty.mjs +4 -0
  15. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-members.mjs +10 -3
  16. package/dist/cli.mjs +2201 -1716
  17. package/dist/preview-assets.generated.bin +0 -0
  18. package/fixtures/wix-canned.json +25 -0
  19. package/guides/branded-lite-site-binding.md +7 -1
  20. package/guides/designing-himi-screens.md +47 -7
  21. package/guides/himi-skill.md +16 -0
  22. package/guides/index.json +1 -0
  23. package/guides/one-app-to-himi-app.md +52 -1
  24. package/guides/sdk-reference.json +37 -9
  25. package/guides/tier-5-add-a-screen.md +9 -0
  26. package/guides/wix-api-usage.md +9 -0
  27. package/package.json +2 -2
  28. package/templates/beauty-salon/config.ts +7 -0
  29. package/templates/beauty-salon/dev/index.ts +758 -352
  30. package/templates/beauty-salon/himalaya.content.json +3 -0
  31. package/templates/beauty-salon/tier5-src/_shared/branded-lite-hosted.ts +1 -1
  32. package/templates/beauty-salon/tier5-src/_shared/collection-contract.ts +19 -3
  33. package/templates/beauty-salon/tier5-src/_shared/himi-restaurants.ts +2 -1
  34. package/templates/beauty-salon/tier5-src/_shared/owner-editor-value.ts +164 -0
  35. package/templates/beauty-salon/tier5-src/_shared/store-product-info.ts +50 -0
  36. package/templates/beauty-salon/tier5-src/himi-blog-post/index.ts +21 -8
  37. package/templates/beauty-salon/tier5-src/himi-branded-lite-category/index.ts +3 -2
  38. package/templates/beauty-salon/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
  39. package/templates/beauty-salon/tier5-src/himi-branded-lite-plans/index.ts +2 -1
  40. package/templates/beauty-salon/tier5-src/himi-store-product/index.ts +14 -3
  41. package/templates/beauty-salon/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
  42. package/templates/beauty-salon/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  43. package/templates/beauty-salon-owner/dev/index.ts +129 -66
  44. package/templates/beauty-salon-owner/tier5-src/_shared/collection-contract.ts +19 -3
  45. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
  46. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
  47. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
  48. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
  49. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
  50. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
  51. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
  52. package/templates/branded-lite/config.ts +9 -0
  53. package/templates/branded-lite/dev/index.ts +4988 -3304
  54. package/templates/branded-lite/himalaya.content.json +3 -0
  55. package/templates/branded-lite/tier5-src/_shared/branded-lite-hosted.ts +1 -1
  56. package/templates/branded-lite/tier5-src/_shared/collection-contract.ts +19 -3
  57. package/templates/branded-lite/tier5-src/_shared/event-registration.ts +86 -0
  58. package/templates/branded-lite/tier5-src/_shared/himi-restaurants.ts +2 -1
  59. package/templates/branded-lite/tier5-src/_shared/owner-editor-value.ts +164 -0
  60. package/templates/branded-lite/tier5-src/_shared/store-product-info.ts +50 -0
  61. package/templates/branded-lite/tier5-src/himi-blog-post/index.ts +21 -8
  62. package/templates/branded-lite/tier5-src/himi-branded-lite-badges/index.ts +2 -1
  63. package/templates/branded-lite/tier5-src/himi-branded-lite-category/index.ts +3 -2
  64. package/templates/branded-lite/tier5-src/himi-branded-lite-feed/index.ts +4 -3
  65. package/templates/branded-lite/tier5-src/himi-branded-lite-group-about/index.ts +243 -0
  66. package/templates/branded-lite/tier5-src/himi-branded-lite-loyalty/index.ts +115 -49
  67. package/templates/branded-lite/tier5-src/himi-branded-lite-plans/index.ts +2 -1
  68. package/templates/branded-lite/tier5-src/himi-branded-lite-podcasts/index.ts +2 -1
  69. package/templates/branded-lite/tier5-src/himi-branded-lite-portfolio/index.ts +2 -1
  70. package/templates/branded-lite/tier5-src/himi-branded-lite-portfolio-project/index.ts +3 -2
  71. package/templates/branded-lite/tier5-src/himi-branded-lite-program/facts.ts +52 -0
  72. package/templates/branded-lite/tier5-src/himi-branded-lite-program/index.ts +21 -11
  73. package/templates/branded-lite/tier5-src/himi-branded-lite-video/index.ts +2 -1
  74. package/templates/branded-lite/tier5-src/himi-events-detail/index.ts +12 -86
  75. package/templates/branded-lite/tier5-src/himi-events-list/index.ts +47 -6
  76. package/templates/branded-lite/tier5-src/himi-store-product/index.ts +13 -3
  77. package/templates/branded-lite/tier5-src/wix-spaces-forum-post/index.ts +3 -2
  78. package/templates/branded-lite/tier5-src/wix-spaces-member-detail/index.ts +53 -37
  79. package/templates/branded-lite/tier5-src/wix-spaces-members/index.ts +100 -34
  80. package/templates/branded-lite/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
  81. package/templates/branded-lite/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  82. package/templates/community-club/config.ts +16 -0
  83. package/templates/community-club/dev/index.ts +1930 -401
  84. package/templates/community-club/himalaya.content.json +6 -0
  85. package/templates/community-club/tier5-src/_shared/branded-lite-hosted.ts +1 -1
  86. package/templates/community-club/tier5-src/_shared/collection-contract.ts +19 -3
  87. package/templates/community-club/tier5-src/_shared/event-registration.ts +86 -0
  88. package/templates/community-club/tier5-src/_shared/himi-restaurants.ts +2 -1
  89. package/templates/community-club/tier5-src/himi-blog-post/index.ts +21 -8
  90. package/templates/community-club/tier5-src/himi-branded-lite-feed/index.ts +4 -3
  91. package/templates/community-club/tier5-src/himi-branded-lite-group-about/index.ts +243 -0
  92. package/templates/community-club/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
  93. package/templates/community-club/tier5-src/himi-events-detail/index.ts +12 -86
  94. package/templates/community-club/tier5-src/himi-events-list/index.ts +47 -6
  95. package/templates/community-club/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  96. package/templates/community-club-owner/dev/index.ts +53 -1
  97. package/templates/community-club-owner/tier5-src/_shared/collection-contract.ts +19 -3
  98. package/templates/community-club-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
  99. package/templates/community-club-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
  100. package/templates/community-club-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
  101. package/templates/community-club-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
  102. package/templates/community-club-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
  103. package/templates/community-club-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
  104. package/templates/community-club-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
  105. package/templates/events-meetups/config.ts +16 -0
  106. package/templates/events-meetups/dev/index.ts +1930 -401
  107. package/templates/events-meetups/himalaya.content.json +6 -0
  108. package/templates/events-meetups/tier5-src/_shared/branded-lite-hosted.ts +1 -1
  109. package/templates/events-meetups/tier5-src/_shared/collection-contract.ts +19 -3
  110. package/templates/events-meetups/tier5-src/_shared/event-registration.ts +86 -0
  111. package/templates/events-meetups/tier5-src/_shared/himi-restaurants.ts +2 -1
  112. package/templates/events-meetups/tier5-src/himi-blog-post/index.ts +21 -8
  113. package/templates/events-meetups/tier5-src/himi-branded-lite-feed/index.ts +4 -3
  114. package/templates/events-meetups/tier5-src/himi-branded-lite-group-about/index.ts +243 -0
  115. package/templates/events-meetups/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
  116. package/templates/events-meetups/tier5-src/himi-events-detail/index.ts +12 -86
  117. package/templates/events-meetups/tier5-src/himi-events-list/index.ts +47 -6
  118. package/templates/events-meetups/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  119. package/templates/events-meetups-owner/dev/index.ts +6 -0
  120. package/templates/events-meetups-owner/tier5-src/_shared/collection-contract.ts +19 -3
  121. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
  122. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
  123. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
  124. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
  125. package/templates/gym-fitness/config.ts +7 -0
  126. package/templates/gym-fitness/dev/index.ts +1115 -278
  127. package/templates/gym-fitness/himalaya.content.json +3 -0
  128. package/templates/gym-fitness/tier5-src/_shared/branded-lite-hosted.ts +1 -1
  129. package/templates/gym-fitness/tier5-src/_shared/collection-contract.ts +19 -3
  130. package/templates/gym-fitness/tier5-src/_shared/event-registration.ts +86 -0
  131. package/templates/gym-fitness/tier5-src/_shared/himi-restaurants.ts +2 -1
  132. package/templates/gym-fitness/tier5-src/_shared/owner-editor-value.ts +164 -0
  133. package/templates/gym-fitness/tier5-src/_shared/store-product-info.ts +50 -0
  134. package/templates/gym-fitness/tier5-src/himi-blog-post/index.ts +21 -8
  135. package/templates/gym-fitness/tier5-src/himi-branded-lite-category/index.ts +3 -2
  136. package/templates/gym-fitness/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
  137. package/templates/gym-fitness/tier5-src/himi-branded-lite-plans/index.ts +2 -1
  138. package/templates/gym-fitness/tier5-src/himi-events-detail/index.ts +12 -86
  139. package/templates/gym-fitness/tier5-src/himi-events-list/index.ts +47 -6
  140. package/templates/gym-fitness/tier5-src/himi-store-product/index.ts +14 -3
  141. package/templates/gym-fitness/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
  142. package/templates/gym-fitness/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  143. package/templates/gym-fitness-owner/dev/index.ts +132 -66
  144. package/templates/gym-fitness-owner/tier5-src/_shared/collection-contract.ts +19 -3
  145. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
  146. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
  147. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
  148. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
  149. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
  150. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
  151. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
  152. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
  153. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
  154. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
  155. package/templates/nonprofit-cause/config.ts +16 -0
  156. package/templates/nonprofit-cause/dev/index.ts +1925 -396
  157. package/templates/nonprofit-cause/himalaya.content.json +6 -0
  158. package/templates/nonprofit-cause/tier5-src/_shared/branded-lite-hosted.ts +1 -1
  159. package/templates/nonprofit-cause/tier5-src/_shared/collection-contract.ts +19 -3
  160. package/templates/nonprofit-cause/tier5-src/_shared/event-registration.ts +86 -0
  161. package/templates/nonprofit-cause/tier5-src/_shared/himi-restaurants.ts +2 -1
  162. package/templates/nonprofit-cause/tier5-src/himi-blog-post/index.ts +21 -8
  163. package/templates/nonprofit-cause/tier5-src/himi-branded-lite-feed/index.ts +4 -3
  164. package/templates/nonprofit-cause/tier5-src/himi-branded-lite-group-about/index.ts +243 -0
  165. package/templates/nonprofit-cause/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
  166. package/templates/nonprofit-cause/tier5-src/himi-branded-lite-plans/index.ts +2 -1
  167. package/templates/nonprofit-cause/tier5-src/himi-events-detail/index.ts +12 -86
  168. package/templates/nonprofit-cause/tier5-src/himi-events-list/index.ts +47 -6
  169. package/templates/nonprofit-cause/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
  170. package/templates/nonprofit-cause/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  171. package/templates/nonprofit-cause-owner/dev/index.ts +85 -65
  172. package/templates/nonprofit-cause-owner/tier5-src/_shared/collection-contract.ts +19 -3
  173. package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-rich-guard.ts +27 -0
  174. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
  175. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
  176. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
  177. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
  178. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
  179. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
  180. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
  181. package/templates/owner-lite/dev/index.ts +132 -66
  182. package/templates/owner-lite/tier5-src/_shared/collection-contract.ts +19 -3
  183. package/templates/owner-lite/tier5-src/himi-owner-lite-event/index.ts +16 -8
  184. package/templates/owner-lite/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
  185. package/templates/owner-lite/tier5-src/himi-owner-lite-events/index.ts +4 -2
  186. package/templates/owner-lite/tier5-src/himi-owner-lite-post/index.ts +7 -0
  187. package/templates/owner-lite/tier5-src/himi-owner-lite-product/index.ts +39 -6
  188. package/templates/owner-lite/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
  189. package/templates/owner-lite/tier5-src/himi-owner-lite-products/index.ts +7 -4
  190. package/templates/owner-lite/tier5-src/himi-owner-lite-service/index.ts +38 -7
  191. package/templates/owner-lite/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
  192. package/templates/owner-lite/tier5-src/himi-owner-lite-services/index.ts +4 -2
  193. package/templates/podcast-creator/config.ts +7 -0
  194. package/templates/podcast-creator/dev/index.ts +1051 -158
  195. package/templates/podcast-creator/himalaya.content.json +3 -0
  196. package/templates/podcast-creator/tier5-src/_shared/branded-lite-hosted.ts +1 -1
  197. package/templates/podcast-creator/tier5-src/_shared/collection-contract.ts +19 -3
  198. package/templates/podcast-creator/tier5-src/_shared/event-registration.ts +86 -0
  199. package/templates/podcast-creator/tier5-src/_shared/himi-restaurants.ts +2 -1
  200. package/templates/podcast-creator/tier5-src/himi-blog-post/index.ts +21 -8
  201. package/templates/podcast-creator/tier5-src/himi-branded-lite-feed/index.ts +4 -3
  202. package/templates/podcast-creator/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
  203. package/templates/podcast-creator/tier5-src/himi-branded-lite-plans/index.ts +2 -1
  204. package/templates/podcast-creator/tier5-src/himi-branded-lite-podcasts/index.ts +2 -1
  205. package/templates/podcast-creator/tier5-src/himi-events-detail/index.ts +12 -86
  206. package/templates/podcast-creator/tier5-src/himi-events-list/index.ts +47 -6
  207. package/templates/podcast-creator/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
  208. package/templates/podcast-creator/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  209. package/templates/podcast-creator-owner/dev/index.ts +53 -1
  210. package/templates/podcast-creator-owner/tier5-src/_shared/collection-contract.ts +19 -3
  211. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
  212. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
  213. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
  214. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
  215. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
  216. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
  217. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
  218. package/templates/portfolio-creative/config.ts +7 -0
  219. package/templates/portfolio-creative/dev/index.ts +1305 -468
  220. package/templates/portfolio-creative/himalaya.content.json +3 -0
  221. package/templates/portfolio-creative/tier5-src/_shared/branded-lite-hosted.ts +1 -1
  222. package/templates/portfolio-creative/tier5-src/_shared/collection-contract.ts +19 -3
  223. package/templates/portfolio-creative/tier5-src/_shared/event-registration.ts +86 -0
  224. package/templates/portfolio-creative/tier5-src/_shared/himi-restaurants.ts +2 -1
  225. package/templates/portfolio-creative/tier5-src/_shared/owner-editor-value.ts +164 -0
  226. package/templates/portfolio-creative/tier5-src/_shared/store-product-info.ts +50 -0
  227. package/templates/portfolio-creative/tier5-src/himi-blog-post/index.ts +21 -8
  228. package/templates/portfolio-creative/tier5-src/himi-branded-lite-category/index.ts +3 -2
  229. package/templates/portfolio-creative/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
  230. package/templates/portfolio-creative/tier5-src/himi-branded-lite-portfolio/index.ts +2 -1
  231. package/templates/portfolio-creative/tier5-src/himi-branded-lite-portfolio-project/index.ts +3 -2
  232. package/templates/portfolio-creative/tier5-src/himi-events-detail/index.ts +12 -86
  233. package/templates/portfolio-creative/tier5-src/himi-events-list/index.ts +47 -6
  234. package/templates/portfolio-creative/tier5-src/himi-store-product/index.ts +14 -3
  235. package/templates/portfolio-creative/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  236. package/templates/portfolio-creative-owner/dev/index.ts +129 -66
  237. package/templates/portfolio-creative-owner/tier5-src/_shared/collection-contract.ts +19 -3
  238. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
  239. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
  240. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
  241. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
  242. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
  243. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
  244. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
  245. package/templates/restaurant/config.ts +7 -0
  246. package/templates/restaurant/dev/index.ts +1051 -158
  247. package/templates/restaurant/himalaya.content.json +3 -0
  248. package/templates/restaurant/tier5-src/_shared/branded-lite-hosted.ts +1 -1
  249. package/templates/restaurant/tier5-src/_shared/collection-contract.ts +19 -3
  250. package/templates/restaurant/tier5-src/_shared/event-registration.ts +86 -0
  251. package/templates/restaurant/tier5-src/_shared/himi-restaurants.ts +2 -1
  252. package/templates/restaurant/tier5-src/himi-blog-post/index.ts +21 -8
  253. package/templates/restaurant/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
  254. package/templates/restaurant/tier5-src/himi-events-detail/index.ts +12 -86
  255. package/templates/restaurant/tier5-src/himi-events-list/index.ts +47 -6
  256. package/templates/restaurant/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  257. package/templates/restaurant-owner/dev/index.ts +132 -66
  258. package/templates/restaurant-owner/tier5-src/_shared/collection-contract.ts +19 -3
  259. package/templates/restaurant-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
  260. package/templates/restaurant-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
  261. package/templates/restaurant-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
  262. package/templates/restaurant-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
  263. package/templates/restaurant-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
  264. package/templates/restaurant-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
  265. package/templates/restaurant-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
  266. package/templates/restaurant-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
  267. package/templates/restaurant-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
  268. package/templates/restaurant-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
  269. package/templates/retail-store/config.ts +7 -0
  270. package/templates/retail-store/dev/index.ts +597 -191
  271. package/templates/retail-store/himalaya.content.json +3 -0
  272. package/templates/retail-store/tier5-src/_shared/branded-lite-hosted.ts +1 -1
  273. package/templates/retail-store/tier5-src/_shared/collection-contract.ts +19 -3
  274. package/templates/retail-store/tier5-src/_shared/himi-restaurants.ts +2 -1
  275. package/templates/retail-store/tier5-src/_shared/owner-editor-value.ts +164 -0
  276. package/templates/retail-store/tier5-src/_shared/store-product-info.ts +50 -0
  277. package/templates/retail-store/tier5-src/himi-blog-post/index.ts +21 -8
  278. package/templates/retail-store/tier5-src/himi-branded-lite-category/index.ts +3 -2
  279. package/templates/retail-store/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
  280. package/templates/retail-store/tier5-src/himi-store-product/index.ts +13 -3
  281. package/templates/retail-store/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  282. package/templates/retail-store-owner/dev/index.ts +50 -1
  283. package/templates/retail-store-owner/tier5-src/_shared/collection-contract.ts +19 -3
  284. package/templates/retail-store-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
  285. package/templates/retail-store-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
  286. package/templates/retail-store-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
  287. package/templates/retail-store-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
  288. package/templates/yoga-studio/config.ts +7 -0
  289. package/templates/yoga-studio/dev/index.ts +1107 -110
  290. package/templates/yoga-studio/himalaya.content.json +3 -0
  291. package/templates/yoga-studio/tier5-src/_shared/branded-lite-hosted.ts +1 -1
  292. package/templates/yoga-studio/tier5-src/_shared/collection-contract.ts +19 -3
  293. package/templates/yoga-studio/tier5-src/_shared/event-registration.ts +86 -0
  294. package/templates/yoga-studio/tier5-src/_shared/himi-restaurants.ts +2 -1
  295. package/templates/yoga-studio/tier5-src/himi-blog-post/index.ts +21 -8
  296. package/templates/yoga-studio/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
  297. package/templates/yoga-studio/tier5-src/himi-branded-lite-plans/index.ts +2 -1
  298. package/templates/yoga-studio/tier5-src/himi-branded-lite-program/facts.ts +52 -0
  299. package/templates/yoga-studio/tier5-src/himi-branded-lite-program/index.ts +21 -11
  300. package/templates/yoga-studio/tier5-src/himi-events-detail/index.ts +12 -86
  301. package/templates/yoga-studio/tier5-src/himi-events-list/index.ts +47 -6
  302. package/templates/yoga-studio/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
  303. package/templates/yoga-studio/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  304. package/templates/yoga-studio-owner/dev/index.ts +85 -65
  305. package/templates/yoga-studio-owner/tier5-src/_shared/collection-contract.ts +19 -3
  306. package/templates/yoga-studio-owner/tier5-src/_shared/owner-rich-guard.ts +27 -0
  307. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
  308. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
  309. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
  310. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
  311. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
  312. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
  313. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
@@ -20,6 +20,7 @@ import { isBridgeUnavailable } from "../_shared/owner-load-error.js";
20
20
  import { isProductSaved, toggleSavedProduct } from "../_shared/himi-store-saved.js";
21
21
  import { openRichLink } from "../_shared/rich-content-link.js";
22
22
  import { descriptionBody } from "../_shared/rich-body.js";
23
+ import { PRODUCT_DETAIL_FIELDS, productInfoSections, type ProductInfoSection } from "../_shared/store-product-info.js";
23
24
 
24
25
  /** Live cart size (sum of line-item quantities) for the top-bar cart badge.
25
26
  * Best-effort: a cart error just yields 0 (badge hidden), never fails the screen. */
@@ -201,6 +202,7 @@ interface S {
201
202
  wasPriceEmpty: boolean;
202
203
  noSku: boolean;
203
204
  skuLabel: string;
205
+ infoSections: ProductInfoSection[];
204
206
  returnPolicyBody: string;
205
207
  shippingInfoBody: string;
206
208
  noReturnPolicyBody: boolean;
@@ -535,6 +537,7 @@ const svc = onlineService<S, {
535
537
  wasPriceEmpty: false,
536
538
  skuLabel: "",
537
539
  noSku: true,
540
+ infoSections: [],
538
541
  returnPolicyBody: "",
539
542
  shippingInfoBody: "",
540
543
  noReturnPolicyBody: true,
@@ -625,7 +628,7 @@ const svc = onlineService<S, {
625
628
  try { saved = isProductSaved(id); } catch { /* save action reports a retryable error */ }
626
629
  s = { ...s, saved, saveHint: "",
627
630
  optionValidationTarget: "",
628
- ...(id !== lastLoadedId ? { adding: false, added: false, shareHint: "", addedSheetPresented: false, quantity: 1, showOptionErrors: false, optionValidationRequest: 0, galleryIndex: 0, returnPolicyExpanded: false, shippingInfoExpanded: false } : {}) };
631
+ ...(id !== lastLoadedId ? { adding: false, added: false, shareHint: "", addedSheetPresented: false, quantity: 1, showOptionErrors: false, optionValidationRequest: 0, galleryIndex: 0, returnPolicyExpanded: false, shippingInfoExpanded: false, infoSections: [] } : {}) };
629
632
  // A fresh navigation into the product resets any quantity left over
630
633
  // from a previous visit to the same worker instance.
631
634
  if (!id) {
@@ -642,8 +645,8 @@ const svc = onlineService<S, {
642
645
  void cartCount.then((n) => { cartKnown = n; }, () => {});
643
646
  // The live product read goes out FIRST too — the local-db read below must never delay it.
644
647
  // Settled into a value so a failure is handled where it is awaited, never unhandled.
645
- // Read both the Ricos description and choice-linked images; V3 omits these fields by default.
646
- const live = getStoreProduct(id, ["DESCRIPTION", "PRODUCT_CHOICES_DISPLAY_IMAGE"], readOptions(arg)).then(
648
+ // Read the Ricos description, the Product Info sections (V3) and choice-linked images; V3 omits them by default.
649
+ const live = getStoreProduct(id, [...PRODUCT_DETAIL_FIELDS, "PRODUCT_CHOICES_DISPLAY_IMAGE"], readOptions(arg)).then(
647
650
  (r) => ({ ok: true as const, r }),
648
651
  (error) => ({ ok: false as const, error }),
649
652
  );
@@ -702,6 +705,7 @@ const svc = onlineService<S, {
702
705
  ...sale,
703
706
  commercePrice: sale.price,
704
707
  skuLabel: skuOf(p) ? `SKU: ${skuOf(p)}` : "",
708
+ infoSections: productInfoSections(p, base.infoSections),
705
709
  returnPolicyBody: productPolicyBody(p, "returns") || copyParam("product.returnPolicyBody", "") || copyParam("product.policyUnavailable", "Policy details have not been provided by this store."),
706
710
  shippingInfoBody: productPolicyBody(p, "shipping") || copyParam("product.shippingInfoBody", "") || copyParam("product.policyUnavailable", "Policy details have not been provided by this store."),
707
711
  ...productBody(p),
@@ -721,6 +725,12 @@ const svc = onlineService<S, {
721
725
  const quantity = parseQuantity(argValue(arg, "value"));
722
726
  return quantity ? derive({ ...s, quantity }) : s;
723
727
  },
728
+ toggleInfoSection: (s, arg) => {
729
+ const id = argValue(arg, "id");
730
+ if (!s.infoSections.some(section => section.id === id && !section.noTitle)) return s;
731
+ return derive({ ...s, infoSections: s.infoSections.map(section => section.id === id
732
+ ? { ...section, expanded: !section.expanded, collapsed: section.expanded } : section) });
733
+ },
724
734
  toggleReturnPolicy: s => derive({ ...s, returnPolicyExpanded: !s.returnPolicyExpanded }),
725
735
  toggleShippingInfo: s => derive({ ...s, shippingInfoExpanded: !s.shippingInfoExpanded }),
726
736
  // One chip row per option group. `group` is the descriptor slot ("1".."3");
@@ -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 || aa.bodyText || "" };
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({
@@ -78707,6 +78707,51 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
78707
78707
  }
78708
78708
  }
78709
78709
  },
78710
+ {
78711
+ "id": "product_body",
78712
+ "body": {
78713
+ "package": "himalaya",
78714
+ "type": "RichContent",
78715
+ "props": {
78716
+ "documentJsonPath": "$service:himiOwnerLiteProduct.bodyJson",
78717
+ "onLink": {
78718
+ "actionId": "tier5.himiOwnerLiteProduct.openLink"
78719
+ },
78720
+ "fallback": {
78721
+ "id": "",
78722
+ "body": {
78723
+ "package": "himalaya",
78724
+ "type": "Text",
78725
+ "props": {
78726
+ "text": "$service:himiOwnerLiteProduct.bodyText",
78727
+ "style": "body",
78728
+ "color": "textPrimary",
78729
+ "collapseWhenEmpty": true
78730
+ }
78731
+ }
78732
+ }
78733
+ }
78734
+ },
78735
+ "modifiers": {
78736
+ "hiddenPath": "$service:himiOwnerLiteProduct.noBodyJson"
78737
+ }
78738
+ },
78739
+ {
78740
+ "id": "product_body_text",
78741
+ "body": {
78742
+ "package": "himalaya",
78743
+ "type": "Text",
78744
+ "props": {
78745
+ "text": "$service:himiOwnerLiteProduct.bodyText",
78746
+ "style": "body",
78747
+ "color": "textPrimary",
78748
+ "collapseWhenEmpty": true
78749
+ }
78750
+ },
78751
+ "modifiers": {
78752
+ "hiddenPath": "$service:himiOwnerLiteProduct.hasBodyJson"
78753
+ }
78754
+ },
78710
78755
  {
78711
78756
  "id": "product_info_card",
78712
78757
  "body": {
@@ -79129,7 +79174,8 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
79129
79174
  "contentType": "application/javascript+ts-bundle",
79130
79175
  "declaredCapabilities": [
79131
79176
  "wix_api",
79132
- "local_database"
79177
+ "local_database",
79178
+ "open_url"
79133
79179
  ],
79134
79180
  "minBinaryVersion": "0.1.0",
79135
79181
  "bundleVersion": "0.0.1"
@@ -79733,6 +79779,9 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
79733
79779
  }
79734
79780
  }
79735
79781
  }
79782
+ },
79783
+ "modifiers": {
79784
+ "hiddenPath": "$service:himiOwnerLitePost.noBodyJson"
79736
79785
  }
79737
79786
  },
79738
79787
  {
@@ -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
  }
@@ -55,6 +55,7 @@ interface PostState {
55
55
  bodyJson: string;
56
56
  /** bodyJson !== "" — gates the plain text, because RichContent draws nothing for "". */
57
57
  hasBodyJson: boolean;
58
+ noBodyJson: boolean;
58
59
  /** Plain text of the body: RichContent's `fallback`, and the offline copy's body. */
59
60
  bodyText: string;
60
61
  // Info rows
@@ -151,6 +152,7 @@ function shapeFields(s: Partial<PostState>): PostState {
151
152
  image,
152
153
  bodyJson: s.bodyJson ?? "",
153
154
  hasBodyJson: !!s.bodyJson,
155
+ noBodyJson: !s.bodyJson,
154
156
  bodyText: s.bodyText ?? "",
155
157
  postStatus: s.postStatus ?? statusLabel(raw),
156
158
  category: s.category ?? "—",
@@ -485,4 +487,9 @@ if ((globalThis as { himalaya?: { hydrationOptOut?: unknown } }).himalaya?.hydra
485
487
  if (booted && typeof booted === "object") Object.assign(booted, { deletePending: false, noDeleteConfirmation: true });
486
488
  }
487
489
 
490
+ // Hydration shallow-merges older snapshots over defaults; derive both body gates from
491
+ // the restored document before the first paint, without waiting for a load action.
492
+ const bootedBody = svc.getState();
493
+ Object.assign(bootedBody, { hasBodyJson: !!bootedBody.bodyJson, noBodyJson: !bootedBody.bodyJson });
494
+
488
495
  export { svc };
@@ -1,3 +1,5 @@
1
+ import { descriptionBody } from "../_shared/rich-body.js";
2
+ import { openRichLink } from "../_shared/rich-content-link.js";
1
3
  // Tier-5 bundle: __HIMI_APP_NAME__ — Store product DETAIL + show/hide (visibility).
2
4
  // Inner admin page opened from the products list (himi_owner_lite_product_<id>).
3
5
  // Uses the Stores v1 client (the Apptestersite catalog is v1; v3 428s) — getProduct
@@ -6,7 +8,7 @@
6
8
 
7
9
  import { defineService } from "@himalaya/state";
8
10
  import { getProduct, updateProduct, deleteProduct, type WixProduct } from "@himalaya/wix-stores";
9
- import { plainText, productImage, wixMediaUrl, WIX_DETAIL_IMAGE, type StoreProduct } from "../_shared/himi-store.js";
11
+ import { productImage, wixMediaUrl, WIX_DETAIL_IMAGE, type StoreProduct } from "../_shared/himi-store.js";
10
12
  import { ownerLoadError, isOwnerPreviewDemo, ownerDemoFallback, ownerWriteError, isNotFound } from "../_shared/owner-load-error.js";
11
13
  import { DEMO_PRODUCTS, DEMO_NOTE, DEMO_SAVE_NOTE } from "../_shared/owner-preview-demo.js";
12
14
  import { stashCopy, copyParam } from "../_shared/himi-copy.js";
@@ -33,6 +35,10 @@ interface ProductState {
33
35
  title: string;
34
36
  subtitle: string;
35
37
  summary: string;
38
+ bodyJson: string;
39
+ bodyText: string;
40
+ hasBodyJson: boolean;
41
+ noBodyJson: boolean;
36
42
  initial: string;
37
43
  image: string;
38
44
  // Info rows
@@ -133,6 +139,10 @@ function shapeFields(s: Partial<ProductState>): ProductState {
133
139
  title: s.title ?? "",
134
140
  subtitle: s.subtitle ?? "",
135
141
  summary: s.summary ?? "",
142
+ bodyJson: s.bodyJson ?? "",
143
+ bodyText: s.bodyText ?? "",
144
+ hasBodyJson: !!s.bodyJson,
145
+ noBodyJson: !s.bodyJson,
136
146
  initial: s.initial ?? "?",
137
147
  image,
138
148
  price: s.price ?? "—",
@@ -170,7 +180,9 @@ function demoDetail(s: ProductState, id: string): ProductState | null {
170
180
  status: "ready",
171
181
  title: d.name,
172
182
  subtitle: d.visible ? "Visible in store" : "Hidden from store",
173
- summary: d.description,
183
+ summary: "",
184
+ bodyText: d.description,
185
+ bodyJson: "",
174
186
  initial: (d.name[0] || "?").toUpperCase(),
175
187
  image: "",
176
188
  price: d.price,
@@ -190,7 +202,9 @@ function cacheRow(s: ProductState): DbEntity {
190
202
  name: s.title,
191
203
  title: s.title,
192
204
  subtitle: s.subtitle,
193
- summary: s.summary,
205
+ summary: s.bodyText,
206
+ bodyJson: s.bodyJson,
207
+ bodyText: s.bodyText,
194
208
  initial: s.initial,
195
209
  image: s.image,
196
210
  price: s.price,
@@ -204,6 +218,7 @@ function cacheRow(s: ProductState): DbEntity {
204
218
  /** Rehydrate a ready detail from a last-synced local row (offline read fallback). */
205
219
  function cachedDetail(s: ProductState, row: DbEntity): ProductState {
206
220
  const visible = row.visible !== "false";
221
+ const body = descriptionBody(row.bodyJson || row.description, descriptionBody(row.bodyText || row.summary).bodyText);
207
222
  const title = String(row.title ?? row.name ?? "");
208
223
  return shape({
209
224
  ...s,
@@ -211,7 +226,9 @@ function cachedDetail(s: ProductState, row: DbEntity): ProductState {
211
226
  status: "ready",
212
227
  title,
213
228
  subtitle: String(row.subtitle ?? (visible ? "Visible in store" : "Hidden from store")),
214
- summary: String(row.summary ?? ""),
229
+ summary: "",
230
+ bodyJson: body.bodyJson,
231
+ bodyText: body.bodyText,
215
232
  initial: String(row.initial ?? (title[0] || "?")).slice(0, 1).toUpperCase(),
216
233
  image: String(row.image ?? ""),
217
234
  price: String(row.price ?? "—"),
@@ -220,25 +237,29 @@ function cachedDetail(s: ProductState, row: DbEntity): ProductState {
220
237
  inventory: String(row.inventory ?? "—"),
221
238
  visibleRaw: visible,
222
239
  error: "",
240
+ actionMessage: "",
223
241
  demoNote: "",
224
242
  });
225
243
  }
226
244
 
227
245
  async function refresh(prev: ProductState, id: string, actionMessage = ""): Promise<ProductState> {
228
- const res = await getProduct(id);
246
+ const res = await getProduct(id, { richDescription: true });
229
247
  const p = (res.product ?? res) as WixProduct;
230
248
  if (!p || !(p as any).id) {
231
249
  return shape({ ...prev, id, status: "error", title: "", error: copyParam("ownerProduct.errorNotFound", "product not found"), actionMessage });
232
250
  }
233
251
  const name = ((p as any).name || "Untitled product").trim();
234
252
  const visible = (p as any).visible !== false;
253
+ const body = descriptionBody((p as { richDescription?: unknown }).richDescription ?? (p as any).description, descriptionBody((p as any).description || (p as any).plainDescription).bodyText);
235
254
  return shape({
236
255
  ...prev,
237
256
  id,
238
257
  status: "ready",
239
258
  title: name,
240
259
  subtitle: visible ? "Visible in store" : "Hidden from store",
241
- summary: plainText((p as any).description || ""),
260
+ summary: "",
261
+ bodyJson: body.bodyJson,
262
+ bodyText: body.bodyText,
242
263
  initial: (name[0] || "?").toUpperCase(),
243
264
  image: imageOf(p),
244
265
  price: priceOf(p),
@@ -300,6 +321,7 @@ const svc = defineService<ProductState, {
300
321
  show: (s: ProductState) => Promise<ProductState>;
301
322
  hide: (s: ProductState) => Promise<ProductState>;
302
323
  delete: (s: ProductState) => Promise<ProductState>;
324
+ openLink: (s: ProductState, arg?: unknown) => Promise<ProductState>;
303
325
  cancelDelete: (s: ProductState) => Promise<ProductState>;
304
326
  confirmDelete: (s: ProductState) => Promise<ProductState | undefined>;
305
327
  }>("himiOwnerLiteProduct", {
@@ -308,6 +330,12 @@ const svc = defineService<ProductState, {
308
330
  // perVisit: a cached embed's warm return starts this run fresh, as a cold boot does (`__resetRunState`).
309
331
  perVisit: [...DELETE_RUN_KEYS],
310
332
  actions: {
333
+ openLink: async (_state, arg): Promise<ProductState> => {
334
+ const opened = await openRichLink(arg);
335
+ const failed = copyParam("ownerProduct.linkOpenFailed", "This link could not be opened.");
336
+ const current = svc.getState();
337
+ return shape({ ...current, actionMessage: opened ? (current.actionMessage === failed ? "" : current.actionMessage) : failed });
338
+ },
311
339
  load: async (s0, arg) => {
312
340
  const s = disarm(s0);
313
341
  stashCopy(arg); // absorb the descriptor's onAppear copy-pack param
@@ -394,4 +422,9 @@ if ((globalThis as { himalaya?: { hydrationOptOut?: unknown } }).himalaya?.hydra
394
422
  if (booted && typeof booted === "object") Object.assign(booted, { deletePending: false, noDeleteConfirmation: true });
395
423
  }
396
424
 
425
+ // Hydration shallow-merges older snapshots over defaults; derive both body gates from
426
+ // the restored document before the first paint, without waiting for a load action.
427
+ const bootedBody = svc.getState();
428
+ Object.assign(bootedBody, { hasBodyJson: !!bootedBody.bodyJson, noBodyJson: !bootedBody.bodyJson });
429
+
397
430
  export { svc };
@@ -1,3 +1,4 @@
1
+ import { descriptionBody } from "../_shared/rich-body.js";
1
2
  // Tier-5 bundle: __HIMI_APP_NAME__ — create/edit Store product (the CRUD "C" + "U").
2
3
  // Opened from the products list ("New product") or a product detail ("Edit").
3
4
  // The Apptestersite catalog is Stores v1 (v3 428s), so this uses the v1 client:
@@ -243,19 +244,23 @@ const svc = defineService<ProductFormState, {
243
244
  name: (p as any).name ?? "",
244
245
  price: priceOf(p),
245
246
  sku: (p as any).sku ?? "",
246
- ...((html: string, rich: unknown) => {
247
+ ...((raw: unknown, rich: unknown) => {
248
+ const html = typeof raw === "string" ? raw : "";
249
+ const preview = htmlPreviewText(html);
250
+ const description = descriptionBody(raw);
251
+ const legacyRich = !!parseRicosJson(raw) || (raw != null && typeof raw !== "string") || (!!preview.trim() && !description.bodyText);
247
252
  // `richDescription` is present only on a Catalog V3 site. V3 is edited in the RichContentEditor;
248
253
  // a V3 product whose Ricos document did not come back is edited only when its HTML is trivial
249
254
  // (seeded as paragraphs), else locked — fail closed. V1 keeps the plain/locked split: the
250
255
  // editor writes Ricos, and a V1 description is HTML.
251
256
  const doc = rich === undefined || rich === null ? null : parseRicosJson(rich);
252
257
  const hasDoc = !!doc && doc.nodes.length > 0;
253
- const text = htmlPreviewText(html);
254
- const descriptionMode = rich === undefined ? (htmlIsTrivial(html) ? "plain" as const : "locked" as const)
258
+ const text = descriptionBody(rich, legacyRich ? description.bodyText : preview).bodyText;
259
+ const descriptionMode = rich === undefined ? (!legacyRich && htmlIsTrivial(html) ? "plain" as const : "locked" as const)
255
260
  : hasDoc || htmlIsTrivial(html) ? "editor" as const : "locked" as const;
256
- const descriptionJson = descriptionMode !== "editor" ? "" : hasDoc ? JSON.stringify(rich) : text ? docJson(plainPostBody(text)) : "";
261
+ const descriptionJson = descriptionMode !== "editor" ? "" : hasDoc ? JSON.stringify(doc) : text ? docJson(plainPostBody(text)) : "";
257
262
  return { ...DESCRIPTION_LOADED, description: text, originalDescription: text, descriptionMode, descriptionJson };
258
- })(String((p as any).description ?? ""), (p as { richDescription?: unknown }).richDescription),
263
+ })((p as any).description, (p as { richDescription?: unknown }).richDescription),
259
264
  visible: (p as any).visible !== false ? "true" : "false",
260
265
  status: "idle",
261
266
  error: "",
@@ -265,12 +270,13 @@ const svc = defineService<ProductFormState, {
265
270
  // Offline: prefill from the last-synced local cache before the demo/error fallbacks.
266
271
  const cached = await cacheGet(id);
267
272
  if (cached) {
273
+ const description = descriptionBody(cached.descriptionJson || cached.bodyJson, descriptionBody(cached.description ?? cached.bodyText ?? cached.summary).bodyText).bodyText;
268
274
  return shape({
269
275
  ...s, mode: "edit", id, heading: "Edit product",
270
276
  name: String(cached.name ?? ""), price: editablePrice(String(cached.price ?? "")), sku: String(cached.sku ?? ""),
271
- description: String(cached.description ?? ""), originalDescription: String(cached.description ?? ""), ...DESCRIPTION_LOADED,
272
- // A row cached with its document reopens in the editor. An older row has none, so its verdict
273
- // decides: plain when it was plain, else locked (it carries no verdict either: fail closed).
277
+ description, originalDescription: description, ...DESCRIPTION_LOADED,
278
+ // Only the form's document establishes its editor mode. Detail bodyJson can also come
279
+ // from a V1 catalog, so it supplies the preview without guessing a V3 write contract.
274
280
  ...(cached.descriptionJson ? { descriptionMode: "editor" as const, descriptionJson: String(cached.descriptionJson) }
275
281
  : { descriptionMode: cached.descriptionProtected === "false" ? "plain" as const : "locked" as const, descriptionJson: "" }),
276
282
  visible: cached.visible === "false" ? "false" : "true",
@@ -1,3 +1,4 @@
1
+ import { descriptionBody } from "../_shared/rich-body.js";
1
2
  // Tier-5 bundle: __HIMI_APP_NAME__ — Store products management list.
2
3
  // Owner/management view of the active business's Wix Stores catalog. Site-scoped
3
4
  // through the native wix-native (mode:owner) provider + WixApiCapability, which
@@ -6,11 +7,11 @@
6
7
 
7
8
  import { compareText } from "../_shared/engine-intl.js";
8
9
  import { defineBackendCollection } from "../_shared/collection-service.js";
9
- import { searchStoreProducts, productImage, productPrice, plainText, type StoreProduct } from "../_shared/himi-store.js";
10
+ import { searchStoreProducts, productImage, productPrice, type StoreProduct } from "../_shared/himi-store.js";
10
11
  import { ownerLoadError, isOwnerPreviewDemo, ownerDemoFallback } from "../_shared/owner-load-error.js";
11
12
  import { DEMO_PRODUCTS, DEMO_NOTE } from "../_shared/owner-preview-demo.js";
12
13
  import { copyParam } from "../_shared/himi-copy.js";
13
- import { getAll, upsert, type DbEntity } from "../_shared/owner-local-db.js";
14
+ import { get, getAll, upsert, type DbEntity } from "../_shared/owner-local-db.js";
14
15
 
15
16
  // Offline-first (data-offline): the owner's last-synced rows are the READ-THROUGH
16
17
  // cache for the `owner_products` entity — paint them instantly (works offline),
@@ -24,7 +25,9 @@ async function readCachedRows(): Promise<ProductRow[]> {
24
25
  try { return (await getAll(ENTITY)) as unknown as ProductRow[]; } catch { return []; }
25
26
  }
26
27
  async function writeCachedRows(rows: ProductRow[]): Promise<void> {
27
- try { for (const r of rows) await upsert(ENTITY, r as unknown as DbEntity); } catch { /* capability not granted → online-only */ }
28
+ try {
29
+ for (const r of rows) await upsert(ENTITY, { ...await get(ENTITY, r.id), ...r, title: r.name } as unknown as DbEntity);
30
+ } catch { /* capability not granted → online-only */ }
28
31
  }
29
32
 
30
33
  interface ProductRow {
@@ -76,7 +79,7 @@ function normalize(raw: StoreProduct): ProductRow {
76
79
  const name = (raw.name || "Untitled product").trim();
77
80
  const image = productImage(raw);
78
81
  const price = productPrice(raw);
79
- const desc = plainText(raw.plainDescription || raw.description);
82
+ const desc = descriptionBody(raw.description, descriptionBody(raw.plainDescription).bodyText).bodyText;
80
83
  return {
81
84
  id: raw.id || "",
82
85
  name,
@@ -238,6 +238,13 @@ export default defineApp({
238
238
  "parentScreenId": "himi_blog",
239
239
  "tabId": "home"
240
240
  },
241
+ {
242
+ "screenId": "himi_notif_settings",
243
+ "isPublic": true,
244
+ "paramKeys": [],
245
+ "parentScreenId": "himi_account",
246
+ "tabId": "profile"
247
+ },
241
248
  {
242
249
  "screenId": "himi_events",
243
250
  "isPublic": true,