@wix/himalaya-cli 0.1582.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.
Files changed (336) hide show
  1. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/dev-server/src/builder.d.ts +8 -0
  2. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/schema.d.ts +26 -2
  3. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/validator.d.ts +18 -0
  4. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/blog-v3/src/extensions.d.ts +2 -0
  5. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/comments-v1/src/extensions.d.ts +2 -0
  6. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/events/src/index.d.ts +3 -0
  7. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/groups/src/extensions.d.ts +15 -0
  8. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/loyalty/src/extensions.d.ts +13 -0
  9. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/members-v1/src/index.d.ts +19 -4
  10. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/core.mjs +5 -1
  11. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/sdui.mjs +5 -1
  12. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-comments.mjs +3 -0
  13. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-events.mjs +4 -2
  14. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-groups.mjs +5 -0
  15. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-loyalty.mjs +4 -0
  16. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-members.mjs +10 -3
  17. package/dist/cli.mjs +1098 -702
  18. package/dist/preview-assets.generated.bin +0 -0
  19. package/fixtures/wix-canned.json +25 -0
  20. package/guides/component-reference.json +4 -3
  21. package/guides/component-reference.md +24 -2
  22. package/guides/one-app-to-himi-app.md +52 -1
  23. package/guides/sdk-reference.json +37 -9
  24. package/guides/wix-api-usage.md +9 -0
  25. package/package.json +2 -2
  26. package/templates/beauty-salon/config.ts +27 -1
  27. package/templates/beauty-salon/dev/index.ts +2285 -757
  28. package/templates/beauty-salon/himalaya.content.json +3 -0
  29. package/templates/beauty-salon/tier5-src/_shared/booking-location.ts +147 -0
  30. package/templates/beauty-salon/tier5-src/_shared/booking-session.ts +222 -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-booking-service/index.ts +277 -14
  38. package/templates/beauty-salon/tier5-src/himi-booking-services/index.ts +351 -92
  39. package/templates/beauty-salon/tier5-src/himi-booking-time/index.ts +25 -5
  40. package/templates/beauty-salon/tier5-src/himi-branded-lite-agenda/index.ts +219 -220
  41. package/templates/beauty-salon/tier5-src/himi-branded-lite-category/index.ts +3 -2
  42. package/templates/beauty-salon/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
  43. package/templates/beauty-salon/tier5-src/himi-branded-lite-plans/index.ts +2 -1
  44. package/templates/beauty-salon/tier5-src/himi-store-product/index.ts +14 -3
  45. package/templates/beauty-salon/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
  46. package/templates/beauty-salon/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  47. package/templates/beauty-salon-owner/dev/index.ts +129 -66
  48. package/templates/beauty-salon-owner/tier5-src/_shared/collection-contract.ts +19 -3
  49. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
  50. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
  51. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
  52. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
  53. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
  54. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
  55. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
  56. package/templates/branded-lite/config.ts +29 -1
  57. package/templates/branded-lite/dev/index.ts +8371 -5565
  58. package/templates/branded-lite/himalaya.content.json +3 -0
  59. package/templates/branded-lite/l10n/en.json +2 -2
  60. package/templates/branded-lite/tier5-src/_shared/booking-location.ts +147 -0
  61. package/templates/branded-lite/tier5-src/_shared/booking-session.ts +222 -0
  62. package/templates/branded-lite/tier5-src/_shared/branded-lite-hosted.ts +1 -1
  63. package/templates/branded-lite/tier5-src/_shared/collection-contract.ts +19 -3
  64. package/templates/branded-lite/tier5-src/_shared/event-registration.ts +86 -0
  65. package/templates/branded-lite/tier5-src/_shared/himi-restaurants.ts +2 -1
  66. package/templates/branded-lite/tier5-src/_shared/owner-editor-value.ts +164 -0
  67. package/templates/branded-lite/tier5-src/_shared/store-product-info.ts +50 -0
  68. package/templates/branded-lite/tier5-src/himi-blog-post/index.ts +21 -8
  69. package/templates/branded-lite/tier5-src/himi-booking-service/index.ts +277 -14
  70. package/templates/branded-lite/tier5-src/himi-booking-services/index.ts +351 -92
  71. package/templates/branded-lite/tier5-src/himi-booking-time/index.ts +25 -5
  72. package/templates/branded-lite/tier5-src/himi-branded-lite-agenda/index.ts +219 -220
  73. package/templates/branded-lite/tier5-src/himi-branded-lite-badges/index.ts +2 -1
  74. package/templates/branded-lite/tier5-src/himi-branded-lite-category/index.ts +3 -2
  75. package/templates/branded-lite/tier5-src/himi-branded-lite-feed/index.ts +4 -3
  76. package/templates/branded-lite/tier5-src/himi-branded-lite-group-about/index.ts +243 -0
  77. package/templates/branded-lite/tier5-src/himi-branded-lite-loyalty/index.ts +115 -49
  78. package/templates/branded-lite/tier5-src/himi-branded-lite-plans/index.ts +2 -1
  79. package/templates/branded-lite/tier5-src/himi-branded-lite-podcasts/index.ts +2 -1
  80. package/templates/branded-lite/tier5-src/himi-branded-lite-portfolio/index.ts +2 -1
  81. package/templates/branded-lite/tier5-src/himi-branded-lite-portfolio-project/index.ts +3 -2
  82. package/templates/branded-lite/tier5-src/himi-branded-lite-program/facts.ts +52 -0
  83. package/templates/branded-lite/tier5-src/himi-branded-lite-program/index.ts +21 -11
  84. package/templates/branded-lite/tier5-src/himi-branded-lite-video/index.ts +2 -1
  85. package/templates/branded-lite/tier5-src/himi-events-detail/index.ts +12 -86
  86. package/templates/branded-lite/tier5-src/himi-events-list/index.ts +47 -6
  87. package/templates/branded-lite/tier5-src/himi-store-product/index.ts +13 -3
  88. package/templates/branded-lite/tier5-src/wix-spaces-forum-post/index.ts +3 -2
  89. package/templates/branded-lite/tier5-src/wix-spaces-member-detail/index.ts +53 -37
  90. package/templates/branded-lite/tier5-src/wix-spaces-members/index.ts +100 -34
  91. package/templates/branded-lite/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
  92. package/templates/branded-lite/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  93. package/templates/community-club/config.ts +36 -1
  94. package/templates/community-club/dev/index.ts +1930 -401
  95. package/templates/community-club/himalaya.content.json +6 -0
  96. package/templates/community-club/tier5-src/_shared/branded-lite-hosted.ts +1 -1
  97. package/templates/community-club/tier5-src/_shared/collection-contract.ts +19 -3
  98. package/templates/community-club/tier5-src/_shared/event-registration.ts +86 -0
  99. package/templates/community-club/tier5-src/_shared/himi-restaurants.ts +2 -1
  100. package/templates/community-club/tier5-src/himi-blog-post/index.ts +21 -8
  101. package/templates/community-club/tier5-src/himi-branded-lite-feed/index.ts +4 -3
  102. package/templates/community-club/tier5-src/himi-branded-lite-group-about/index.ts +243 -0
  103. package/templates/community-club/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
  104. package/templates/community-club/tier5-src/himi-events-detail/index.ts +12 -86
  105. package/templates/community-club/tier5-src/himi-events-list/index.ts +47 -6
  106. package/templates/community-club/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  107. package/templates/community-club-owner/dev/index.ts +53 -1
  108. package/templates/community-club-owner/tier5-src/_shared/collection-contract.ts +19 -3
  109. package/templates/community-club-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
  110. package/templates/community-club-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
  111. package/templates/community-club-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
  112. package/templates/community-club-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
  113. package/templates/community-club-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
  114. package/templates/community-club-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
  115. package/templates/community-club-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
  116. package/templates/events-meetups/config.ts +36 -1
  117. package/templates/events-meetups/dev/index.ts +1930 -401
  118. package/templates/events-meetups/himalaya.content.json +6 -0
  119. package/templates/events-meetups/tier5-src/_shared/branded-lite-hosted.ts +1 -1
  120. package/templates/events-meetups/tier5-src/_shared/collection-contract.ts +19 -3
  121. package/templates/events-meetups/tier5-src/_shared/event-registration.ts +86 -0
  122. package/templates/events-meetups/tier5-src/_shared/himi-restaurants.ts +2 -1
  123. package/templates/events-meetups/tier5-src/himi-blog-post/index.ts +21 -8
  124. package/templates/events-meetups/tier5-src/himi-branded-lite-feed/index.ts +4 -3
  125. package/templates/events-meetups/tier5-src/himi-branded-lite-group-about/index.ts +243 -0
  126. package/templates/events-meetups/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
  127. package/templates/events-meetups/tier5-src/himi-events-detail/index.ts +12 -86
  128. package/templates/events-meetups/tier5-src/himi-events-list/index.ts +47 -6
  129. package/templates/events-meetups/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  130. package/templates/events-meetups-owner/dev/index.ts +6 -0
  131. package/templates/events-meetups-owner/tier5-src/_shared/collection-contract.ts +19 -3
  132. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
  133. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
  134. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
  135. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
  136. package/templates/gym-fitness/config.ts +27 -1
  137. package/templates/gym-fitness/dev/index.ts +2803 -844
  138. package/templates/gym-fitness/himalaya.content.json +3 -0
  139. package/templates/gym-fitness/tier5-src/_shared/booking-location.ts +147 -0
  140. package/templates/gym-fitness/tier5-src/_shared/booking-session.ts +222 -0
  141. package/templates/gym-fitness/tier5-src/_shared/branded-lite-hosted.ts +1 -1
  142. package/templates/gym-fitness/tier5-src/_shared/collection-contract.ts +19 -3
  143. package/templates/gym-fitness/tier5-src/_shared/event-registration.ts +86 -0
  144. package/templates/gym-fitness/tier5-src/_shared/himi-restaurants.ts +2 -1
  145. package/templates/gym-fitness/tier5-src/_shared/owner-editor-value.ts +164 -0
  146. package/templates/gym-fitness/tier5-src/_shared/store-product-info.ts +50 -0
  147. package/templates/gym-fitness/tier5-src/himi-blog-post/index.ts +21 -8
  148. package/templates/gym-fitness/tier5-src/himi-booking-service/index.ts +277 -14
  149. package/templates/gym-fitness/tier5-src/himi-booking-services/index.ts +351 -92
  150. package/templates/gym-fitness/tier5-src/himi-booking-time/index.ts +25 -5
  151. package/templates/gym-fitness/tier5-src/himi-branded-lite-agenda/index.ts +219 -220
  152. package/templates/gym-fitness/tier5-src/himi-branded-lite-category/index.ts +3 -2
  153. package/templates/gym-fitness/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
  154. package/templates/gym-fitness/tier5-src/himi-branded-lite-plans/index.ts +2 -1
  155. package/templates/gym-fitness/tier5-src/himi-events-detail/index.ts +12 -86
  156. package/templates/gym-fitness/tier5-src/himi-events-list/index.ts +47 -6
  157. package/templates/gym-fitness/tier5-src/himi-store-product/index.ts +14 -3
  158. package/templates/gym-fitness/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
  159. package/templates/gym-fitness/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  160. package/templates/gym-fitness-owner/dev/index.ts +132 -66
  161. package/templates/gym-fitness-owner/tier5-src/_shared/collection-contract.ts +19 -3
  162. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
  163. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
  164. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
  165. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
  166. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
  167. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
  168. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
  169. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
  170. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
  171. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
  172. package/templates/nonprofit-cause/config.ts +36 -1
  173. package/templates/nonprofit-cause/dev/index.ts +1925 -396
  174. package/templates/nonprofit-cause/himalaya.content.json +6 -0
  175. package/templates/nonprofit-cause/tier5-src/_shared/branded-lite-hosted.ts +1 -1
  176. package/templates/nonprofit-cause/tier5-src/_shared/collection-contract.ts +19 -3
  177. package/templates/nonprofit-cause/tier5-src/_shared/event-registration.ts +86 -0
  178. package/templates/nonprofit-cause/tier5-src/_shared/himi-restaurants.ts +2 -1
  179. package/templates/nonprofit-cause/tier5-src/himi-blog-post/index.ts +21 -8
  180. package/templates/nonprofit-cause/tier5-src/himi-branded-lite-feed/index.ts +4 -3
  181. package/templates/nonprofit-cause/tier5-src/himi-branded-lite-group-about/index.ts +243 -0
  182. package/templates/nonprofit-cause/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
  183. package/templates/nonprofit-cause/tier5-src/himi-branded-lite-plans/index.ts +2 -1
  184. package/templates/nonprofit-cause/tier5-src/himi-events-detail/index.ts +12 -86
  185. package/templates/nonprofit-cause/tier5-src/himi-events-list/index.ts +47 -6
  186. package/templates/nonprofit-cause/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
  187. package/templates/nonprofit-cause/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  188. package/templates/nonprofit-cause-owner/dev/index.ts +85 -65
  189. package/templates/nonprofit-cause-owner/tier5-src/_shared/collection-contract.ts +19 -3
  190. package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-rich-guard.ts +27 -0
  191. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
  192. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
  193. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
  194. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
  195. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
  196. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
  197. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
  198. package/templates/owner-lite/dev/index.ts +132 -66
  199. package/templates/owner-lite/tier5-src/_shared/collection-contract.ts +19 -3
  200. package/templates/owner-lite/tier5-src/himi-owner-lite-event/index.ts +16 -8
  201. package/templates/owner-lite/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
  202. package/templates/owner-lite/tier5-src/himi-owner-lite-events/index.ts +4 -2
  203. package/templates/owner-lite/tier5-src/himi-owner-lite-post/index.ts +7 -0
  204. package/templates/owner-lite/tier5-src/himi-owner-lite-product/index.ts +39 -6
  205. package/templates/owner-lite/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
  206. package/templates/owner-lite/tier5-src/himi-owner-lite-products/index.ts +7 -4
  207. package/templates/owner-lite/tier5-src/himi-owner-lite-service/index.ts +38 -7
  208. package/templates/owner-lite/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
  209. package/templates/owner-lite/tier5-src/himi-owner-lite-services/index.ts +4 -2
  210. package/templates/podcast-creator/config.ts +27 -1
  211. package/templates/podcast-creator/dev/index.ts +1051 -158
  212. package/templates/podcast-creator/himalaya.content.json +3 -0
  213. package/templates/podcast-creator/tier5-src/_shared/branded-lite-hosted.ts +1 -1
  214. package/templates/podcast-creator/tier5-src/_shared/collection-contract.ts +19 -3
  215. package/templates/podcast-creator/tier5-src/_shared/event-registration.ts +86 -0
  216. package/templates/podcast-creator/tier5-src/_shared/himi-restaurants.ts +2 -1
  217. package/templates/podcast-creator/tier5-src/himi-blog-post/index.ts +21 -8
  218. package/templates/podcast-creator/tier5-src/himi-branded-lite-feed/index.ts +4 -3
  219. package/templates/podcast-creator/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
  220. package/templates/podcast-creator/tier5-src/himi-branded-lite-plans/index.ts +2 -1
  221. package/templates/podcast-creator/tier5-src/himi-branded-lite-podcasts/index.ts +2 -1
  222. package/templates/podcast-creator/tier5-src/himi-events-detail/index.ts +12 -86
  223. package/templates/podcast-creator/tier5-src/himi-events-list/index.ts +47 -6
  224. package/templates/podcast-creator/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
  225. package/templates/podcast-creator/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  226. package/templates/podcast-creator-owner/dev/index.ts +53 -1
  227. package/templates/podcast-creator-owner/tier5-src/_shared/collection-contract.ts +19 -3
  228. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
  229. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
  230. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
  231. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
  232. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
  233. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
  234. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
  235. package/templates/portfolio-creative/config.ts +27 -1
  236. package/templates/portfolio-creative/dev/index.ts +1305 -468
  237. package/templates/portfolio-creative/himalaya.content.json +3 -0
  238. package/templates/portfolio-creative/tier5-src/_shared/branded-lite-hosted.ts +1 -1
  239. package/templates/portfolio-creative/tier5-src/_shared/collection-contract.ts +19 -3
  240. package/templates/portfolio-creative/tier5-src/_shared/event-registration.ts +86 -0
  241. package/templates/portfolio-creative/tier5-src/_shared/himi-restaurants.ts +2 -1
  242. package/templates/portfolio-creative/tier5-src/_shared/owner-editor-value.ts +164 -0
  243. package/templates/portfolio-creative/tier5-src/_shared/store-product-info.ts +50 -0
  244. package/templates/portfolio-creative/tier5-src/himi-blog-post/index.ts +21 -8
  245. package/templates/portfolio-creative/tier5-src/himi-branded-lite-category/index.ts +3 -2
  246. package/templates/portfolio-creative/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
  247. package/templates/portfolio-creative/tier5-src/himi-branded-lite-portfolio/index.ts +2 -1
  248. package/templates/portfolio-creative/tier5-src/himi-branded-lite-portfolio-project/index.ts +3 -2
  249. package/templates/portfolio-creative/tier5-src/himi-events-detail/index.ts +12 -86
  250. package/templates/portfolio-creative/tier5-src/himi-events-list/index.ts +47 -6
  251. package/templates/portfolio-creative/tier5-src/himi-store-product/index.ts +14 -3
  252. package/templates/portfolio-creative/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  253. package/templates/portfolio-creative-owner/dev/index.ts +129 -66
  254. package/templates/portfolio-creative-owner/tier5-src/_shared/collection-contract.ts +19 -3
  255. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
  256. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
  257. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
  258. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
  259. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
  260. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
  261. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
  262. package/templates/restaurant/config.ts +27 -1
  263. package/templates/restaurant/dev/index.ts +1051 -158
  264. package/templates/restaurant/himalaya.content.json +3 -0
  265. package/templates/restaurant/tier5-src/_shared/branded-lite-hosted.ts +1 -1
  266. package/templates/restaurant/tier5-src/_shared/collection-contract.ts +19 -3
  267. package/templates/restaurant/tier5-src/_shared/event-registration.ts +86 -0
  268. package/templates/restaurant/tier5-src/_shared/himi-restaurants.ts +2 -1
  269. package/templates/restaurant/tier5-src/himi-blog-post/index.ts +21 -8
  270. package/templates/restaurant/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
  271. package/templates/restaurant/tier5-src/himi-events-detail/index.ts +12 -86
  272. package/templates/restaurant/tier5-src/himi-events-list/index.ts +47 -6
  273. package/templates/restaurant/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  274. package/templates/restaurant-owner/dev/index.ts +132 -66
  275. package/templates/restaurant-owner/tier5-src/_shared/collection-contract.ts +19 -3
  276. package/templates/restaurant-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
  277. package/templates/restaurant-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
  278. package/templates/restaurant-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
  279. package/templates/restaurant-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
  280. package/templates/restaurant-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
  281. package/templates/restaurant-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
  282. package/templates/restaurant-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
  283. package/templates/restaurant-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
  284. package/templates/restaurant-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
  285. package/templates/restaurant-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
  286. package/templates/retail-store/config.ts +27 -1
  287. package/templates/retail-store/dev/index.ts +597 -191
  288. package/templates/retail-store/himalaya.content.json +3 -0
  289. package/templates/retail-store/tier5-src/_shared/branded-lite-hosted.ts +1 -1
  290. package/templates/retail-store/tier5-src/_shared/collection-contract.ts +19 -3
  291. package/templates/retail-store/tier5-src/_shared/himi-restaurants.ts +2 -1
  292. package/templates/retail-store/tier5-src/_shared/owner-editor-value.ts +164 -0
  293. package/templates/retail-store/tier5-src/_shared/store-product-info.ts +50 -0
  294. package/templates/retail-store/tier5-src/himi-blog-post/index.ts +21 -8
  295. package/templates/retail-store/tier5-src/himi-branded-lite-category/index.ts +3 -2
  296. package/templates/retail-store/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
  297. package/templates/retail-store/tier5-src/himi-store-product/index.ts +13 -3
  298. package/templates/retail-store/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  299. package/templates/retail-store-owner/dev/index.ts +50 -1
  300. package/templates/retail-store-owner/tier5-src/_shared/collection-contract.ts +19 -3
  301. package/templates/retail-store-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
  302. package/templates/retail-store-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
  303. package/templates/retail-store-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
  304. package/templates/retail-store-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
  305. package/templates/yoga-studio/config.ts +27 -1
  306. package/templates/yoga-studio/dev/index.ts +2996 -877
  307. package/templates/yoga-studio/himalaya.content.json +3 -0
  308. package/templates/yoga-studio/tier5-src/_shared/booking-location.ts +147 -0
  309. package/templates/yoga-studio/tier5-src/_shared/booking-session.ts +222 -0
  310. package/templates/yoga-studio/tier5-src/_shared/branded-lite-hosted.ts +1 -1
  311. package/templates/yoga-studio/tier5-src/_shared/collection-contract.ts +19 -3
  312. package/templates/yoga-studio/tier5-src/_shared/event-registration.ts +86 -0
  313. package/templates/yoga-studio/tier5-src/_shared/himi-restaurants.ts +2 -1
  314. package/templates/yoga-studio/tier5-src/himi-blog-post/index.ts +21 -8
  315. package/templates/yoga-studio/tier5-src/himi-booking-service/index.ts +277 -14
  316. package/templates/yoga-studio/tier5-src/himi-booking-services/index.ts +351 -92
  317. package/templates/yoga-studio/tier5-src/himi-booking-time/index.ts +25 -5
  318. package/templates/yoga-studio/tier5-src/himi-branded-lite-agenda/index.ts +219 -220
  319. package/templates/yoga-studio/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
  320. package/templates/yoga-studio/tier5-src/himi-branded-lite-plans/index.ts +2 -1
  321. package/templates/yoga-studio/tier5-src/himi-branded-lite-program/facts.ts +52 -0
  322. package/templates/yoga-studio/tier5-src/himi-branded-lite-program/index.ts +21 -11
  323. package/templates/yoga-studio/tier5-src/himi-events-detail/index.ts +12 -86
  324. package/templates/yoga-studio/tier5-src/himi-events-list/index.ts +47 -6
  325. package/templates/yoga-studio/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
  326. package/templates/yoga-studio/tier5-src/wix-spaces-whats-new/index.ts +2 -1
  327. package/templates/yoga-studio-owner/dev/index.ts +85 -65
  328. package/templates/yoga-studio-owner/tier5-src/_shared/collection-contract.ts +19 -3
  329. package/templates/yoga-studio-owner/tier5-src/_shared/owner-rich-guard.ts +27 -0
  330. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
  331. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
  332. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
  333. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
  334. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
  335. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
  336. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
@@ -12,7 +12,7 @@ import { ownerLoadError, isOwnerPreviewDemo, ownerDemoFallback, ownerWriteError,
12
12
  import { DEMO_EVENTS, DEMO_NOTE, DEMO_SAVE_NOTE } from "../_shared/owner-preview-demo.js";
13
13
  import { stashCopy, copyParam } from "../_shared/himi-copy.js";
14
14
  import { openRichLink } from "../_shared/rich-content-link.js";
15
- import { richBody } from "../_shared/rich-body.js";
15
+ import { descriptionBody } from "../_shared/rich-body.js";
16
16
  import { get as dbGet, upsert as dbUpsert, remove as dbRemove, type DbEntity } from "../_shared/owner-local-db.js";
17
17
  import { blankFlags } from "../_shared/detail-facts.js";
18
18
 
@@ -41,6 +41,7 @@ interface EventState {
41
41
  bodyJson: string;
42
42
  /** bodyJson !== "" — gates the plain text, because RichContent draws nothing for "". */
43
43
  hasBodyJson: boolean;
44
+ noBodyJson: boolean;
44
45
  /** The description's plain text (the document's own text, else the legacy description). */
45
46
  bodyText: string;
46
47
  initial: string;
@@ -68,15 +69,15 @@ interface EventState {
68
69
  }
69
70
 
70
71
  /* eslint-disable @typescript-eslint/no-explicit-any */
71
- /** [rico] #3499 — keep the description's plain text with the event's cached row, so the offline detail shows it.
72
+ /** [rico] #3499 — keep the description pair with the event's cached row, so the offline detail shows it.
72
73
  * Merged into the row the events list (or the form) wrote rather than replacing it; with no row yet, the
73
74
  * loaded detail's own fields become one. */
74
75
  async function cacheBodyText(s: EventState): Promise<void> {
75
76
  if (s.status !== "ready" || !s.id) return;
76
77
  const prev = await cacheGet(s.id);
77
- await cachePut(prev ? { ...prev, bodyText: s.bodyText } : {
78
+ await cachePut(prev ? { ...prev, bodyText: s.bodyText, bodyJson: s.bodyJson } : {
78
79
  id: s.id, title: s.title, subtitle: s.subtitle, image: s.image, dateLine: s.dateLine, location: s.location,
79
- statusLabel: s.statusLabel, registration: s.registration, bodyText: s.bodyText,
80
+ statusLabel: s.statusLabel, registration: s.registration, bodyText: s.bodyText, bodyJson: s.bodyJson,
80
81
  });
81
82
  }
82
83
  function idFrom(arg: unknown, fallback = ""): string {
@@ -132,6 +133,7 @@ function shapeFields(s: Partial<EventState>): EventState {
132
133
  summary: s.summary ?? "",
133
134
  bodyJson: s.bodyJson ?? "",
134
135
  hasBodyJson: !!s.bodyJson,
136
+ noBodyJson: !s.bodyJson,
135
137
  bodyText: s.bodyText ?? "",
136
138
  initial: s.initial ?? "?",
137
139
  image,
@@ -186,6 +188,7 @@ function cachedDetail(s: EventState, row: DbEntity): EventState {
186
188
  const title = String(row.title ?? row.name ?? "");
187
189
  const dateLine = String(row.dateLine ?? row.when ?? "");
188
190
  const location = String(row.location ?? "");
191
+ const body = descriptionBody(row.bodyJson || row.description, descriptionBody(row.bodyText ?? row.summary).bodyText);
189
192
  return shape({
190
193
  ...s,
191
194
  id: String(row.id),
@@ -193,8 +196,8 @@ function cachedDetail(s: EventState, row: DbEntity): EventState {
193
196
  title,
194
197
  subtitle: String(row.subtitle ?? [dateLine, location].filter((x) => x && x !== "—").join(" · ")),
195
198
  summary: "",
196
- bodyJson: "",
197
- bodyText: String(row.bodyText ?? row.summary ?? row.description ?? ""),
199
+ bodyJson: body.bodyJson,
200
+ bodyText: body.bodyText,
198
201
  initial: String(row.initial ?? (title[0] || "?")).slice(0, 1).toUpperCase(),
199
202
  image: String(row.image ?? ""),
200
203
  dateLine: dateLine || "—",
@@ -216,9 +219,9 @@ async function refresh(prev: EventState, id: string): Promise<EventState> {
216
219
  }
217
220
  const row = normalizeEvent(ev); // reuses date/location/status normalization
218
221
  const image = /^https?:\/\//.test(row.image) ? row.image : "";
219
- const { bodyJson, bodyText } = richBody((ev as unknown as { description?: unknown }).description, (eventDescription(ev) || "").trim());
222
+ const { bodyJson, bodyText } = descriptionBody((ev as unknown as { description?: unknown }).description, descriptionBody(eventDescription({ ...ev, description: undefined })).bodyText);
220
223
  // The teaser stays above the body only when it says something the body does not.
221
- const teaser = String((ev as any).shortDescription ?? "").trim();
224
+ const teaser = descriptionBody((ev as any).shortDescription).bodyText;
222
225
  return shape({
223
226
  ...prev,
224
227
  id,
@@ -358,4 +361,9 @@ if ((globalThis as { himalaya?: { hydrationOptOut?: unknown } }).himalaya?.hydra
358
361
  if (booted && typeof booted === "object") Object.assign(booted, { deletePending: false, noDeleteConfirmation: true });
359
362
  }
360
363
 
364
+ // Hydration shallow-merges older snapshots over defaults; derive both body gates from
365
+ // the restored document before the first paint, without waiting for a load action.
366
+ const bootedBody = svc.getState();
367
+ Object.assign(bootedBody, { hasBodyJson: !!bootedBody.bodyJson, noBodyJson: !bootedBody.bodyJson });
368
+
361
369
  export { svc };
@@ -1,3 +1,4 @@
1
+ import { descriptionBody } from "../_shared/rich-body.js";
1
2
  // Tier-5 bundle: __HIMI_APP_NAME__ — Events event EDIT form (the CRUD "U" only).
2
3
  // Modeled on himi-blog-owner-editor. Opened from the event detail ("Edit").
3
4
  //
@@ -222,12 +223,16 @@ const svc = defineService<EventFormState, {
222
223
  // this form never writes, so showing them here would invite an edit that lands elsewhere.
223
224
  ...(() => {
224
225
  const raw = (ev as unknown as { description?: unknown }).description;
225
- const doc = raw && typeof raw === "object" && Array.isArray((raw as { nodes?: unknown }).nodes) ? raw as Parameters<typeof postBodyText>[0] : null;
226
- const text = doc ? postBodyText(doc) : typeof raw === "string" ? raw.trim() : "";
226
+ const doc = parseRicosJson(raw);
227
+ const text = descriptionBody(raw).bodyText;
227
228
  // Edited in the RichContentEditor, seeded with the event's own document byte for byte (never
228
229
  // re-encoded); a legacy string seeds as paragraphs, and none seeds an empty editor.
229
- return { ...DESCRIPTION_LOADED, description: text, originalDescription: text, descriptionMode: "editor" as const,
230
- descriptionJson: doc ? JSON.stringify(raw) : text ? docJson(plainPostBody(text)) : "" };
230
+ // A description that looks like a serialized document but does not read as one (malformed JSON,
231
+ // or an object that is not a document) is locked, as on the Product form: an empty editor would
232
+ // let a save replace it. A blank or tag-only string stays editable so the owner can write the first one.
233
+ const unreadable = !doc && !text && raw != null && (typeof raw !== "string" || /^\s*[{[]/.test(raw));
234
+ return { ...DESCRIPTION_LOADED, description: text, originalDescription: text, descriptionMode: unreadable ? "locked" as const : "editor" as const,
235
+ descriptionJson: unreadable ? "" : doc ? JSON.stringify(doc) : text ? docJson(plainPostBody(text)) : "" };
231
236
  })(),
232
237
  when: row.dateLine || "—",
233
238
  location: row.location || "—",
@@ -239,14 +244,18 @@ const svc = defineService<EventFormState, {
239
244
  // Offline: prefill from the last-synced local cache before the demo/error fallbacks.
240
245
  const cached = await cacheGet(id);
241
246
  if (cached) {
247
+ // Only `descriptionJson` is the document as Wix returned it. The detail's `bodyJson` is the encoder's
248
+ // DISPLAY copy (media resized to urls), so it feeds the preview text and never seeds the editor.
249
+ const doc = parseRicosJson(cached.descriptionJson);
250
+ const description = descriptionBody(doc ?? cached.bodyJson, descriptionBody(cached.description ?? cached.bodyText ?? cached.summary).bodyText).bodyText;
242
251
  return shape({
243
252
  ...s, mode, id, heading: "Edit event",
244
253
  title: String(cached.title ?? cached.name ?? ""),
245
- description: String(cached.description ?? ""),
246
- originalDescription: String(cached.description ?? ""), ...DESCRIPTION_LOADED,
254
+ description,
255
+ originalDescription: description, ...DESCRIPTION_LOADED,
247
256
  // A row cached with its document reopens in the editor. An older row has none, so its verdict
248
257
  // decides: plain when it was plain, else locked (it carries no verdict either: fail closed).
249
- ...(cached.descriptionJson ? { descriptionMode: "editor" as const, descriptionJson: String(cached.descriptionJson) }
258
+ ...(doc ? { descriptionMode: "editor" as const, descriptionJson: JSON.stringify(doc) }
250
259
  : { descriptionMode: cached.descriptionProtected === "false" ? "plain" as const : "locked" as const, descriptionJson: "" }),
251
260
  when: String(cached.when ?? cached.dateLine ?? "—"),
252
261
  location: String(cached.location ?? "—"),
@@ -9,7 +9,7 @@ import { normalizeEvent, type EventRow } from "../_shared/himi-events.js";
9
9
  import { ownerLoadError, isOwnerPreviewDemo, ownerDemoFallback } from "../_shared/owner-load-error.js";
10
10
  import { DEMO_EVENTS, DEMO_NOTE } from "../_shared/owner-preview-demo.js";
11
11
  import { copyParam } from "../_shared/himi-copy.js";
12
- import { getAll, upsert, type DbEntity } from "../_shared/owner-local-db.js";
12
+ import { get, getAll, upsert, type DbEntity } from "../_shared/owner-local-db.js";
13
13
 
14
14
  // Last-synced rows are an explicitly incomplete fallback for an unfiltered
15
15
  // request during an outage. Filtered pages never claim this cache is complete.
@@ -19,7 +19,9 @@ async function readCachedRows(): Promise<EventRow[]> {
19
19
  try { return (await getAll(ENTITY)) as unknown as EventRow[]; } catch { return []; }
20
20
  }
21
21
  async function writeCachedRows(rows: EventRow[]): Promise<void> {
22
- try { for (const r of rows) await upsert(ENTITY, r as unknown as DbEntity); } catch { /* capability not granted → online-only */ }
22
+ try {
23
+ for (const r of rows) await upsert(ENTITY, { ...await get(ENTITY, r.id), ...r } as unknown as DbEntity);
24
+ } catch { /* capability not granted → online-only */ }
23
25
  }
24
26
 
25
27
  interface EventsState {
@@ -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,
@@ -144,6 +144,13 @@ export default defineApp({
144
144
  "parentScreenId": "himi_blog",
145
145
  "tabId": "home"
146
146
  },
147
+ {
148
+ "screenId": "himi_notif_settings",
149
+ "isPublic": true,
150
+ "paramKeys": [],
151
+ "parentScreenId": "himi_account",
152
+ "tabId": "profile"
153
+ },
147
154
  {
148
155
  "screenId": "himi_events",
149
156
  "isPublic": true,
@@ -215,6 +222,15 @@ export default defineApp({
215
222
  "parentScreenId": "himi_groups",
216
223
  "tabId": "groups"
217
224
  },
225
+ {
226
+ "screenId": "himi_group_about",
227
+ "isPublic": true,
228
+ "paramKeys": [
229
+ "id"
230
+ ],
231
+ "parentScreenId": "himi_group",
232
+ "tabId": "groups"
233
+ },
218
234
  {
219
235
  "screenId": "himi_account",
220
236
  "isPublic": true,
@@ -348,7 +364,7 @@ export default defineApp({
348
364
  // Your on-device database. It must declare every entity a worker reads or writes,
349
365
  // or those calls fail closed — keep it in step with `local_database` above.
350
366
  dataSchema: {
351
- "version": 2,
367
+ "version": 3,
352
368
  "entities": [
353
369
  {
354
370
  "name": "products",
@@ -429,6 +445,25 @@ export default defineApp({
429
445
  }
430
446
  ]
431
447
  },
448
+ {
449
+ "name": "booking_prefs",
450
+ "encrypted": false,
451
+ "fields": [
452
+ {
453
+ "name": "id",
454
+ "type": "string",
455
+ "required": true
456
+ },
457
+ {
458
+ "name": "locationId",
459
+ "type": "string"
460
+ },
461
+ {
462
+ "name": "locationLabel",
463
+ "type": "string"
464
+ }
465
+ ]
466
+ },
432
467
  {
433
468
  "name": "cms_collections",
434
469
  "encrypted": false,