cloudcommerce 0.26.7 → 0.28.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 (248) hide show
  1. package/.github/workflows/test-apps.yml +2 -2
  2. package/.gitmodules +0 -3
  3. package/.vscode/settings.json +3 -1
  4. package/CHANGELOG.md +51 -0
  5. package/action.yml +2 -2
  6. package/ecomplus-stores/barra-doce/functions/many/package.json +3 -3
  7. package/ecomplus-stores/barra-doce/functions/ssr/content/layout.json +13 -13
  8. package/ecomplus-stores/barra-doce/functions/ssr/content/pages/home.json +10 -10
  9. package/ecomplus-stores/barra-doce/functions/ssr/content/pages/products.json +17 -0
  10. package/ecomplus-stores/barra-doce/functions/ssr/content/settings.json +8 -8
  11. package/ecomplus-stores/barra-doce/functions/ssr/package.json +6 -6
  12. package/ecomplus-stores/barra-doce/functions/ssr/src/components/AccountMenu.vue +11 -11
  13. package/ecomplus-stores/barra-doce/functions/ssr/src/components/ShopFooter.vue +24 -24
  14. package/ecomplus-stores/barra-doce/functions/ssr/src/layouts/PageFooter.astro +4 -4
  15. package/ecomplus-stores/barra-doce/functions/with-apps/package.json +3 -3
  16. package/ecomplus-stores/barra-doce/package.json +2 -2
  17. package/ecomplus-stores/monocard/functions/many/package.json +3 -3
  18. package/ecomplus-stores/monocard/functions/ssr/content/layout.json +11 -11
  19. package/ecomplus-stores/monocard/functions/ssr/content/pages/home.json +16 -16
  20. package/ecomplus-stores/monocard/functions/ssr/content/pages/products.json +2 -4
  21. package/ecomplus-stores/monocard/functions/ssr/content/settings.json +11 -11
  22. package/ecomplus-stores/monocard/functions/ssr/package.json +6 -6
  23. package/ecomplus-stores/monocard/functions/ssr/src/components/AccountMenu.vue +1 -1
  24. package/ecomplus-stores/monocard/functions/ssr/src/components/DocDescription.vue +33 -0
  25. package/ecomplus-stores/monocard/functions/ssr/src/components/FeatureTabs.vue +3 -3
  26. package/ecomplus-stores/monocard/functions/ssr/src/components/ShopFooter.vue +3 -3
  27. package/ecomplus-stores/monocard/functions/ssr/src/components/ShopHeader.vue +5 -13
  28. package/ecomplus-stores/monocard/functions/ssr/src/layouts/PageFooter.astro +2 -2
  29. package/ecomplus-stores/monocard/functions/ssr/src/main/Home.astro +1 -1
  30. package/ecomplus-stores/monocard/functions/ssr/src/main/Sections.astro +1 -1
  31. package/ecomplus-stores/monocard/functions/with-apps/package.json +3 -3
  32. package/ecomplus-stores/monocard/package.json +2 -2
  33. package/package.json +6 -6
  34. package/packages/api/package.json +1 -1
  35. package/packages/apps/affilate-program/package.json +2 -2
  36. package/packages/apps/correios/package.json +3 -4
  37. package/packages/apps/custom-payment/package.json +1 -1
  38. package/packages/apps/custom-shipping/package.json +1 -1
  39. package/packages/apps/datafrete/package.json +3 -3
  40. package/packages/apps/discounts/package.json +1 -1
  41. package/packages/apps/emails/lib/functios-lib/utils.js +1 -1
  42. package/packages/apps/emails/lib/functios-lib/utils.js.map +1 -1
  43. package/packages/apps/emails/package.json +2 -2
  44. package/packages/apps/emails/src/functios-lib/utils.ts +1 -1
  45. package/packages/apps/fb-conversions/package.json +3 -3
  46. package/packages/apps/flash-courier/package.json +2 -2
  47. package/packages/apps/frenet/package.json +3 -3
  48. package/packages/apps/galaxpay/package.json +3 -3
  49. package/packages/apps/google-analytics/package.json +3 -3
  50. package/packages/apps/jadlog/package.json +2 -2
  51. package/packages/apps/loyalty-points/lib/functions-lib/cron-add-points.d.ts +2 -0
  52. package/packages/apps/loyalty-points/lib/functions-lib/cron-add-points.js +98 -0
  53. package/packages/apps/loyalty-points/lib/functions-lib/cron-add-points.js.map +1 -0
  54. package/packages/apps/loyalty-points/lib/functions-lib/handle-loyalty-points-event.js +59 -23
  55. package/packages/apps/loyalty-points/lib/functions-lib/handle-loyalty-points-event.js.map +1 -1
  56. package/packages/apps/loyalty-points/lib/loyalty-create-transaction.js +9 -4
  57. package/packages/apps/loyalty-points/lib/loyalty-create-transaction.js.map +1 -1
  58. package/packages/apps/loyalty-points/lib/loyalty-list-payments.js +7 -2
  59. package/packages/apps/loyalty-points/lib/loyalty-list-payments.js.map +1 -1
  60. package/packages/apps/loyalty-points/lib/loyalty-points-events.d.ts +3 -1
  61. package/packages/apps/loyalty-points/lib/loyalty-points-events.js +9 -0
  62. package/packages/apps/loyalty-points/lib/loyalty-points-events.js.map +1 -1
  63. package/packages/apps/loyalty-points/package.json +3 -2
  64. package/packages/apps/loyalty-points/src/functions-lib/cron-add-points.ts +104 -0
  65. package/packages/apps/loyalty-points/src/functions-lib/handle-loyalty-points-event.ts +67 -25
  66. package/packages/apps/loyalty-points/src/loyalty-create-transaction.ts +11 -4
  67. package/packages/apps/loyalty-points/src/loyalty-list-payments.ts +9 -2
  68. package/packages/apps/loyalty-points/src/loyalty-points-events.ts +12 -1
  69. package/packages/apps/melhor-envio/package.json +3 -3
  70. package/packages/apps/mercadopago/assets/onload-expression.js +5 -1
  71. package/packages/apps/mercadopago/assets/onload-expression.min.js +1 -1
  72. package/packages/apps/mercadopago/lib/mp-create-transaction.js +16 -6
  73. package/packages/apps/mercadopago/lib/mp-create-transaction.js.map +1 -1
  74. package/packages/apps/mercadopago/package.json +3 -3
  75. package/packages/apps/mercadopago/src/mp-create-transaction.ts +19 -7
  76. package/packages/apps/pagarme/package.json +3 -3
  77. package/packages/apps/paghiper/package.json +3 -3
  78. package/packages/apps/pix/package.json +3 -3
  79. package/packages/apps/tiny-erp/lib/integration/export-order-to-tiny.js +22 -0
  80. package/packages/apps/tiny-erp/lib/integration/export-order-to-tiny.js.map +1 -1
  81. package/packages/apps/tiny-erp/lib/integration/helpers/format-tiny-date.js +2 -2
  82. package/packages/apps/tiny-erp/lib/integration/helpers/format-tiny-date.js.map +1 -1
  83. package/packages/apps/tiny-erp/lib/integration/import-order-from-tiny.js +7 -1
  84. package/packages/apps/tiny-erp/lib/integration/import-order-from-tiny.js.map +1 -1
  85. package/packages/apps/tiny-erp/lib/integration/import-product-from-tiny.js +14 -5
  86. package/packages/apps/tiny-erp/lib/integration/import-product-from-tiny.js.map +1 -1
  87. package/packages/apps/tiny-erp/lib/integration/parsers/order-from-tiny.js +9 -1
  88. package/packages/apps/tiny-erp/lib/integration/parsers/order-from-tiny.js.map +1 -1
  89. package/packages/apps/tiny-erp/lib/integration/parsers/order-to-tiny.js +8 -6
  90. package/packages/apps/tiny-erp/lib/integration/parsers/order-to-tiny.js.map +1 -1
  91. package/packages/apps/tiny-erp/lib/integration/parsers/product-from-tiny.js +118 -38
  92. package/packages/apps/tiny-erp/lib/integration/parsers/product-from-tiny.js.map +1 -1
  93. package/packages/apps/tiny-erp/lib/integration/parsers/product-to-tiny.js +8 -0
  94. package/packages/apps/tiny-erp/lib/integration/parsers/product-to-tiny.js.map +1 -1
  95. package/packages/apps/tiny-erp/package.json +3 -3
  96. package/packages/apps/tiny-erp/src/integration/export-order-to-tiny.ts +24 -0
  97. package/packages/apps/tiny-erp/src/integration/helpers/format-tiny-date.ts +2 -2
  98. package/packages/apps/tiny-erp/src/integration/import-order-from-tiny.ts +8 -1
  99. package/packages/apps/tiny-erp/src/integration/import-product-from-tiny.ts +17 -5
  100. package/packages/apps/tiny-erp/src/integration/parsers/order-from-tiny.ts +13 -1
  101. package/packages/apps/tiny-erp/src/integration/parsers/order-to-tiny.ts +11 -6
  102. package/packages/apps/tiny-erp/src/integration/parsers/product-from-tiny.ts +144 -41
  103. package/packages/apps/tiny-erp/src/integration/parsers/product-to-tiny.ts +10 -0
  104. package/packages/apps/webhooks/package.json +3 -3
  105. package/packages/cli/package.json +1 -1
  106. package/packages/config/lib/config.js +2 -2
  107. package/packages/config/lib/config.js.map +1 -1
  108. package/packages/config/package.json +1 -1
  109. package/packages/config/src/config.ts +2 -2
  110. package/packages/emails/package.json +4 -4
  111. package/packages/eslint/base.eslintrc.cjs +3 -0
  112. package/packages/eslint/package.json +5 -4
  113. package/packages/eslint/storefront.eslintrc.cjs +8 -1
  114. package/packages/events/package.json +2 -2
  115. package/packages/feeds/package.json +1 -1
  116. package/packages/firebase/package.json +2 -2
  117. package/packages/i18n/package.json +1 -1
  118. package/packages/modules/package.json +3 -3
  119. package/packages/passport/package.json +2 -2
  120. package/packages/ssr/package.json +3 -3
  121. package/packages/storefront/.auto-imports.d.ts +65 -0
  122. package/packages/storefront/astro.config.mjs +24 -1
  123. package/packages/storefront/client.d.ts +1 -0
  124. package/packages/storefront/config/astro/context-directive.mjs +21 -0
  125. package/packages/storefront/config/astro/index.d.ts +8 -0
  126. package/packages/storefront/config/storefront.cms.js +2 -2
  127. package/packages/storefront/config/storefront.tailwind.cjs +0 -1
  128. package/packages/storefront/package.json +4 -3
  129. package/packages/storefront/server.d.ts +1 -1
  130. package/packages/storefront/src/lib/$storefront.d.ts +8 -8
  131. package/packages/storefront/src/lib/assets/base.css +5 -0
  132. package/packages/storefront/src/lib/components/Carousel.vue +93 -72
  133. package/packages/storefront/src/lib/components/CarouselControl.vue +13 -7
  134. package/packages/storefront/src/lib/components/ContentClearfix.vue +17 -0
  135. package/packages/storefront/src/lib/components/Drawer.vue +2 -2
  136. package/packages/storefront/src/lib/components/PaymentMethodFlag.vue +2 -2
  137. package/packages/storefront/src/lib/components/QuantitySelector.vue +4 -4
  138. package/packages/storefront/src/lib/components/QuantitySelectorControl.vue +2 -2
  139. package/packages/storefront/src/lib/components/ViewTransitions.astro +409 -0
  140. package/packages/storefront/src/lib/components/globals/AImg.vue +2 -1
  141. package/packages/storefront/src/lib/composables/use-pitch-bar.ts +2 -2
  142. package/packages/storefront/src/lib/content.d.ts +5 -5
  143. package/packages/storefront/src/lib/layouts/Base.astro +4 -4
  144. package/packages/storefront/src/lib/layouts/BaseBody.astro +0 -2
  145. package/packages/storefront/src/lib/layouts/BaseHead.astro +32 -14
  146. package/packages/storefront/src/lib/layouts/use-page-header.ts +9 -4
  147. package/packages/storefront/src/lib/layouts/use-page-main.ts +13 -33
  148. package/packages/test-base/package.json +1 -1
  149. package/packages/types/index.ts +14 -14
  150. package/packages/types/package.json +1 -1
  151. package/ecomplus-stores/iluminim/.devcontainer/devcontainer.json +0 -30
  152. package/ecomplus-stores/iluminim/.editorconfig +0 -13
  153. package/ecomplus-stores/iluminim/.eslintrc.cjs +0 -3
  154. package/ecomplus-stores/iluminim/.firebaserc +0 -5
  155. package/ecomplus-stores/iluminim/.github/renovate.json +0 -5
  156. package/ecomplus-stores/iluminim/.github/workflows/build-and-deploy.yml +0 -36
  157. package/ecomplus-stores/iluminim/.github/workflows/calibreapp-image-actions.yml +0 -23
  158. package/ecomplus-stores/iluminim/.gitpod.yml +0 -12
  159. package/ecomplus-stores/iluminim/.idx/dev.nix +0 -24
  160. package/ecomplus-stores/iluminim/.nvmrc +0 -1
  161. package/ecomplus-stores/iluminim/.vscode/extensions.json +0 -8
  162. package/ecomplus-stores/iluminim/.vscode/launch.json +0 -11
  163. package/ecomplus-stores/iluminim/.vscode/settings.json +0 -10
  164. package/ecomplus-stores/iluminim/README.md +0 -31
  165. package/ecomplus-stores/iluminim/SETUP.md +0 -117
  166. package/ecomplus-stores/iluminim/SETUP.pt-BR.md +0 -117
  167. package/ecomplus-stores/iluminim/functions/config.json +0 -3
  168. package/ecomplus-stores/iluminim/functions/example.env +0 -10
  169. package/ecomplus-stores/iluminim/functions/many/index.js +0 -14
  170. package/ecomplus-stores/iluminim/functions/many/package.json +0 -22
  171. package/ecomplus-stores/iluminim/functions/ssr/.eslintrc.cjs +0 -6
  172. package/ecomplus-stores/iluminim/functions/ssr/astro.config.mjs +0 -4
  173. package/ecomplus-stores/iluminim/functions/ssr/content/blog/.gitkeep +0 -0
  174. package/ecomplus-stores/iluminim/functions/ssr/content/extra-pages/contato.json +0 -11
  175. package/ecomplus-stores/iluminim/functions/ssr/content/extra-pages/terms.json +0 -11
  176. package/ecomplus-stores/iluminim/functions/ssr/content/extra-pages/trocas.json +0 -11
  177. package/ecomplus-stores/iluminim/functions/ssr/content/layout.json +0 -57
  178. package/ecomplus-stores/iluminim/functions/ssr/content/pages/home.json +0 -70
  179. package/ecomplus-stores/iluminim/functions/ssr/content/settings.json +0 -65
  180. package/ecomplus-stores/iluminim/functions/ssr/index.js +0 -18
  181. package/ecomplus-stores/iluminim/functions/ssr/package.json +0 -31
  182. package/ecomplus-stores/iluminim/functions/ssr/public/admin/.gitkeep +0 -2
  183. package/ecomplus-stores/iluminim/functions/ssr/public/assets/cms-preview.css +0 -274
  184. package/ecomplus-stores/iluminim/functions/ssr/public/assets/cms.css +0 -114
  185. package/ecomplus-stores/iluminim/functions/ssr/public/assets/cvv.png +0 -0
  186. package/ecomplus-stores/iluminim/functions/ssr/public/assets/img-placeholder.png +0 -0
  187. package/ecomplus-stores/iluminim/functions/ssr/public/assets/payments.png +0 -0
  188. package/ecomplus-stores/iluminim/functions/ssr/public/assets/ssl-safe.png +0 -0
  189. package/ecomplus-stores/iluminim/functions/ssr/public/img/icon.png +0 -0
  190. package/ecomplus-stores/iluminim/functions/ssr/public/img/large-icon.png +0 -0
  191. package/ecomplus-stores/iluminim/functions/ssr/public/img/uploads/banner-chamada-desktop-9x81zmd91q.webp +0 -0
  192. package/ecomplus-stores/iluminim/functions/ssr/public/img/uploads/banner2.webp +0 -0
  193. package/ecomplus-stores/iluminim/functions/ssr/public/img/uploads/chamada-mobile-q1c6om6jx4.webp +0 -0
  194. package/ecomplus-stores/iluminim/functions/ssr/public/img/uploads/ecom-icon.png +0 -0
  195. package/ecomplus-stores/iluminim/functions/ssr/public/img/uploads/headphone.webp +0 -0
  196. package/ecomplus-stores/iluminim/functions/ssr/public/img/uploads/logo.webp +0 -0
  197. package/ecomplus-stores/iluminim/functions/ssr/public/img/uploads/og-image.png +0 -0
  198. package/ecomplus-stores/iluminim/functions/ssr/public/img/uploads/passion.webp +0 -0
  199. package/ecomplus-stores/iluminim/functions/ssr/public/img/uploads/rect8589.png +0 -0
  200. package/ecomplus-stores/iluminim/functions/ssr/public/img/uploads/rect859.png +0 -0
  201. package/ecomplus-stores/iluminim/functions/ssr/public/img/uploads/rect89.webp +0 -0
  202. package/ecomplus-stores/iluminim/functions/ssr/public/robots.txt +0 -6
  203. package/ecomplus-stores/iluminim/functions/ssr/scripts/build.sh +0 -14
  204. package/ecomplus-stores/iluminim/functions/ssr/src/assets/style.css +0 -65
  205. package/ecomplus-stores/iluminim/functions/ssr/src/components/AccountMenu.vue +0 -95
  206. package/ecomplus-stores/iluminim/functions/ssr/src/components/Banner.vue +0 -57
  207. package/ecomplus-stores/iluminim/functions/ssr/src/components/BannersGrid.astro +0 -25
  208. package/ecomplus-stores/iluminim/functions/ssr/src/components/CartItem.vue +0 -64
  209. package/ecomplus-stores/iluminim/functions/ssr/src/components/CartSidebar.vue +0 -66
  210. package/ecomplus-stores/iluminim/functions/ssr/src/components/Countdown.vue +0 -79
  211. package/ecomplus-stores/iluminim/functions/ssr/src/components/HeroSlider.vue +0 -52
  212. package/ecomplus-stores/iluminim/functions/ssr/src/components/PitchBar.vue +0 -56
  213. package/ecomplus-stores/iluminim/functions/ssr/src/components/Prices.vue +0 -95
  214. package/ecomplus-stores/iluminim/functions/ssr/src/components/ProductCard.vue +0 -117
  215. package/ecomplus-stores/iluminim/functions/ssr/src/components/ProductShelf.vue +0 -57
  216. package/ecomplus-stores/iluminim/functions/ssr/src/components/ProductsCountdown.vue +0 -20
  217. package/ecomplus-stores/iluminim/functions/ssr/src/components/SearchModal.vue +0 -6
  218. package/ecomplus-stores/iluminim/functions/ssr/src/components/ShopFooter.vue +0 -149
  219. package/ecomplus-stores/iluminim/functions/ssr/src/components/ShopHeader.vue +0 -158
  220. package/ecomplus-stores/iluminim/functions/ssr/src/components/ShopHeaderMenu.vue +0 -58
  221. package/ecomplus-stores/iluminim/functions/ssr/src/components/ShopHeaderSubmenu.vue +0 -88
  222. package/ecomplus-stores/iluminim/functions/ssr/src/components/ShopSidenav.vue +0 -61
  223. package/ecomplus-stores/iluminim/functions/ssr/src/components/ShopSidenavCategory.vue +0 -80
  224. package/ecomplus-stores/iluminim/functions/ssr/src/env.d.ts +0 -13
  225. package/ecomplus-stores/iluminim/functions/ssr/src/layouts/Base.astro +0 -16
  226. package/ecomplus-stores/iluminim/functions/ssr/src/layouts/Checkout.astro +0 -0
  227. package/ecomplus-stores/iluminim/functions/ssr/src/layouts/PageFooter.astro +0 -68
  228. package/ecomplus-stores/iluminim/functions/ssr/src/layouts/PageHeader.astro +0 -42
  229. package/ecomplus-stores/iluminim/functions/ssr/src/main/Fallback.astro +0 -10
  230. package/ecomplus-stores/iluminim/functions/ssr/src/main/Home.astro +0 -49
  231. package/ecomplus-stores/iluminim/functions/ssr/src/main/Sections.astro +0 -42
  232. package/ecomplus-stores/iluminim/functions/ssr/src/main/Wildcard.astro +0 -18
  233. package/ecomplus-stores/iluminim/functions/ssr/src/pages/[...slug].astro +0 -40
  234. package/ecomplus-stores/iluminim/functions/ssr/src/pages/_vue.ts +0 -3
  235. package/ecomplus-stores/iluminim/functions/ssr/src/pages/app/account.astro +0 -0
  236. package/ecomplus-stores/iluminim/functions/ssr/src/pages/app/index.astro +0 -0
  237. package/ecomplus-stores/iluminim/functions/ssr/src/pages/index.astro +0 -37
  238. package/ecomplus-stores/iluminim/functions/ssr/src/pages/~fallback.astro +0 -25
  239. package/ecomplus-stores/iluminim/functions/ssr/src/scripts/InlineScripts.astro +0 -10
  240. package/ecomplus-stores/iluminim/functions/ssr/tailwind.config.cjs +0 -13
  241. package/ecomplus-stores/iluminim/functions/ssr/tsconfig.json +0 -12
  242. package/ecomplus-stores/iluminim/functions/ssr/uno.config.cjs +0 -5
  243. package/ecomplus-stores/iluminim/functions/with-apps/index.js +0 -12
  244. package/ecomplus-stores/iluminim/functions/with-apps/package.json +0 -22
  245. package/ecomplus-stores/iluminim/package.json +0 -31
  246. package/ecomplus-stores/iluminim/scripts/install.sh +0 -24
  247. package/ecomplus-stores/monocard/functions/ssr/src/components/DocDescription.astro +0 -30
  248. package/packages/storefront/src/lib/components/ContentClearfix.astro +0 -15
@@ -0,0 +1,409 @@
1
+ ---
2
+ type Fallback = 'none' | 'animate' | 'swap';
3
+
4
+ export interface Props {
5
+ fallback?: Fallback;
6
+ }
7
+
8
+ const { fallback = 'animate' } = Astro.props as Props;
9
+ ---
10
+
11
+ <meta name="astro-view-transitions-enabled" content="true" />
12
+ <meta name="astro-view-transitions-fallback" content={fallback} />
13
+ <script>
14
+ type Fallback = 'none' | 'animate' | 'swap';
15
+ type Direction = 'forward' | 'back';
16
+ type State = {
17
+ index: number;
18
+ scrollY: number;
19
+ };
20
+ type Events = 'astro:load' | 'astro:beforeload';
21
+
22
+ const persistState = (state: State) => history.replaceState(state, '');
23
+ // @ts-ignore
24
+ const supportsViewTransitions = !!document.startViewTransition;
25
+ const transitionEnabledOnThisPage = () =>
26
+ !!document.querySelector('[name="astro-view-transitions-enabled"]');
27
+ const triggerEvent = (name: Events) => document.dispatchEvent(new Event(name));
28
+ const onload = () => triggerEvent('astro:load');
29
+ const PERSIST_ATTR = 'data-astro-transition-persist';
30
+
31
+ // The History API does not tell you if navigation is forward or back, so
32
+ // you can figure it using an index. On pushState the index is incremented so you
33
+ // can use that to determine popstate if going forward or back.
34
+ let currentHistoryIndex = history.state?.index || 0;
35
+ if (!history.state && transitionEnabledOnThisPage()) {
36
+ persistState({ index: currentHistoryIndex, scrollY: 0 });
37
+ }
38
+
39
+ const throttle = (cb: (...args: any[]) => any, delay: number) => {
40
+ let wait = false;
41
+ // During the waiting time additional events are lost.
42
+ // So repeat the callback at the end if we have swallowed events.
43
+ let onceMore = false;
44
+ return (...args: any[]) => {
45
+ if (wait) {
46
+ onceMore = true;
47
+ return;
48
+ }
49
+ cb(...args);
50
+ wait = true;
51
+ setTimeout(() => {
52
+ if (onceMore) {
53
+ onceMore = false;
54
+ cb(...args);
55
+ }
56
+ wait = false;
57
+ }, delay);
58
+ };
59
+ };
60
+
61
+ async function getHTML(href: string) {
62
+ const res = await fetch(href);
63
+ const html = await res.text();
64
+ return { ok: res.ok, html };
65
+ }
66
+
67
+ function getFallback(): Fallback {
68
+ const el = document.querySelector('[name="astro-view-transitions-fallback"]');
69
+ if (el) {
70
+ return el.getAttribute('content') as Fallback;
71
+ }
72
+ return 'animate';
73
+ }
74
+
75
+ function markScriptsExec() {
76
+ for (const script of document.scripts) {
77
+ script.dataset.astroExec = '';
78
+ }
79
+ }
80
+
81
+ function runScripts() {
82
+ let wait = Promise.resolve();
83
+ for (const script of Array.from(document.scripts)) {
84
+ if (script.dataset.astroExec === '') continue;
85
+ const s = document.createElement('script');
86
+ s.innerHTML = script.innerHTML;
87
+ for (const attr of script.attributes) {
88
+ if (attr.name === 'src') {
89
+ const p = new Promise((r) => {
90
+ s.onload = r;
91
+ });
92
+ wait = wait.then(() => p as any);
93
+ }
94
+ s.setAttribute(attr.name, attr.value);
95
+ }
96
+ s.dataset.astroExec = '';
97
+ script.replaceWith(s);
98
+ }
99
+ return wait;
100
+ }
101
+
102
+ const parser = new DOMParser();
103
+
104
+ async function updateDOM(html: string, state?: State, fallback?: Fallback) {
105
+ const doc = parser.parseFromString(html, 'text/html');
106
+
107
+ // Check for a head element that should persist, either because it has the data
108
+ // attribute or is a link el.
109
+ const persistedHeadElement = (el: Element): Element | null => {
110
+ const id = el.getAttribute(PERSIST_ATTR);
111
+ const newEl = id && doc.head.querySelector(`[${PERSIST_ATTR}="${id}"]`);
112
+ if (newEl) {
113
+ return newEl;
114
+ }
115
+ if (el.matches('link[rel=stylesheet]')) {
116
+ const href = el.getAttribute('href');
117
+ return doc.head.querySelector(`link[rel=stylesheet][href="${href}"]`);
118
+ }
119
+ if (el.tagName === 'SCRIPT') {
120
+ let s1 = el as HTMLScriptElement;
121
+ for (const s2 of doc.scripts) {
122
+ if (
123
+ // Inline
124
+ (s1.textContent && s1.textContent === s2.textContent) ||
125
+ // External
126
+ (s1.type === s2.type && s1.src && s1.src === s2.src)
127
+ ) {
128
+ return s2;
129
+ }
130
+ }
131
+ }
132
+ return null;
133
+ };
134
+
135
+ const swap = () => {
136
+ // noscript tags inside head element are not honored on swap (#7969).
137
+ // Remove them before swapping.
138
+ doc.querySelectorAll('head noscript').forEach((el) => el.remove());
139
+
140
+ // swap attributes of the html element
141
+ // - delete all attributes from the current document
142
+ // - insert all attributes from doc
143
+ // - reinsert all original attributes that are named 'data-astro-*'
144
+ const html = document.documentElement;
145
+ const astro = [...html.attributes].filter(
146
+ ({ name }) => (html.removeAttribute(name), name.startsWith('data-astro-'))
147
+ );
148
+ [...doc.documentElement.attributes, ...astro].forEach(({ name, value }) =>
149
+ html.setAttribute(name, value)
150
+ );
151
+
152
+ // Swap head
153
+ for (const el of Array.from(document.head.children)) {
154
+ const newEl = persistedHeadElement(el);
155
+ // If the element exists in the document already, remove it
156
+ // from the new document and leave the current node alone
157
+ if (newEl) {
158
+ newEl.remove();
159
+ } else {
160
+ // Otherwise remove the element in the head. It doesn't exist in the new page.
161
+ el.remove();
162
+ }
163
+ }
164
+ // Everything left in the new head is new, append it all.
165
+ document.head.append(...doc.head.children);
166
+
167
+ // Move over persist stuff in the body
168
+ const oldBody = document.body;
169
+ document.body.replaceWith(doc.body);
170
+ for (const el of oldBody.querySelectorAll(`[${PERSIST_ATTR}]`)) {
171
+ const id = el.getAttribute(PERSIST_ATTR);
172
+ const newEl = document.querySelector(`[${PERSIST_ATTR}="${id}"]`);
173
+ if (newEl) {
174
+ // The element exists in the new page, replace it with the element
175
+ // from the old page so that state is preserved.
176
+ newEl.replaceWith(el);
177
+ }
178
+ }
179
+
180
+ // Simulate scroll behavior of Safari and
181
+ // Chromium based browsers (Chrome, Edge, Opera, ...)
182
+ // @ts-ignore
183
+ scrollTo({ left: 0, top: 0, behavior: 'instant' });
184
+
185
+ if (state?.scrollY === 0 && location.hash) {
186
+ const id = decodeURIComponent(location.hash.slice(1));
187
+ const elem = document.getElementById(id);
188
+ // prefer scrollIntoView() over scrollTo() because it takes scroll-padding into account
189
+ if (elem) {
190
+ state.scrollY = elem.offsetTop;
191
+ persistState(state); // first guess, later updated by scroll handler
192
+ elem.scrollIntoView(); // for Firefox, this should better be {behavior: 'instant'}
193
+ }
194
+ } else if (state && state.scrollY !== 0) {
195
+ scrollTo(0, state.scrollY); // usings default scrollBehavior
196
+ }
197
+
198
+ triggerEvent('astro:beforeload');
199
+ };
200
+
201
+ // Wait on links to finish, to prevent FOUC
202
+ const links: Promise<any>[] = [];
203
+ for (const el of doc.querySelectorAll('head link[rel=stylesheet]')) {
204
+ // Do not preload links that are already on the page.
205
+ if (
206
+ !document.querySelector(
207
+ `[${PERSIST_ATTR}="${el.getAttribute(PERSIST_ATTR)}"], link[rel=stylesheet]`
208
+ )
209
+ ) {
210
+ const c = document.createElement('link');
211
+ c.setAttribute('rel', 'preload');
212
+ c.setAttribute('as', 'style');
213
+ c.setAttribute('href', el.getAttribute('href')!);
214
+ links.push(
215
+ new Promise<any>((resolve) => {
216
+ ['load', 'error'].forEach((evName) => c.addEventListener(evName, resolve));
217
+ document.head.append(c);
218
+ })
219
+ );
220
+ }
221
+ }
222
+ links.length && (await Promise.all(links));
223
+
224
+ if (fallback === 'animate') {
225
+ let isAnimating = false;
226
+ addEventListener('animationstart', () => (isAnimating = true), { once: true });
227
+
228
+ // Trigger the animations
229
+ document.documentElement.dataset.astroTransitionFallback = 'old';
230
+ await new Promise((resolve) => {
231
+ const fallbackSwap = () => {
232
+ removeEventListener('animationend', fallbackSwap);
233
+ clearTimeout(timeout);
234
+ swap();
235
+ resolve(true);
236
+ document.documentElement.dataset.astroTransitionFallback = 'new';
237
+ };
238
+ // If there are any animations, want for the animationend event.
239
+ addEventListener('animationend', fallbackSwap, { once: true });
240
+ // If there are no animations, go ahead and swap on next tick
241
+ // This is necessary because we do not know if there are animations.
242
+ // The setTimeout is a fallback in case there are none.
243
+ let timeout = setTimeout(() => !isAnimating && fallbackSwap());
244
+ });
245
+ } else {
246
+ swap();
247
+ }
248
+ }
249
+
250
+ async function navigate(dir: Direction, href: string, state?: State) {
251
+ let finished: Promise<void>;
252
+ const { html, ok } = await getHTML(href);
253
+ // If there is a problem fetching the new page, just do an MPA navigation to it.
254
+ if (!ok) {
255
+ location.href = href;
256
+ return;
257
+ }
258
+ document.documentElement.dataset.astroTransition = dir;
259
+ if (supportsViewTransitions) {
260
+ // @ts-ignore
261
+ finished = document.startViewTransition(() => updateDOM(html, state)).finished;
262
+ } else {
263
+ finished = updateDOM(html, state, getFallback());
264
+ }
265
+ try {
266
+ await finished;
267
+ } finally {
268
+ // skip this for the moment as it tends to stop fallback animations
269
+ // document.documentElement.removeAttribute('data-astro-transition');
270
+ await runScripts();
271
+ markScriptsExec();
272
+ onload();
273
+ }
274
+ }
275
+
276
+ // Prefetching
277
+ function maybePrefetch(pathname: string) {
278
+ if (document.querySelector(`link[rel=prefetch][href="${pathname}"]`)) return;
279
+ // @ts-ignore
280
+ if (navigator.connection) {
281
+ // @ts-ignore
282
+ let conn = navigator.connection;
283
+ if (conn.saveData || /(2|3)g/.test(conn.effectiveType || '')) return;
284
+ }
285
+ let link = document.createElement('link');
286
+ link.setAttribute('rel', 'prefetch');
287
+ link.setAttribute('href', pathname);
288
+ document.head.append(link);
289
+ }
290
+
291
+ if (supportsViewTransitions || getFallback() !== 'none') {
292
+ markScriptsExec();
293
+
294
+ document.addEventListener('click', (ev) => {
295
+ let link = ev.target;
296
+ if (link instanceof Element && link.tagName !== 'A') {
297
+ link = link.closest('a');
298
+ }
299
+ // This check verifies that the click is happening on an anchor
300
+ // that is going to another page within the same origin. Basically it determines
301
+ // same-origin navigation, but omits special key combos for new tabs, etc.
302
+ if (
303
+ !link ||
304
+ !(link instanceof HTMLAnchorElement) ||
305
+ !link.href ||
306
+ (link.target && link.target !== '_self') ||
307
+ link.origin !== location.origin ||
308
+ ev.button !== 0 || // left clicks only
309
+ ev.metaKey || // new tab (mac)
310
+ ev.ctrlKey || // new tab (windows)
311
+ ev.altKey || // download
312
+ ev.shiftKey || // new window
313
+ ev.defaultPrevented ||
314
+ !transitionEnabledOnThisPage()
315
+ )
316
+ // No page transitions in these cases,
317
+ // Let the browser standard action handle this
318
+ return;
319
+
320
+ // We do not need to handle same page links because there are no page transitions
321
+ // Same page means same path and same query params (but different hash)
322
+ if (location.pathname === link.pathname && location.search === link.search) {
323
+ if (link.hash) {
324
+ // The browser default action will handle navigations with hash fragments
325
+ return;
326
+ } else {
327
+ // Special case: self link without hash
328
+ // If handed to the browser it will reload the page
329
+ // But we want to handle it like any other same page navigation
330
+ // So we scroll to the top of the page but do not start page transitions
331
+ ev.preventDefault();
332
+ persistState({ ...history.state, scrollY });
333
+ // @ts-ignore
334
+ scrollTo({ left: 0, top: 0, behavior: 'instant' });
335
+ if (location.hash) {
336
+ // last target was different
337
+ const newState: State = { index: ++currentHistoryIndex, scrollY: 0 };
338
+ history.pushState(newState, '', link.href);
339
+ }
340
+ return;
341
+ }
342
+ }
343
+
344
+ // these are the cases we will handle: same origin, different page
345
+ ev.preventDefault();
346
+ navigate('forward', link.href, { index: ++currentHistoryIndex, scrollY: 0 });
347
+ const newState: State = { index: currentHistoryIndex, scrollY };
348
+ persistState({ index: currentHistoryIndex - 1, scrollY });
349
+ history.pushState(newState, '', link.href);
350
+ });
351
+
352
+ addEventListener('popstate', (ev) => {
353
+ if (!transitionEnabledOnThisPage() && ev.state) {
354
+ // The current page doesn't haven't View Transitions,
355
+ // respect that with a full page reload
356
+ // -- but only for transition managed by us (ev.state is set)
357
+ location.reload();
358
+ return;
359
+ }
360
+
361
+ // History entries without state are created by the browser (e.g. for hash links)
362
+ // Our view transition entries always have state.
363
+ // Just ignore stateless entries.
364
+ // The browser will handle navigation fine without our help
365
+ if (ev.state === null) {
366
+ return;
367
+ }
368
+
369
+ const state: State | undefined = history.state;
370
+ const nextIndex = state?.index ?? currentHistoryIndex + 1;
371
+ const direction: Direction = nextIndex > currentHistoryIndex ? 'forward' : 'back';
372
+ navigate(direction, location.href, state);
373
+ currentHistoryIndex = nextIndex;
374
+ });
375
+
376
+ ['mouseenter', 'touchstart', 'focus'].forEach((evName) => {
377
+ document.addEventListener(
378
+ evName,
379
+ (ev) => {
380
+ if (ev.target instanceof HTMLAnchorElement) {
381
+ let el = ev.target;
382
+ if (
383
+ el.origin === location.origin &&
384
+ el.pathname !== location.pathname &&
385
+ transitionEnabledOnThisPage()
386
+ ) {
387
+ maybePrefetch(el.pathname);
388
+ }
389
+ }
390
+ },
391
+ { passive: true, capture: true }
392
+ );
393
+ });
394
+ addEventListener('load', onload);
395
+ // There's not a good way to record scroll position before a back button.
396
+ // So the way we do it is by listening to scroll and just continuously recording it.
397
+ addEventListener(
398
+ 'scroll',
399
+ throttle(() => {
400
+ // only updste history entries that are managed by us
401
+ // leave other entries alone and do not accidently add state.
402
+ if (history.state) {
403
+ persistState({ ...history.state, scrollY });
404
+ }
405
+ }, 300),
406
+ { passive: true }
407
+ );
408
+ }
409
+ </script>
@@ -23,6 +23,7 @@ export interface Props {
23
23
  loading?: 'lazy' | 'eager';
24
24
  decoding?: 'async' | 'sync' | 'auto';
25
25
  alt?: string;
26
+ preferredSize?: string;
26
27
  }
27
28
 
28
29
  const props = withDefaults(defineProps<Props>(), {
@@ -32,7 +33,7 @@ const image = computed<Partial<PictureSize>>(() => {
32
33
  if ((props.picture as PictureSize).url) {
33
34
  return props.picture as PictureSize;
34
35
  }
35
- return getImg(props.picture) || {};
36
+ return getImg(props.picture, undefined, props.preferredSize) || {};
36
37
  });
37
38
  const dimensions = computed(() => {
38
39
  return getImgSizes(image.value) as { width: number, height: number };
@@ -13,8 +13,8 @@ export interface Props {
13
13
 
14
14
  const parseLayoutContent = (layoutContent: LayoutContent) => {
15
15
  const pitchBar: Props = { slides: [] };
16
- if (layoutContent.header?.pitch_bar) {
17
- pitchBar.slides = layoutContent.header.pitch_bar;
16
+ if (layoutContent.header?.pitchBar) {
17
+ pitchBar.slides = layoutContent.header.pitchBar;
18
18
  }
19
19
  return pitchBar;
20
20
  };
@@ -18,16 +18,16 @@ export interface PageContent {
18
18
  autoplay?: number,
19
19
  slides: Array<{
20
20
  [k: string]: unknown,
21
- start?: string,
22
- end?: string,
21
+ startsAt?: string,
22
+ endsAt?: string,
23
23
  img: string,
24
24
  alt?: string,
25
- mobile_img?: string,
25
+ mobileImg?: string,
26
26
  href?: string,
27
27
  title?: string,
28
28
  subtitle?: string
29
- button_link?: string,
30
- button_text?: string,
29
+ buttonLink?: string,
30
+ buttonText?: string,
31
31
  }>,
32
32
  };
33
33
  sections: Array<Record<string, any> & {
@@ -3,13 +3,13 @@ import { Head } from 'astro-capo';
3
3
  import BaseBody from '@@sf/layouts/BaseBody.astro';
4
4
 
5
5
  const { getContent } = Astro.locals.routeContext;
6
- const { custom_code: customCodeContent } = await getContent('layout');
6
+ const { customCode } = await getContent('layout');
7
7
  ---
8
8
 
9
9
  <Head>
10
10
  <slot name="base-head" />
11
- {customCodeContent?.css && <style>{customCodeContent.css}</style>}
12
- {customCodeContent?.html_head && <Fragment set:html={customCodeContent.html_head} />}
11
+ {customCode?.css && <style>{customCode.css}</style>}
12
+ {customCode?.htmlHead && <Fragment set:html={customCode.htmlHead} />}
13
13
  <slot name="base-head-scripts">
14
14
  <script src="../scripts/modules-info-preset"></script>
15
15
  </slot>
@@ -17,7 +17,7 @@ const { custom_code: customCodeContent } = await getContent('layout');
17
17
  </Head>
18
18
  <BaseBody>
19
19
  <slot />
20
- {customCodeContent?.html_body && <Fragment set:html={customCodeContent.html_body} />}
20
+ {customCode?.htmlBody && <Fragment set:html={customCode.htmlBody} />}
21
21
  <slot name="base-body-scripts">
22
22
  <script src="../scripts/session-utm"></script>
23
23
  </slot>
@@ -8,11 +8,9 @@ import '@@sf/assets/tooltip.css';
8
8
  import Picture from '@@sf/components/Picture.astro';
9
9
 
10
10
  const { settings } = Astro.locals.routeContext;
11
- const { contextInlineClientJS } = Astro.locals;
12
11
  ---
13
12
 
14
13
  <body style="visibility:hidden" class="!visible"> <!-- Prevent FOUC -->
15
- {contextInlineClientJS && <script is:inline set:html={contextInlineClientJS} />}
16
14
  <div id="teleported-overlap" class="relative z-[59]"></div>
17
15
  <div id="teleported-top" class="relative z-[19]"></div>
18
16
  <slot />
@@ -1,8 +1,13 @@
1
1
  ---
2
2
  import { pwaInfo } from 'virtual:pwa-info';
3
- import { ViewTransitions } from 'astro:transitions';
4
3
  import { img as getImg, price as getPrice } from '@ecomplus/utils';
4
+ import ViewTransitions from '@@sf/components/ViewTransitions.astro';
5
5
 
6
+ export interface Props {
7
+ hasViewTransitions?: boolean;
8
+ }
9
+
10
+ const hasViewTransitions = Astro.props.hasViewTransitions !== false;
6
11
  const deployRand = import.meta.env.DEPLOY_RAND || '_';
7
12
  const getIconUrl = (size: number) => {
8
13
  return `/_image?f=png&w=${size}&h=${size}`
@@ -43,15 +48,20 @@ if (apiDoc) {
43
48
  ogImage = picture && picture.url;
44
49
  }
45
50
  if (!ogImage) {
46
- if (metatagsContent?.og_image) {
47
- ogImage = metatagsContent.og_image.charAt(0) === '/'
48
- ? `https://${domain}${metatagsContent.og_image}` : metatagsContent.og_image;
51
+ if (metatagsContent?.ogImage) {
52
+ ogImage = metatagsContent.ogImage.charAt(0) === '/'
53
+ ? `https://${domain}${metatagsContent.ogImage}` : metatagsContent.ogImage;
49
54
  }
50
55
  } else {
51
56
  ogImage = ogImage.replace(/(\w+\.)?(ecoms\d)\.com/i, '$2-nyc3.nyc3.cdn.digitaloceanspaces.com');
52
57
  }
53
58
 
54
59
  let inlineClientJS = `
60
+ window._emitApiContext = (id = null) => {
61
+ console.log('[ctx] emit ' + id);
62
+ window.dispatchEvent(new Event('storefront:apiContext'));
63
+ window._emitedContextId = id;
64
+ };
55
65
  window.ECOM_STORE_ID = ${storeId};
56
66
  window.ECOM_LANG = '${lang}';
57
67
  window.ECOM_CURRENCY = '${currency}';
@@ -67,6 +77,7 @@ setTimeout(() => {
67
77
  window.location.replace("/~fallback?status=${statusCode}&url=${encodeURIComponent(url)}");
68
78
  }, 1);`;
69
79
  }
80
+ let contextInlineClientJS: string | undefined;
70
81
  if (apiDoc) {
71
82
  if (typeof apiDoc.price === 'number') {
72
83
  apiDoc.price = getPrice(apiDoc);
@@ -89,18 +100,24 @@ if (apiDoc) {
89
100
  }
90
101
  return nestedDoc;
91
102
  };
92
- Astro.locals.contextInlineClientJS = `
103
+ inlineClientJS += `
104
+ window._firstLoadContextId = '${apiDoc._id}';`;
105
+ contextInlineClientJS = `
93
106
  $storefront.apiContext = ${JSON.stringify({
94
107
  resource: apiContext.resource,
95
108
  doc: minifyApiDoc({ ...apiDoc }),
96
109
  timestamp: Date.now(),
97
110
  })};
98
- $storefront.context /* DEPRECATED */ = $storefront.apiContext`;
111
+ $storefront.context /* DEPRECATED */ = $storefront.apiContext;
112
+ _emitApiContext('${apiDoc._id}');`;
99
113
  } else {
100
- Astro.locals.contextInlineClientJS = `
114
+ inlineClientJS += `
115
+ window._firstLoadContextId = null;`;
116
+ contextInlineClientJS = `
101
117
  $storefront.apiContext = null;
102
118
  delete $storefront.apiContext;
103
- delete $storefront.context;`;
119
+ delete $storefront.context;
120
+ _emitApiContext();`;
104
121
  }
105
122
  if (isPreview) {
106
123
  inlineClientJS += `
@@ -137,11 +154,11 @@ const inlineJSONLd = JSON.stringify({
137
154
  <meta property="og:type" content="website">
138
155
  <meta property="og:locale" content={ogLocale}>
139
156
  {ogImage && <meta property="og:image" content={ogImage} />}
140
- {metatagsContent?.fb_app_id &&
141
- <meta property="fb:app_id" content={metatagsContent.fb_app_id} />}
157
+ {metatagsContent?.fbAppId &&
158
+ <meta property="fb:app_id" content={metatagsContent.fbAppId} />}
142
159
  <meta name="twitter:card" content="summary">
143
- {metatagsContent?.twitter_username &&
144
- <meta name="twitter:site" content={metatagsContent.twitter_username} />}
160
+ {metatagsContent?.twitterUsername &&
161
+ <meta name="twitter:site" content={metatagsContent.twitterUsername} />}
145
162
  <meta name="ecom-store-id" content={String(storeId)}>
146
163
 
147
164
  <script>
@@ -152,7 +169,8 @@ const inlineJSONLd = JSON.stringify({
152
169
  {(!pwaInfo && !import.meta.env.DEV) &&
153
170
  <link rel="manifest" href="/manifest.webmanifest" />}
154
171
 
155
- <script is:inline set:html={inlineClientJS} />
172
+ <script is:inline set:html={inlineClientJS} transition:persist />
156
173
  <script type="application/ld+json" set:html={inlineJSONLd} />
157
174
 
158
- <ViewTransitions />
175
+ {hasViewTransitions && <ViewTransitions fallback="none" />}
176
+ {contextInlineClientJS && <script is:inline set:html={contextInlineClientJS} />}
@@ -13,7 +13,12 @@ export interface Props {
13
13
  const usePageHeader = async ({ routeContext, listedCategoryFields }: Props) => {
14
14
  const { apiState, getContent } = routeContext;
15
15
  const layoutContent = await getContent('layout');
16
- const { header: headerContent } = layoutContent;
16
+ const {
17
+ header: {
18
+ inlineMenuCategories,
19
+ isAlphabeticalSortSubmenu,
20
+ },
21
+ } = layoutContent;
17
22
  const pitchBar = parseLayoutContent(layoutContent);
18
23
  let { categories } = apiState;
19
24
  if (!categories && listedCategoryFields !== null) {
@@ -36,9 +41,9 @@ const usePageHeader = async ({ routeContext, listedCategoryFields }: Props) => {
36
41
  }
37
42
  const shopHeader: ShopHeaderProps = {
38
43
  categories,
39
- menuCategorySlugs: headerContent.inline_menu_categories?.featured,
40
- menuRandomCategories: headerContent.inline_menu_categories?.random,
41
- isAlphabeticalSortSubmenu: headerContent.alphabetical_sort_submenu,
44
+ menuCategorySlugs: inlineMenuCategories?.featured,
45
+ menuRandomCategories: inlineMenuCategories?.random,
46
+ isAlphabeticalSortSubmenu,
42
47
  };
43
48
  /*
44
49
  if (import.meta.env.DEV) {