@wix/himalaya-cli 0.1392.0 → 0.1393.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 (284) hide show
  1. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/bookings-v2/src/extensions.d.ts +7 -5
  2. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-bookings.mjs +4 -4
  3. package/dist/cli.mjs +31 -24
  4. package/dist/preview-assets.generated.bin +0 -0
  5. package/guides/sdk-reference.json +4 -4
  6. package/package.json +2 -2
  7. package/templates/beauty-salon/tier5-src/_shared/owner-load-error.ts +115 -12
  8. package/templates/beauty-salon/tier5-src/himi-branded-lite-cart/index.ts +52 -28
  9. package/templates/beauty-salon-owner/dev/index.ts +545 -100
  10. package/templates/beauty-salon-owner/himalaya.content.json +6 -0
  11. package/templates/beauty-salon-owner/tier5-src/_shared/owner-account.ts +6 -2
  12. package/templates/beauty-salon-owner/tier5-src/_shared/owner-booking-respond.ts +82 -0
  13. package/templates/beauty-salon-owner/tier5-src/_shared/owner-load-error.ts +115 -12
  14. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-account/index.ts +7 -4
  15. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-appointments/index.ts +2 -2
  16. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  17. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-home/index.ts +2 -2
  18. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-order/index.ts +3 -3
  19. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-orders/index.ts +2 -2
  20. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  21. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-post/index.ts +60 -43
  22. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  23. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  24. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-product/index.ts +31 -32
  25. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-product-form/index.ts +23 -43
  26. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-products/index.ts +2 -2
  27. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-service/index.ts +18 -20
  28. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-service-form/index.ts +16 -29
  29. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-services/index.ts +2 -2
  30. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  31. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-today/index.ts +315 -0
  32. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
  33. package/templates/branded-lite/tier5-src/_shared/owner-load-error.ts +115 -12
  34. package/templates/branded-lite/tier5-src/himi-branded-lite-cart/index.ts +52 -28
  35. package/templates/branded-lite/tier5-src/himi-branded-lite-group/index.ts +24 -24
  36. package/templates/community-club/tier5-src/_shared/owner-load-error.ts +115 -12
  37. package/templates/community-club/tier5-src/himi-branded-lite-group/index.ts +24 -24
  38. package/templates/community-club-owner/dev/index.ts +317 -100
  39. package/templates/community-club-owner/himalaya.content.json +6 -0
  40. package/templates/community-club-owner/tier5-src/_shared/owner-account.ts +6 -2
  41. package/templates/community-club-owner/tier5-src/_shared/owner-booking-respond.ts +82 -0
  42. package/templates/community-club-owner/tier5-src/_shared/owner-load-error.ts +115 -12
  43. package/templates/community-club-owner/tier5-src/himi-owner-lite-account/index.ts +7 -4
  44. package/templates/community-club-owner/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  45. package/templates/community-club-owner/tier5-src/himi-owner-lite-event/index.ts +18 -20
  46. package/templates/community-club-owner/tier5-src/himi-owner-lite-event-form/index.ts +20 -28
  47. package/templates/community-club-owner/tier5-src/himi-owner-lite-events/index.ts +2 -2
  48. package/templates/community-club-owner/tier5-src/himi-owner-lite-home/index.ts +2 -2
  49. package/templates/community-club-owner/tier5-src/himi-owner-lite-order/index.ts +3 -3
  50. package/templates/community-club-owner/tier5-src/himi-owner-lite-orders/index.ts +2 -2
  51. package/templates/community-club-owner/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  52. package/templates/community-club-owner/tier5-src/himi-owner-lite-post/index.ts +60 -43
  53. package/templates/community-club-owner/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  54. package/templates/community-club-owner/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  55. package/templates/community-club-owner/tier5-src/himi-owner-lite-product/index.ts +31 -32
  56. package/templates/community-club-owner/tier5-src/himi-owner-lite-product-form/index.ts +23 -43
  57. package/templates/community-club-owner/tier5-src/himi-owner-lite-products/index.ts +2 -2
  58. package/templates/community-club-owner/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  59. package/templates/community-club-owner/tier5-src/himi-owner-lite-today/index.ts +315 -0
  60. package/templates/community-club-owner/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
  61. package/templates/events-meetups/tier5-src/_shared/owner-load-error.ts +115 -12
  62. package/templates/events-meetups/tier5-src/himi-branded-lite-group/index.ts +24 -24
  63. package/templates/events-meetups-owner/dev/index.ts +275 -100
  64. package/templates/events-meetups-owner/himalaya.content.json +6 -0
  65. package/templates/events-meetups-owner/tier5-src/_shared/owner-account.ts +6 -2
  66. package/templates/events-meetups-owner/tier5-src/_shared/owner-booking-respond.ts +82 -0
  67. package/templates/events-meetups-owner/tier5-src/_shared/owner-load-error.ts +115 -12
  68. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-account/index.ts +7 -4
  69. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  70. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-event/index.ts +18 -20
  71. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-event-form/index.ts +20 -28
  72. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-events/index.ts +2 -2
  73. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-home/index.ts +2 -2
  74. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  75. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-post/index.ts +60 -43
  76. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  77. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  78. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  79. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-today/index.ts +315 -0
  80. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
  81. package/templates/gym-fitness/tier5-src/_shared/owner-load-error.ts +115 -12
  82. package/templates/gym-fitness/tier5-src/himi-branded-lite-cart/index.ts +52 -28
  83. package/templates/gym-fitness-owner/dev/index.ts +545 -100
  84. package/templates/gym-fitness-owner/himalaya.content.json +6 -0
  85. package/templates/gym-fitness-owner/tier5-src/_shared/owner-account.ts +6 -2
  86. package/templates/gym-fitness-owner/tier5-src/_shared/owner-booking-respond.ts +82 -0
  87. package/templates/gym-fitness-owner/tier5-src/_shared/owner-load-error.ts +115 -12
  88. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-account/index.ts +7 -4
  89. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-appointments/index.ts +2 -2
  90. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  91. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-event/index.ts +18 -20
  92. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-event-form/index.ts +20 -28
  93. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-events/index.ts +2 -2
  94. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-home/index.ts +2 -2
  95. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-order/index.ts +3 -3
  96. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-orders/index.ts +2 -2
  97. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  98. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-post/index.ts +60 -43
  99. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  100. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  101. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-product/index.ts +31 -32
  102. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-product-form/index.ts +23 -43
  103. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-products/index.ts +2 -2
  104. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-service/index.ts +18 -20
  105. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-service-form/index.ts +16 -29
  106. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-services/index.ts +2 -2
  107. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  108. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-today/index.ts +315 -0
  109. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
  110. package/templates/himi-chat/tier5-src/_shared/owner-load-error.ts +115 -12
  111. package/templates/nonprofit-cause/tier5-src/_shared/owner-load-error.ts +115 -12
  112. package/templates/nonprofit-cause/tier5-src/himi-branded-lite-group/index.ts +24 -24
  113. package/templates/nonprofit-cause-owner/dev/index.ts +503 -100
  114. package/templates/nonprofit-cause-owner/himalaya.content.json +6 -0
  115. package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-account.ts +6 -2
  116. package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-booking-respond.ts +82 -0
  117. package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-load-error.ts +115 -12
  118. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-account/index.ts +7 -4
  119. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-appointments/index.ts +2 -2
  120. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  121. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-event/index.ts +18 -20
  122. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-event-form/index.ts +20 -28
  123. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-events/index.ts +2 -2
  124. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-home/index.ts +2 -2
  125. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  126. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-post/index.ts +60 -43
  127. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  128. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  129. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-service/index.ts +18 -20
  130. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-service-form/index.ts +16 -29
  131. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-services/index.ts +2 -2
  132. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  133. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-today/index.ts +315 -0
  134. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
  135. package/templates/owner-lite/dev/index.ts +545 -100
  136. package/templates/owner-lite/himalaya.content.json +6 -0
  137. package/templates/owner-lite/tier5-src/_shared/owner-account.ts +6 -2
  138. package/templates/owner-lite/tier5-src/_shared/owner-booking-respond.ts +82 -0
  139. package/templates/owner-lite/tier5-src/_shared/owner-load-error.ts +115 -12
  140. package/templates/owner-lite/tier5-src/himi-owner-lite-account/index.ts +7 -4
  141. package/templates/owner-lite/tier5-src/himi-owner-lite-appointments/index.ts +2 -2
  142. package/templates/owner-lite/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  143. package/templates/owner-lite/tier5-src/himi-owner-lite-event/index.ts +18 -20
  144. package/templates/owner-lite/tier5-src/himi-owner-lite-event-form/index.ts +20 -28
  145. package/templates/owner-lite/tier5-src/himi-owner-lite-events/index.ts +2 -2
  146. package/templates/owner-lite/tier5-src/himi-owner-lite-home/index.ts +2 -2
  147. package/templates/owner-lite/tier5-src/himi-owner-lite-order/index.ts +3 -3
  148. package/templates/owner-lite/tier5-src/himi-owner-lite-orders/index.ts +2 -2
  149. package/templates/owner-lite/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  150. package/templates/owner-lite/tier5-src/himi-owner-lite-post/index.ts +60 -43
  151. package/templates/owner-lite/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  152. package/templates/owner-lite/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  153. package/templates/owner-lite/tier5-src/himi-owner-lite-product/index.ts +31 -32
  154. package/templates/owner-lite/tier5-src/himi-owner-lite-product-form/index.ts +23 -43
  155. package/templates/owner-lite/tier5-src/himi-owner-lite-products/index.ts +2 -2
  156. package/templates/owner-lite/tier5-src/himi-owner-lite-service/index.ts +18 -20
  157. package/templates/owner-lite/tier5-src/himi-owner-lite-service-form/index.ts +16 -29
  158. package/templates/owner-lite/tier5-src/himi-owner-lite-services/index.ts +2 -2
  159. package/templates/owner-lite/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  160. package/templates/owner-lite/tier5-src/himi-owner-lite-today/index.ts +315 -0
  161. package/templates/owner-lite/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
  162. package/templates/podcast-creator/tier5-src/_shared/owner-load-error.ts +115 -12
  163. package/templates/podcast-creator-owner/dev/index.ts +317 -100
  164. package/templates/podcast-creator-owner/himalaya.content.json +6 -0
  165. package/templates/podcast-creator-owner/tier5-src/_shared/owner-account.ts +6 -2
  166. package/templates/podcast-creator-owner/tier5-src/_shared/owner-booking-respond.ts +82 -0
  167. package/templates/podcast-creator-owner/tier5-src/_shared/owner-load-error.ts +115 -12
  168. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-account/index.ts +7 -4
  169. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  170. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-event/index.ts +18 -20
  171. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-event-form/index.ts +20 -28
  172. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-events/index.ts +2 -2
  173. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-home/index.ts +2 -2
  174. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-order/index.ts +3 -3
  175. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-orders/index.ts +2 -2
  176. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  177. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-post/index.ts +60 -43
  178. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  179. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  180. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-product/index.ts +31 -32
  181. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-product-form/index.ts +23 -43
  182. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-products/index.ts +2 -2
  183. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  184. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-today/index.ts +315 -0
  185. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
  186. package/templates/portfolio-creative/tier5-src/_shared/owner-load-error.ts +115 -12
  187. package/templates/portfolio-creative/tier5-src/himi-branded-lite-cart/index.ts +52 -28
  188. package/templates/portfolio-creative-owner/dev/index.ts +545 -100
  189. package/templates/portfolio-creative-owner/himalaya.content.json +6 -0
  190. package/templates/portfolio-creative-owner/tier5-src/_shared/owner-account.ts +6 -2
  191. package/templates/portfolio-creative-owner/tier5-src/_shared/owner-booking-respond.ts +82 -0
  192. package/templates/portfolio-creative-owner/tier5-src/_shared/owner-load-error.ts +115 -12
  193. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-account/index.ts +7 -4
  194. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-appointments/index.ts +2 -2
  195. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  196. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-home/index.ts +2 -2
  197. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-order/index.ts +3 -3
  198. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-orders/index.ts +2 -2
  199. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  200. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-post/index.ts +60 -43
  201. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  202. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  203. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-product/index.ts +31 -32
  204. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-product-form/index.ts +23 -43
  205. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-products/index.ts +2 -2
  206. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-service/index.ts +18 -20
  207. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-service-form/index.ts +16 -29
  208. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-services/index.ts +2 -2
  209. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  210. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-today/index.ts +315 -0
  211. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
  212. package/templates/restaurant/tier5-src/_shared/owner-load-error.ts +115 -12
  213. package/templates/restaurant-owner/dev/index.ts +545 -100
  214. package/templates/restaurant-owner/himalaya.content.json +6 -0
  215. package/templates/restaurant-owner/tier5-src/_shared/owner-account.ts +6 -2
  216. package/templates/restaurant-owner/tier5-src/_shared/owner-booking-respond.ts +82 -0
  217. package/templates/restaurant-owner/tier5-src/_shared/owner-load-error.ts +115 -12
  218. package/templates/restaurant-owner/tier5-src/himi-owner-lite-account/index.ts +7 -4
  219. package/templates/restaurant-owner/tier5-src/himi-owner-lite-appointments/index.ts +2 -2
  220. package/templates/restaurant-owner/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  221. package/templates/restaurant-owner/tier5-src/himi-owner-lite-event/index.ts +18 -20
  222. package/templates/restaurant-owner/tier5-src/himi-owner-lite-event-form/index.ts +20 -28
  223. package/templates/restaurant-owner/tier5-src/himi-owner-lite-events/index.ts +2 -2
  224. package/templates/restaurant-owner/tier5-src/himi-owner-lite-home/index.ts +2 -2
  225. package/templates/restaurant-owner/tier5-src/himi-owner-lite-order/index.ts +3 -3
  226. package/templates/restaurant-owner/tier5-src/himi-owner-lite-orders/index.ts +2 -2
  227. package/templates/restaurant-owner/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  228. package/templates/restaurant-owner/tier5-src/himi-owner-lite-post/index.ts +60 -43
  229. package/templates/restaurant-owner/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  230. package/templates/restaurant-owner/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  231. package/templates/restaurant-owner/tier5-src/himi-owner-lite-product/index.ts +31 -32
  232. package/templates/restaurant-owner/tier5-src/himi-owner-lite-product-form/index.ts +23 -43
  233. package/templates/restaurant-owner/tier5-src/himi-owner-lite-products/index.ts +2 -2
  234. package/templates/restaurant-owner/tier5-src/himi-owner-lite-service/index.ts +18 -20
  235. package/templates/restaurant-owner/tier5-src/himi-owner-lite-service-form/index.ts +16 -29
  236. package/templates/restaurant-owner/tier5-src/himi-owner-lite-services/index.ts +2 -2
  237. package/templates/restaurant-owner/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  238. package/templates/restaurant-owner/tier5-src/himi-owner-lite-today/index.ts +315 -0
  239. package/templates/restaurant-owner/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
  240. package/templates/retail-store/tier5-src/_shared/owner-load-error.ts +115 -12
  241. package/templates/retail-store/tier5-src/himi-branded-lite-cart/index.ts +52 -28
  242. package/templates/retail-store-owner/dev/index.ts +317 -100
  243. package/templates/retail-store-owner/himalaya.content.json +6 -0
  244. package/templates/retail-store-owner/tier5-src/_shared/owner-account.ts +6 -2
  245. package/templates/retail-store-owner/tier5-src/_shared/owner-booking-respond.ts +82 -0
  246. package/templates/retail-store-owner/tier5-src/_shared/owner-load-error.ts +115 -12
  247. package/templates/retail-store-owner/tier5-src/himi-owner-lite-account/index.ts +7 -4
  248. package/templates/retail-store-owner/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  249. package/templates/retail-store-owner/tier5-src/himi-owner-lite-home/index.ts +2 -2
  250. package/templates/retail-store-owner/tier5-src/himi-owner-lite-order/index.ts +3 -3
  251. package/templates/retail-store-owner/tier5-src/himi-owner-lite-orders/index.ts +2 -2
  252. package/templates/retail-store-owner/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  253. package/templates/retail-store-owner/tier5-src/himi-owner-lite-post/index.ts +60 -43
  254. package/templates/retail-store-owner/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  255. package/templates/retail-store-owner/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  256. package/templates/retail-store-owner/tier5-src/himi-owner-lite-product/index.ts +31 -32
  257. package/templates/retail-store-owner/tier5-src/himi-owner-lite-product-form/index.ts +23 -43
  258. package/templates/retail-store-owner/tier5-src/himi-owner-lite-products/index.ts +2 -2
  259. package/templates/retail-store-owner/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  260. package/templates/retail-store-owner/tier5-src/himi-owner-lite-today/index.ts +315 -0
  261. package/templates/retail-store-owner/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
  262. package/templates/yoga-studio/tier5-src/_shared/owner-load-error.ts +115 -12
  263. package/templates/yoga-studio-owner/dev/index.ts +503 -100
  264. package/templates/yoga-studio-owner/himalaya.content.json +6 -0
  265. package/templates/yoga-studio-owner/tier5-src/_shared/owner-account.ts +6 -2
  266. package/templates/yoga-studio-owner/tier5-src/_shared/owner-booking-respond.ts +82 -0
  267. package/templates/yoga-studio-owner/tier5-src/_shared/owner-load-error.ts +115 -12
  268. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-account/index.ts +7 -4
  269. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-appointments/index.ts +2 -2
  270. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  271. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-event/index.ts +18 -20
  272. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-event-form/index.ts +20 -28
  273. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-events/index.ts +2 -2
  274. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-home/index.ts +2 -2
  275. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  276. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-post/index.ts +60 -43
  277. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  278. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  279. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-service/index.ts +18 -20
  280. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-service-form/index.ts +16 -29
  281. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-services/index.ts +2 -2
  282. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  283. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-today/index.ts +315 -0
  284. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
@@ -15,10 +15,13 @@ export interface AccountState {
15
15
  supportUrl: string;
16
16
  privacyUrl: string;
17
17
  termsUrl: string;
18
+ /** Wix's own account-deletion destination (App Store 5.1.1(v)). */
19
+ deleteAccountUrl: string;
18
20
  /** hiddenPath flags — TRUE hides, so each is phrased negatively. */
19
21
  noSupport: boolean;
20
22
  noPrivacy: boolean;
21
23
  noTerms: boolean;
24
+ noDeleteAccount: boolean;
22
25
  }
23
26
 
24
27
  /** Only absolute http(s) URLs are openable; anything else is treated as absent. */
@@ -37,13 +40,14 @@ export function ownerLineOf(name: string, email: string): string {
37
40
 
38
41
  export function shapeAccount(s: Partial<AccountState>): AccountState {
39
42
  const supportUrl = safeUrl(s.supportUrl), privacyUrl = safeUrl(s.privacyUrl), termsUrl = safeUrl(s.termsUrl);
43
+ const deleteAccountUrl = safeUrl(s.deleteAccountUrl);
40
44
  return {
41
45
  status: s.status ?? "loading",
42
46
  businessName: s.businessName ?? "",
43
47
  ownerLine: s.ownerLine ?? "",
44
48
  versionLine: s.versionLine ?? "",
45
49
  error: s.error ?? "",
46
- supportUrl, privacyUrl, termsUrl,
47
- noSupport: !supportUrl, noPrivacy: !privacyUrl, noTerms: !termsUrl,
50
+ supportUrl, privacyUrl, termsUrl, deleteAccountUrl,
51
+ noSupport: !supportUrl, noPrivacy: !privacyUrl, noTerms: !termsUrl, noDeleteAccount: !deleteAccountUrl,
48
52
  };
49
53
  }
@@ -0,0 +1,82 @@
1
+ // Accept / Decline ONE booking request — the write shared by the two __HIMI_APP_NAME__ surfaces that
2
+ // answer a request without opening the booking screen: the paired watch (`himi-owner-lite-wrist`)
3
+ // and the notification's action buttons (`himi-owner-lite-nav`).
4
+ //
5
+ // Both follow the same rules:
6
+ // • the press names the business it was shown for, and is REFUSED unless that is the business
7
+ // the phone has active — a site switched between delivery and press must never confirm
8
+ // another business's booking;
9
+ // • the write itself is addressed at that business (`wix-site-id`), so even a switch that lands
10
+ // between the check and the request cannot move it;
11
+ // • only a request still pending is written, at the revision Wix last reported.
12
+
13
+ import { getBooking, confirmBooking, declineBooking } from "@himalaya/wix-bookings";
14
+
15
+ type Rec = Record<string, unknown>;
16
+
17
+ /** The statuses that are waiting on the owner. */
18
+ export const PENDING_BOOKING_STATUSES: ReadonlySet<string> = new Set(["PENDING", "PENDING_APPROVAL", "WAITING_LIST"]);
19
+
20
+ export type BookingResponse = "confirm" | "decline";
21
+
22
+ /** A press may write only for the business the phone has active. Fails CLOSED: a press that
23
+ * names no business, or a host that cannot say which one is active, writes nothing. */
24
+ export function isForActiveBusiness(siteId: string, activeSiteId: string): boolean {
25
+ return !!siteId && !!activeSiteId && siteId === activeSiteId;
26
+ }
27
+
28
+ /** Wix refused the write because the booking moved on (another revision, already handled). */
29
+ export function isStaleBookingWrite(e: unknown): boolean {
30
+ return /revision|\b409\b|ABORTED|conflict/i.test(String((e as Error)?.message ?? e));
31
+ }
32
+
33
+ /** Confirm or decline `bookingId` at `revision`, addressed at `siteId`. Rejects without a
34
+ * request when `siteId` is empty: an unaddressed write would land on whatever business the
35
+ * ambient bridge is scoped to. */
36
+ export function writeBookingResponse(kind: BookingResponse, bookingId: string, revision: string, siteId: string): Promise<unknown> {
37
+ const site = siteId.trim();
38
+ if (!site) return Promise.reject(new Error("writeBookingResponse: a booking write must name its business"));
39
+ const opts = { site };
40
+ return kind === "confirm" ? confirmBooking(bookingId, revision, opts) : declineBooking(bookingId, revision, false, opts);
41
+ }
42
+
43
+ export type BookingResponseOutcome =
44
+ | "confirmed" | "declined"
45
+ /** Not written: no booking id, or a press for a business other than the active one. */
46
+ | "refused"
47
+ /** Not written: the booking is no longer waiting on the owner (or no longer exists). */
48
+ | "notPending"
49
+ /** Not written: Wix reported a newer revision between the read and the write. */
50
+ | "stale"
51
+ /** Not written: the read or the write failed. */
52
+ | "failed";
53
+
54
+ function str(r: Rec | undefined, key: string): string {
55
+ const v = r?.[key];
56
+ return typeof v === "string" ? v : typeof v === "number" ? String(v) : "";
57
+ }
58
+
59
+ /** Answer a request known only by id — a notification carries no revision, so the booking is
60
+ * read first (from the business the press names) and written only while it is still pending. */
61
+ export async function respondToBookingById(
62
+ kind: BookingResponse,
63
+ bookingId: string,
64
+ siteId: string,
65
+ activeSiteId: string,
66
+ ): Promise<BookingResponseOutcome> {
67
+ if (!bookingId || !isForActiveBusiness(siteId, activeSiteId)) return "refused";
68
+ let booking: Rec | undefined;
69
+ try {
70
+ booking = ((await getBooking(bookingId, { site: siteId })) as unknown as { booking?: Rec } | undefined)?.booking;
71
+ } catch {
72
+ return "failed";
73
+ }
74
+ const revision = str(booking, "revision");
75
+ if (!booking || !revision || !PENDING_BOOKING_STATUSES.has(str(booking, "status"))) return "notPending";
76
+ try {
77
+ await writeBookingResponse(kind, bookingId, revision, siteId);
78
+ } catch (e) {
79
+ return isStaleBookingWrite(e) ? "stale" : "failed";
80
+ }
81
+ return kind === "confirm" ? "confirmed" : "declined";
82
+ }
@@ -20,10 +20,9 @@ export function isOwnerPreviewLive(): boolean {
20
20
  *
21
21
  * `isBridgeUnavailable` cannot answer this: it reads "not live" as "preview",
22
22
  * and on NATIVE there is no input at all, so `undefined` satisfies it. That is
23
- * harmless for the callers that use it to pick a demo fallback or to queue a
24
- * write, and it is deliberately left alone for them — native write-behind
25
- * depends on it. It is NOT harmless for choosing COPY: native workers format
26
- * their failures the same way (`"HTTP \(code): \(body)"`, JSWorker.swift;
23
+ * left alone for the other apps that use it to pick a demo fallback or to queue
24
+ * a write. Owner-lite reads ask `ownerDemoFallback` instead. It is NOT
25
+ * harmless for choosing COPY: native workers format their failures the same way (`"HTTP \(code): \(body)"`, JSWorker.swift;
27
26
  * `"HTTP ${e.code}: ..."`, WebViewJSWorker.kt), so a transient `HTTP 503` on a
28
27
  * phone would otherwise be answered with "open this app on a device" — on the
29
28
  * device. Callers that pick a SENTENCE ask this instead.
@@ -43,11 +42,89 @@ export function isBridgeUnavailable(e: unknown): boolean {
43
42
  return /HTTP (405|501|502|503)\b/.test(String((e as Error)?.message ?? e));
44
43
  }
45
44
 
46
- /** Preserve native write-behind when the bridge is unavailable. This is a
47
- * queue decision, never permission to replace a failed live read with samples. */
48
- export function shouldQueueOwnerWrite(e: unknown): boolean {
49
- if (ownerPreviewMode() === "live" || isOwnerPreviewDemo()) return false;
50
- return /HTTP (405|501|502|503)\b/.test(String((e as Error)?.message ?? e));
45
+ /**
46
+ * Whether a failed owner-lite READ may answer with the built-in demo records.
47
+ *
48
+ * Only where a demo was asked for: a web preview host that is not live. On a phone no
49
+ * mode is injected, so `isBridgeUnavailable` alone is `true` for a transient Wix
50
+ * `HTTP 503` — and the owner was shown sample appointments, orders and sites as if
51
+ * they were their business. Native falls through to the screen's error state.
52
+ * `isBridgeUnavailable` keeps its semantics: other apps' callers depend on it.
53
+ */
54
+ export function ownerDemoFallback(e: unknown): boolean {
55
+ return isOwnerPreviewHost() && !isOwnerPreviewLive() && isBridgeUnavailable(e);
56
+ }
57
+
58
+ /**
59
+ * The sentence for an owner WRITE that failed because the device could not reach Wix at
60
+ * all (a transport failure). Nothing replays a queued write on any platform — every host's
61
+ * `drain` passes an empty closure — so the honest answer is that nothing was saved.
62
+ * Copy-as-configuration under `ownerCommon.`, which every owner screen forwards.
63
+ */
64
+ export function ownerOfflineNotSaved(): string {
65
+ return copyParam(
66
+ "ownerCommon.offlineNotSaved",
67
+ "You’re offline — nothing was saved. Try again when you reconnect.",
68
+ );
69
+ }
70
+
71
+ /** The sentence for an owner WRITE that Wix answered with an unavailable status: the
72
+ * device is online, so it is not "offline" — but nothing was saved all the same. */
73
+ /**
74
+ * Whether a failed WRITE may have landed on Wix anyway, so the user must not be told it
75
+ * was not saved: a transport failure mid-request (timeout, reset, fetch rejection), the web
76
+ * host's after-send envelope (`HTTP 502 {…"sent":true}`), the serve bridge's mid-request
77
+ * `webwix_bridge_upstream_failed`, or a gateway status (502/503/504) that can arrive after
78
+ * the backend already ran. Only connect-time failures (`isOfflineFailure`) and the designed
79
+ * 405/501 bridge refusals prove nothing happened.
80
+ */
81
+ export function writeMayHaveLanded(e: unknown): boolean {
82
+ if (isOfflineFailure(e)) return false;
83
+ if (isTransportFailure(e)) return true;
84
+ const msg = String((e as Error)?.message ?? e ?? "");
85
+ if (/"sent"\s*:\s*true/.test(msg)) return true;
86
+ // The web host's own envelope WITHOUT `sent: true` failed before the request left it, and
87
+ // a disabled owner rung / bridge refuses by design without sending anything.
88
+ if (/\bwebwix_(?:direct_failed|owner_disabled|bridge_disabled)\b/.test(msg)) return false;
89
+ // `webwix_bridge_upstream_failed` stays ambiguous: the same code covers a lookup that failed
90
+ // before sending and a serve-bridge failure mid-request, and nothing in it says which.
91
+ return /\bwebwix_bridge_upstream_failed\b/.test(msg) || /HTTP (502|503|504)\b/.test(msg);
92
+ }
93
+
94
+ /** Wix answered that the record does not exist (`HTTP 404`). A detail must not fall back to
95
+ * its cached row then: that row is what a delete whose reply was lost leaves behind. */
96
+ export function isNotFound(e: unknown): boolean {
97
+ if (/HTTP 404\b/.test(String((e as Error)?.message ?? e ?? ""))) return true;
98
+ // An SDK that answers a 404 with its own "not found" error keeps the HTTP one as `cause`
99
+ // (the blog SDK's getPost, after its query fallback also finds nothing).
100
+ const cause = (e as { cause?: unknown } | null | undefined)?.cause;
101
+ return cause !== undefined && cause !== e && /HTTP 404\b/.test(String((cause as Error)?.message ?? cause));
102
+ }
103
+
104
+ export function ownerUnavailableNotSaved(): string {
105
+ return copyParam(
106
+ "ownerCommon.unavailableNotSaved",
107
+ "Wix isn’t available right now — nothing was saved. Try again in a moment.",
108
+ );
109
+ }
110
+
111
+ /** The sentence for an owner WRITE that may have landed (`writeMayHaveLanded`): it can't
112
+ * be called saved or not saved. */
113
+ export function ownerWriteUnconfirmed(): string {
114
+ return copyParam(
115
+ "ownerCommon.writeUnconfirmed",
116
+ "Wix didn’t confirm this, so it may or may not have been saved. Check before trying again.",
117
+ );
118
+ }
119
+
120
+ /** Display copy for a failed owner write: `ownerOfflineNotSaved` when the request never
121
+ * left the device, `ownerWriteUnconfirmed` when it may have landed, `ownerUnavailableNotSaved`
122
+ * for the designed 405/501 bridge refusals outside a live preview, else `ownerLoadError`. */
123
+ export function ownerWriteError(e: unknown): string {
124
+ if (isOfflineFailure(e)) return ownerOfflineNotSaved();
125
+ if (writeMayHaveLanded(e)) return ownerWriteUnconfirmed();
126
+ if (!isOwnerPreviewLive() && /HTTP (405|501)\b/.test(String((e as Error)?.message ?? e))) return ownerUnavailableNotSaved();
127
+ return ownerLoadError(e);
51
128
  }
52
129
 
53
130
  /** `HTTP 403: …` → "403", when the message carries a status at all. */
@@ -99,6 +176,10 @@ const TRANSPORT = [
99
176
  /^Failed to connect to \S/,
100
177
  /^Unable to resolve host\b/,
101
178
  /\b(?:Connection refused|Network is unreachable|Software caused connection abort)\b/,
179
+ // OkHttp / HttpURLConnection messages a dropped connection produces mid-request, which
180
+ // Android's bridge forwards without the exception class.
181
+ /\b(?:Connection reset|ECONNRESET|ETIMEDOUT|EPIPE|Broken pipe|stream was reset)\b/,
182
+ /^unexpected end of stream\b/i,
102
183
  /^(?:timeout|Read timed out|connect timed out)$/i,
103
184
  /\bFailed to fetch\b/,
104
185
  /\bNetworkError when attempting to fetch\b/,
@@ -113,6 +194,27 @@ export function isTransportFailure(e: unknown): boolean {
113
194
  return TRANSPORT.some((re) => re.test(msg));
114
195
  }
115
196
 
197
+ /** Transport failures that happen while CONNECTING — no connection, no route, no such host,
198
+ * connection refused — so the request provably never left the device. Every other
199
+ * transport failure (a timeout, a reset, a bad or truncated response, a browser's fetch
200
+ * rejection, which says nothing about when it failed) may come after Wix took the write. */
201
+ const NEVER_SENT = [
202
+ /\bNSURLErrorDomain Code=-10(?:09|04|03|06|20|18)\b/, // not connected / cannot connect / no host / DNS / data not allowed / roaming off
203
+ /\b(?:UnknownHost|Connect|NoRouteToHost)Exception\b/,
204
+ /^Failed to connect to \S/,
205
+ /^Unable to resolve host\b/,
206
+ /\b(?:Connection refused|Network is unreachable)\b/,
207
+ /\bnet::ERR_(?:INTERNET_DISCONNECTED|NAME_NOT_RESOLVED|CONNECTION_REFUSED|ADDRESS_UNREACHABLE|NETWORK_ACCESS_DENIED)\b/,
208
+ ];
209
+
210
+ /** No HTTP answer, and the request provably never left the device: the user is offline, and
211
+ * a write certainly did not happen. Anything else may have landed (see `NEVER_SENT`). */
212
+ export function isOfflineFailure(e: unknown): boolean {
213
+ if (!isTransportFailure(e)) return false;
214
+ const msg = String((e as Error)?.message ?? e ?? "");
215
+ return NEVER_SENT.some((re) => re.test(msg));
216
+ }
217
+
116
218
  /** The one sentence for a transport failure. Copy-as-configuration: the key is
117
219
  * under `ownerCommon.`, which every owner screen (Aria included) forwards. */
118
220
  export function ownerTransportFailureText(): string {
@@ -194,8 +296,8 @@ export function ownerPreviewUnavailable(): string {
194
296
  * error says: this names the web preview when there IS one. `isBridgeUnavailable`
195
297
  * reads "not live" as "preview", and native injects no mode at all, so the
196
298
  * default would answer a device-side `HTTP 503` with "open this app on a device"
197
- * — on the device. That predicate is deliberately left alone: native
198
- * write-behind (`shouldQueueOwnerWrite`) depends on exactly it.
299
+ * — on the device. That predicate is deliberately left alone: other apps'
300
+ * demo and write-queue decisions depend on exactly it.
199
301
  *
200
302
  * The reductions this used to add are now in `humanWireError`, so every owner
201
303
  * screen gets them rather than the two that happened to call this.
@@ -232,6 +334,7 @@ export function ownerDisplayError(e: unknown): string {
232
334
  */
233
335
  export function ownerLoadError(e: unknown): string {
234
336
  const msg = String((e as Error)?.message ?? e);
235
- if (isBridgeUnavailable(e)) return ownerPreviewUnavailable();
337
+ // Same host guard as `ownerDisplayError`: on a phone, "open this app on a device" is false.
338
+ if (isOwnerPreviewHost() && isBridgeUnavailable(e)) return ownerPreviewUnavailable();
236
339
  return humanWireError(msg);
237
340
  }
@@ -9,7 +9,8 @@
9
9
  // which goes stale the moment the binary is bumped);
10
10
  // • the help / privacy / terms links, which arrive as onAppear params baked
11
11
  // from provisioning.json `identity` — so a branded template ships ITS links,
12
- // and `openLink` can only ever open one of those three URLs.
12
+ // and `openLink` can only ever open one of those URLs — plus Wix's own
13
+ // account-deletion page (`deleteAccountUrl`, App Store 5.1.1(v)).
13
14
  //
14
15
  // • which business this is — the one the owner picked on Sites (see
15
16
  // `_shared/owner-selected-site.ts`), not the build-time provisioning name,
@@ -27,7 +28,7 @@ import { stashCopy, copyTemplate } from "../_shared/himi-copy.js";
27
28
  import { ownerLineOf, shapeAccount, type AccountState } from "../_shared/owner-account.js";
28
29
  import { fallbackNameFrom, selectedSiteName } from "../_shared/owner-selected-site.js";
29
30
 
30
- type LinkKind = "support" | "privacy" | "terms";
31
+ type LinkKind = "support" | "privacy" | "terms" | "deleteAccount";
31
32
 
32
33
  const obj = (v: unknown): Record<string, unknown> => (v && typeof v === "object" ? v as Record<string, unknown> : {});
33
34
 
@@ -44,7 +45,8 @@ const svc = defineService<AccountState, {
44
45
  fallbackBusinessName = fallbackNameFrom(arg, fallbackBusinessName);
45
46
  const businessName = selectedSiteName(fallbackBusinessName);
46
47
  const p = obj(arg);
47
- const links = { supportUrl: String(p.supportUrl ?? s.supportUrl), privacyUrl: String(p.privacyUrl ?? s.privacyUrl), termsUrl: String(p.termsUrl ?? s.termsUrl) };
48
+ const links = { supportUrl: String(p.supportUrl ?? s.supportUrl), privacyUrl: String(p.privacyUrl ?? s.privacyUrl), termsUrl: String(p.termsUrl ?? s.termsUrl),
49
+ deleteAccountUrl: String(p.deleteAccountUrl ?? s.deleteAccountUrl) };
48
50
  let ownerLine = "";
49
51
  // Why the identity line is missing, when it is. Kept in state (the failure is
50
52
  // modelled, not swallowed) but not painted: a settings screen that cannot name
@@ -68,7 +70,8 @@ const svc = defineService<AccountState, {
68
70
  },
69
71
  openLink: async (s, arg) => {
70
72
  const kind = String(obj(arg).kind ?? arg ?? "") as LinkKind;
71
- const url = kind === "support" ? s.supportUrl : kind === "privacy" ? s.privacyUrl : kind === "terms" ? s.termsUrl : "";
73
+ const url = kind === "support" ? s.supportUrl : kind === "privacy" ? s.privacyUrl : kind === "terms" ? s.termsUrl
74
+ : kind === "deleteAccount" ? s.deleteAccountUrl : "";
72
75
  if (url) await open(url);
73
76
  return s;
74
77
  },
@@ -21,7 +21,7 @@ import { offsetPage } from "../_shared/offset-page.js";
21
21
  import { localPreferences } from "../_shared/local-preferences.js";
22
22
  import { defineService } from "@himalaya/state";
23
23
  import { queryBookings, rescheduleBooking, type WixBooking } from "@himalaya/wix-bookings";
24
- import { ownerLoadError, isBridgeUnavailable, isOwnerPreviewDemo } from "../_shared/owner-load-error.js";
24
+ import { ownerLoadError, isOwnerPreviewDemo, ownerDemoFallback } from "../_shared/owner-load-error.js";
25
25
  import { DEMO_APPOINTMENTS, DEMO_NOTE, demoAppointmentWindow } from "../_shared/owner-preview-demo.js";
26
26
  import { stashCopy, copyParam } from "../_shared/himi-copy.js";
27
27
  import { dayKey, dayLabel, hhmm, type CalendarEvent, type DayDecoration } from "@himalaya/time";
@@ -437,7 +437,7 @@ async function loadList(s: AppointmentsState, append = false): Promise<Appointme
437
437
  } catch (e) {
438
438
  if (revision !== loadRevision) return undefined;
439
439
  s = { ...s, ...presentation() };
440
- if (!append && isBridgeUnavailable(e)) return demoList(s);
440
+ if (!append && ownerDemoFallback(e)) return demoList(s);
441
441
  if (append && !/401|403|forbidden/i.test(String(e))) return shape({ ...s, status: "ready", pageError: true });
442
442
  return shape({ ...s, status: "error", allAppointments: [], appointments: [], nextCursor: "", pageError: false, error: ownerLoadError(e) });
443
443
  } finally { if (revision === loadRevision) paging = false; }
@@ -2,7 +2,7 @@
2
2
  //
3
3
  // `loadEntityRows` calls the SAME owner-scoped Wix clients the sibling
4
4
  // list/detail workers use (searchOrders, queryStoreProducts, …), with the
5
- // identical `isBridgeUnavailable` → owner-preview-demo fallback.
5
+ // identical `ownerDemoFallback` → owner-preview-demo fallback (preview hosts only).
6
6
  //
7
7
  // That is not a nicety. A generated row carries its record `id` into
8
8
  // `tier5.ask.openEntity`, which navigates to `himi_owner_lite_<entity>` — and
@@ -16,7 +16,7 @@
16
16
  // alias map to resolve a bare "@himalaya/wix-*" with.
17
17
  import { wixMediaUrl } from "@himalaya/wix-media";
18
18
 
19
- import { isBridgeUnavailable, isOwnerPreviewDemo } from "../_shared/owner-load-error.js";
19
+ import { isOwnerPreviewDemo, ownerDemoFallback } from "../_shared/owner-load-error.js";
20
20
  import { queryStoreProducts, productPrice, type StoreProduct } from "../_shared/himi-store.js";
21
21
  import { updateProduct, deleteProduct } from "@himalaya/wix-stores";
22
22
  import { deleteDraftPost } from "@himalaya/wix-blog";
@@ -362,7 +362,7 @@ export async function loadEntityRows(entity: EntityName): Promise<{ rows: Row[];
362
362
  // labelled demo row keeps the web preview useful; for a measure it would be
363
363
  // fabricated traffic and revenue, which is the one thing this screen family
364
364
  // refuses. It takes the error arm below instead, exactly as a timeout does.
365
- if (isBridgeUnavailable(e) && entity !== "metrics") return { rows: demoRows(entity), demo: true, error: "" };
365
+ if (ownerDemoFallback(e) && entity !== "metrics") return { rows: demoRows(entity), demo: true, error: "" };
366
366
  return { rows: [], demo: false, error: `${entity} couldn't be read` };
367
367
  }
368
368
  }
@@ -19,7 +19,7 @@ import { getSiteAnalytics, getSiteTimeZone, localDateRange, localDateOf, localMi
19
19
  // `text(...)` and never matched on — the RAW reason is kept beside it in
20
20
  // `<part>Reason` for anything that needs it — so the display-only reduction is
21
21
  // both safe here and the reason a 428 reason code stopped reaching the owner.
22
- import { ownerDisplayError, isBridgeUnavailable, isOwnerPreviewDemo } from "../_shared/owner-load-error.js";
22
+ import { ownerDisplayError, isOwnerPreviewDemo, ownerDemoFallback } from "../_shared/owner-load-error.js";
23
23
  import { DEMO_DASHBOARD, DEMO_NOTE, DEMO_TODAY } from "../_shared/owner-preview-demo.js";
24
24
  import { stashCopy, copyParam, copyTemplate } from "../_shared/himi-copy.js";
25
25
  import { fallbackNameFrom, selectedSiteName } from "../_shared/owner-selected-site.js";
@@ -803,7 +803,7 @@ async function loadDashboard(s: HomeState, sources: HomeSourceId[]): Promise<Hom
803
803
  const successfulParts = results.flatMap(({ value }) => [value.primary, value.metrics, value.activity]).filter(Boolean);
804
804
  const failedReasons = results.flatMap(({ value }) => [value.primaryReason, value.metricsReason, value.activityReason]).filter((reason) => reason !== undefined);
805
805
  if (successfulParts.length === 0) {
806
- if (failedReasons.length > 0 && failedReasons.every((reason) => isBridgeUnavailable(reason))) {
806
+ if (failedReasons.length > 0 && failedReasons.every((reason) => ownerDemoFallback(reason))) {
807
807
  return demoDashboard(shape({ ...s, sourceStates: [], sourceFailures: [] }));
808
808
  }
809
809
  return shape({ ...composeState(), status: "error", error: ownerDisplayError(failedReasons[0]) });
@@ -8,7 +8,7 @@
8
8
 
9
9
  import { defineService } from "@himalaya/state";
10
10
  import { getOrder, type WixOrder, type WixOrderLineItem } from "@himalaya/wix-ecom";
11
- import { ownerLoadError, isBridgeUnavailable, isOwnerPreviewDemo } from "../_shared/owner-load-error.js";
11
+ import { ownerLoadError, isOwnerPreviewDemo, ownerDemoFallback } from "../_shared/owner-load-error.js";
12
12
  import { DEMO_ORDERS, DEMO_NOTE, demoOrderDate } from "../_shared/owner-preview-demo.js";
13
13
  import { stashCopy, copyParam } from "../_shared/himi-copy.js";
14
14
  import { formatDateMedium } from "../_shared/engine-intl.js";
@@ -298,7 +298,7 @@ const svc = defineService<OrderState, {
298
298
  try {
299
299
  return await refresh(shape({ ...s, id, status: "loading" }), id);
300
300
  } catch (e) {
301
- if (isBridgeUnavailable(e)) {
301
+ if (ownerDemoFallback(e)) {
302
302
  const demo = demoDetail(s, id);
303
303
  if (demo) return demo;
304
304
  }
@@ -356,7 +356,7 @@ const svc = defineService<OrderState, {
356
356
  try {
357
357
  return await refresh(shape({ ...s, status: "loading" }), s.id);
358
358
  } catch (e) {
359
- if (isBridgeUnavailable(e)) {
359
+ if (ownerDemoFallback(e)) {
360
360
  const demo = demoDetail(s, s.id);
361
361
  if (demo) return demo;
362
362
  }
@@ -8,7 +8,7 @@
8
8
 
9
9
  import { defineBackendCollection } from "../_shared/collection-service.js";
10
10
  import { searchOrders, type WixOrder } from "@himalaya/wix-ecom";
11
- import { ownerLoadError, isBridgeUnavailable, isOwnerPreviewDemo } from "../_shared/owner-load-error.js";
11
+ import { ownerLoadError, isOwnerPreviewDemo, ownerDemoFallback } from "../_shared/owner-load-error.js";
12
12
  import { DEMO_ORDERS, DEMO_NOTE, demoOrderDate } from "../_shared/owner-preview-demo.js";
13
13
  import { copyParam } from "../_shared/himi-copy.js";
14
14
  import { compareText, formatMonthDay } from "../_shared/engine-intl.js";
@@ -276,7 +276,7 @@ const svc = defineBackendCollection("himiOwnerLiteOrders", {
276
276
  if (metadata?.hasNext && !nextCursor) throw new Error("Orders response is missing its next-page cursor");
277
277
  return { items: (response.orders ?? []).filter(order => !!order?.id).map(normalize), nextCursor, metadata: { demoNote: "" } };
278
278
  } catch (error) {
279
- if (!cursor && isBridgeUnavailable(error)) return demoPage();
279
+ if (!cursor && ownerDemoFallback(error)) return demoPage();
280
280
  throw error;
281
281
  }
282
282
  },
@@ -27,7 +27,7 @@ import { defineService } from "@himalaya/state";
27
27
  import { querySites, type WixSite } from "@himalaya/wix-site-list";
28
28
  import { site } from "@himalaya/wix-platform";
29
29
  import { searchOrders } from "@himalaya/wix-ecom";
30
- import { ownerLoadError, isBridgeUnavailable, isOwnerPreviewDemo } from "../_shared/owner-load-error.js";
30
+ import { ownerLoadError, isOwnerPreviewDemo, ownerDemoFallback } from "../_shared/owner-load-error.js";
31
31
  import { DEMO_SITES, DEMO_NOTE } from "../_shared/owner-preview-demo.js";
32
32
  import { stashCopy, copyParam } from "../_shared/himi-copy.js";
33
33
  import { pickSite, pickedSite } from "../_shared/owner-site-pick.js";
@@ -203,7 +203,7 @@ async function loadRollup(): Promise<OverviewState> {
203
203
  return shape({ status: "ready", rows });
204
204
  } catch (e) {
205
205
  // Only the ACCOUNT-level list failing gets here; a per-business failure is a row.
206
- if (isBridgeUnavailable(e)) return demoRollup();
206
+ if (ownerDemoFallback(e)) return demoRollup();
207
207
  return shape({ status: "error", rows: [], error: ownerLoadError(e) });
208
208
  }
209
209
  }
@@ -10,25 +10,24 @@ import { getPost, getDraftPost, publishDraftPost, revertDraftPost, deleteDraftPo
10
10
  import { parseRicosJson } from "@himalaya/wix-rich-content";
11
11
  import { openRichLink } from "../_shared/rich-content-link.js";
12
12
  import { richBody } from "../_shared/rich-body.js";
13
- import { ownerLoadError, isBridgeUnavailable, isOwnerPreviewDemo, shouldQueueOwnerWrite } from "../_shared/owner-load-error.js";
13
+ import { ownerLoadError, isBridgeUnavailable, isTransportFailure, isOwnerPreviewDemo, ownerDemoFallback, ownerWriteError, isNotFound } from "../_shared/owner-load-error.js";
14
14
  import { DEMO_POSTS, DEMO_NOTE, DEMO_SAVE_NOTE } from "../_shared/owner-preview-demo.js";
15
15
  import { stashCopy, copyParam } from "../_shared/himi-copy.js";
16
- import { get as dbGet, upsert as dbUpsert, remove as dbRemove, enqueue as dbEnqueue, type DbEntity } from "../_shared/owner-local-db.js";
16
+ import { get as dbGet, upsert as dbUpsert, remove as dbRemove, type DbEntity } from "../_shared/owner-local-db.js";
17
17
  import { formatDateMedium } from "../_shared/engine-intl.js";
18
18
  import { blankFlags } from "../_shared/detail-facts.js";
19
19
 
20
- // Offline-first (data-offline): owner CRUD is WRITE-BEHIND against the encrypted
21
- // `owner_posts` entity — publish/unpublish/delete update the local store
22
- // OPTIMISTICALLY so the detail/list repaint from cache immediately, then the wix
23
- // write is attempted; if it can't reach the bridge/network the mutation is ENQUEUED
24
- // for replay on reconnect, and detail reads fall back to the last-synced local row.
20
+ // Offline-first (data-offline): detail reads fall back to the last-synced local row
21
+ // of the encrypted `owner_posts` entity. Publish/unpublish/delete are
22
+ // SERVER-CONFIRMED: the local row changes only after Wix accepts the write; a failed
23
+ // one leaves it alone and tells the owner why. No host replays a queued write, so
24
+ // nothing is queued.
25
25
  // Every local-db call is wrapped (try/catch) so a build that ships without the
26
- // `local_database` grant behaves exactly as before (online-only, no cache/queue).
26
+ // `local_database` grant behaves exactly as before (online-only, no cache).
27
27
  const ENTITY = "owner_posts";
28
28
  async function cachePut(row: DbEntity): Promise<void> { try { await dbUpsert(ENTITY, row); } catch { /* capability not granted */ } }
29
29
  async function cacheDrop(id: string): Promise<void> { try { await dbRemove(ENTITY, id); } catch { /* capability not granted */ } }
30
30
  async function cacheGet(id: string): Promise<DbEntity | null> { try { return await dbGet(ENTITY, id); } catch { return null; } }
31
- async function queueWrite(actionId: string, params: Record<string, string>): Promise<void> { try { await dbEnqueue(actionId, params); } catch { /* capability not granted */ } }
32
31
  /** [rico] #3370 — keep the body's plain text with the post's cached row, so the offline detail shows it. It is
33
32
  * merged into the row the posts list wrote rather than replacing it; a later list re-sync writes its own rows
34
33
  * and drops it again, until the detail is next opened online. */
@@ -250,16 +249,39 @@ function cachedDetail(s: PostState, row: DbEntity): PostState {
250
249
  });
251
250
  }
252
251
 
253
- async function refresh(prev: PostState, id: string, actionMessage = ""): Promise<PostState> {
252
+ /** The re-read after a write Wix CONFIRMED: when it fails — thrown or as an error state
253
+ * ("post not found" for a 5xx on both reads) — the confirmed change stays on screen. */
254
+ async function reread(prev: PostState, actionMessage: string, confirmed: PostState): Promise<PostState> {
255
+ try {
256
+ // A reread right after a CONFIRMED write never drops the row that write just cached: a
257
+ // both-404 here is a lagging read, not proof the post is gone.
258
+ const next = await refresh(prev, prev.id, actionMessage, { dropIfGone: false });
259
+ return next.status === "error" ? confirmed : next;
260
+ } catch {
261
+ return confirmed;
262
+ }
263
+ }
264
+
265
+ async function refresh(prev: PostState, id: string, actionMessage = "", opts: { dropIfGone?: boolean } = {}): Promise<PostState> {
254
266
  let post: any | undefined;
255
267
  let draft: any | undefined;
256
268
  let lastError: unknown;
257
- try { post = (await getPost(id)).post; } catch (e) { lastError = e; /* draft-only */ }
269
+ let postError: unknown;
270
+ try { post = (await getPost(id)).post; } catch (e) { lastError = postError = e; /* draft-only */ }
258
271
  try { draft = (await getDraftPost(id)).draftPost; } catch (e) { lastError = e; /* published-only or missing */ }
259
272
  if (!post && !draft) {
260
273
  // Both arms swallowed their errors above; surface the DESIGNED bridge
261
- // boundary so the callers' catches can fall back to the demo post.
262
- if (isBridgeUnavailable(lastError)) throw lastError;
274
+ // boundary (and a device with no connection) so the callers' catches can fall
275
+ // back to the cached row or the demo post — never "post not found" for a post
276
+ // that was only unreachable.
277
+ // Either read counts: a published-only post's draft read is always a 404, so the
278
+ // published read's failure is the one that says whether the post was only unreachable.
279
+ for (const err of [postError, lastError]) {
280
+ if (isBridgeUnavailable(err) || isTransportFailure(err)) throw err;
281
+ }
282
+ // Wix says it is gone on BOTH reads (a published-only post's draft read is a 404 on its
283
+ // own): its cached row must not outlive it, or an offline load repaints a deleted post.
284
+ if (opts.dropIfGone !== false && isNotFound(postError) && isNotFound(lastError)) await cacheDrop(id);
263
285
  return shape({ ...prev, id, status: "error", title: "", error: copyParam("ownerPost.errorNotFound", "post not found"), actionMessage });
264
286
  }
265
287
  const title = (draft?.title || post?.title || "Untitled post").trim();
@@ -336,9 +358,10 @@ const svc = defineService<PostState, {
336
358
  return loaded;
337
359
  } catch (e) {
338
360
  // Offline: fall back to the last-synced local row before the demo/error paths.
339
- const cached = await cacheGet(id);
361
+ // Wix says it is gone (e.g. a delete whose reply was lost): drop the row, never show it.
362
+ const cached = isNotFound(e) ? (await cacheDrop(id), null) : await cacheGet(id);
340
363
  if (cached) return cachedDetail(s, cached);
341
- if (isBridgeUnavailable(e)) {
364
+ if (ownerDemoFallback(e)) {
342
365
  const demo = demoDetail(s, id);
343
366
  if (demo) return demo;
344
367
  }
@@ -359,9 +382,10 @@ const svc = defineService<PostState, {
359
382
  await cacheBodyText(loaded);
360
383
  return loaded;
361
384
  } catch (e) {
362
- const cached = await cacheGet(s.id);
385
+ // Wix says it is gone (e.g. a delete whose reply was lost): drop the row, never show it.
386
+ const cached = isNotFound(e) ? (await cacheDrop(s.id), null) : await cacheGet(s.id);
363
387
  if (cached) return cachedDetail(s, cached);
364
- if (isBridgeUnavailable(e)) {
388
+ if (ownerDemoFallback(e)) {
365
389
  const demo = demoDetail(s, s.id);
366
390
  if (demo) return demo;
367
391
  }
@@ -373,19 +397,18 @@ const svc = defineService<PostState, {
373
397
  if (isOwnerPreviewDemo() || s.demoNote) return shape({ ...s, actionMessage: copyParam("ownerCommon.demoSaveNote", DEMO_SAVE_NOTE) });
374
398
  if (!s.id) return shape({ ...s, actionMessage: copyParam("ownerPost.noIdMessage", "No post id.") });
375
399
  if (s.postStatusRaw === "PUBLISHED") return shape({ ...s, actionMessage: copyParam("ownerPost.alreadyPublished", "Post is already published.") });
376
- // Optimistic local write — the detail/list repaint from cache immediately.
377
- const optimistic = shape({ ...s, postStatusRaw: "PUBLISHED", postStatus: "Published", actionMessage: copyParam("ownerPost.publishedMessage", "Post published.") });
378
- await cachePut(cacheRow(optimistic));
379
400
  try {
380
401
  await publishDraftPost(s.id);
381
- return refresh(s, s.id, copyParam("ownerPost.publishedMessage", "Post published."));
382
402
  } catch (e) {
383
- if (shouldQueueOwnerWrite(e)) {
384
- await queueWrite("tier5.himiOwnerLitePost.publish", { id: s.id });
385
- return shape({ ...optimistic, actionMessage: copyParam("ownerCommon.demoSaveNote", DEMO_SAVE_NOTE) });
386
- }
387
- return shape({ ...s, actionMessage: ownerLoadError(e) });
403
+ // Nothing replays a queued write: the post is as it was, and the owner is told why.
404
+ return shape({ ...s, actionMessage: ownerWriteError(e) });
388
405
  }
406
+ // Wix confirmed it: the list repaints from cache at once, and a re-read that fails
407
+ // afterwards still shows the confirmed change rather than undoing it on screen.
408
+ const published = copyParam("ownerPost.publishedMessage", "Post published.");
409
+ const confirmed = shape({ ...s, postStatusRaw: "PUBLISHED", postStatus: "Published", actionMessage: published });
410
+ await cachePut(cacheRow(confirmed));
411
+ return reread(s, published, confirmed);
389
412
  },
390
413
  unpublish: async (s0) => {
391
414
  const s = disarm(s0);
@@ -394,19 +417,16 @@ const svc = defineService<PostState, {
394
417
  if (s.postStatusRaw !== "PUBLISHED" && s.postStatusRaw !== "SCHEDULED") {
395
418
  return shape({ ...s, actionMessage: copyParam("ownerPost.alreadyDraft", "Post is already a draft.") });
396
419
  }
397
- // Optimistic local write — the detail/list repaint from cache immediately.
398
- const optimistic = shape({ ...s, postStatusRaw: "UNPUBLISHED", postStatus: "Draft", actionMessage: "Post moved to drafts." });
399
- await cachePut(cacheRow(optimistic));
400
420
  try {
401
421
  await revertDraftPost(s.id);
402
- return refresh(s, s.id, copyParam("ownerPost.unpublishedMessage", "Post moved to drafts."));
403
422
  } catch (e) {
404
- if (shouldQueueOwnerWrite(e)) {
405
- await queueWrite("tier5.himiOwnerLitePost.unpublish", { id: s.id });
406
- return shape({ ...optimistic, actionMessage: copyParam("ownerCommon.demoSaveNote", DEMO_SAVE_NOTE) });
407
- }
408
- return shape({ ...s, actionMessage: ownerLoadError(e) });
423
+ // Nothing replays a queued write: the post is as it was, and the owner is told why.
424
+ return shape({ ...s, actionMessage: ownerWriteError(e) });
409
425
  }
426
+ const unpublished = copyParam("ownerPost.unpublishedMessage", "Post moved to drafts.");
427
+ const confirmed = shape({ ...s, postStatusRaw: "UNPUBLISHED", postStatus: "Draft", actionMessage: unpublished });
428
+ await cachePut(cacheRow(confirmed));
429
+ return reread(s, unpublished, confirmed);
410
430
  },
411
431
  // #3158 — destructive, so two steps. `delete` (the Manage card's Delete button)
412
432
  // only ARMS the inline confirmation, which names the record and says it cannot
@@ -423,18 +443,15 @@ const svc = defineService<PostState, {
423
443
  const s = disarm(s0);
424
444
  if (isOwnerPreviewDemo() || s.demoNote) return shape({ ...s, actionMessage: copyParam("ownerCommon.demoSaveNote", DEMO_SAVE_NOTE) });
425
445
  if (!s.id) return shape({ ...s, actionMessage: copyParam("ownerPost.noIdMessage", "No post id.") });
426
- // Optimistic local delete — the list drops the row immediately.
427
- await cacheDrop(s.id);
428
446
  try {
429
447
  await deleteDraftPost(s.id);
430
- return shape({ ...s, status: "deleted", title: "", emptyText: copyParam("ownerPost.deletedEmpty", "Post deleted."), actionMessage: "" });
431
448
  } catch (e) {
432
- if (shouldQueueOwnerWrite(e)) {
433
- await queueWrite("tier5.himiOwnerLitePost.delete", { id: s.id });
434
- return shape({ ...s, status: "deleted", title: "", emptyText: copyParam("ownerPost.deletedEmpty", "Post deleted."), actionMessage: copyParam("ownerCommon.demoSaveNote", DEMO_SAVE_NOTE) });
435
- }
436
- return shape({ ...s, actionMessage: ownerLoadError(e) });
449
+ // Nothing replays a queued write: the post stays, and the owner is told why.
450
+ return shape({ ...s, actionMessage: ownerWriteError(e) });
437
451
  }
452
+ // Only a delete Wix confirmed leaves the local list.
453
+ await cacheDrop(s.id);
454
+ return shape({ ...s, status: "deleted", title: "", emptyText: copyParam("ownerPost.deletedEmpty", "Post deleted."), actionMessage: "" });
438
455
  } finally {
439
456
  deleteInFlight = false;
440
457
  }