cloudcommerce 0.2.1 → 0.2.2

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 (124) hide show
  1. package/.eslintrc.cjs +1 -93
  2. package/CHANGELOG.md +23 -0
  3. package/ecomplus-stores/monocard/functions/ssr/package.json +2 -1
  4. package/ecomplus-stores/tia-sonia/functions/ssr/package.json +2 -1
  5. package/package.json +6 -6
  6. package/packages/api/package.json +1 -1
  7. package/packages/apps/correios/package.json +2 -2
  8. package/packages/apps/custom-payment/package.json +1 -1
  9. package/packages/apps/custom-shipping/package.json +1 -1
  10. package/packages/apps/datafrete/package.json +4 -4
  11. package/packages/apps/discounts/package.json +1 -1
  12. package/packages/apps/emails/package.json +2 -2
  13. package/packages/apps/fb-conversions/package.json +4 -4
  14. package/packages/apps/frenet/package.json +4 -4
  15. package/packages/apps/galaxpay/lib/galaxpay-list-payments.d.ts +2 -2
  16. package/packages/apps/galaxpay/lib/galaxpay.d.ts +2 -2
  17. package/packages/apps/galaxpay/package.json +4 -4
  18. package/packages/apps/google-analytics/package.json +4 -4
  19. package/packages/apps/infinitepay/package.json +4 -4
  20. package/packages/apps/jadlog/package.json +2 -2
  21. package/packages/apps/loyalty-points/package.json +1 -1
  22. package/packages/apps/mercadopago/package.json +4 -4
  23. package/packages/apps/pagarme/package.json +4 -4
  24. package/packages/apps/paghiper/CHANGELOG.md +1 -0
  25. package/packages/apps/paghiper/README.md +1 -0
  26. package/packages/apps/paghiper/lib/functions-lib/create-axios.d.ts +2 -0
  27. package/packages/apps/paghiper/lib/functions-lib/create-axios.js +22 -0
  28. package/packages/apps/paghiper/lib/functions-lib/create-axios.js.map +1 -0
  29. package/packages/apps/paghiper/lib/functions-lib/handle-webhook.d.ts +3 -0
  30. package/packages/apps/paghiper/lib/functions-lib/handle-webhook.js +154 -0
  31. package/packages/apps/paghiper/lib/functions-lib/handle-webhook.js.map +1 -0
  32. package/packages/apps/paghiper/lib/index.d.ts +1 -0
  33. package/packages/apps/paghiper/lib/index.js +2 -0
  34. package/packages/apps/paghiper/lib/index.js.map +1 -0
  35. package/packages/apps/paghiper/lib/paghiper-create-transaction.d.ts +71 -0
  36. package/packages/apps/paghiper/lib/paghiper-create-transaction.js +199 -0
  37. package/packages/apps/paghiper/lib/paghiper-create-transaction.js.map +1 -0
  38. package/packages/apps/paghiper/lib/paghiper-list-payments.d.ts +7 -0
  39. package/packages/apps/paghiper/lib/paghiper-list-payments.js +97 -0
  40. package/packages/apps/paghiper/lib/paghiper-list-payments.js.map +1 -0
  41. package/packages/apps/paghiper/lib/paghiper-webhook.d.ts +5 -0
  42. package/packages/apps/paghiper/lib/paghiper-webhook.js +18 -0
  43. package/packages/apps/paghiper/lib/paghiper-webhook.js.map +1 -0
  44. package/packages/apps/paghiper/lib/paghiper.d.ts +76 -0
  45. package/packages/apps/paghiper/lib/paghiper.js +12 -0
  46. package/packages/apps/paghiper/lib/paghiper.js.map +1 -0
  47. package/packages/apps/paghiper/package.json +36 -0
  48. package/packages/apps/paghiper/src/functions-lib/create-axios.ts +21 -0
  49. package/packages/apps/paghiper/src/functions-lib/handle-webhook.ts +176 -0
  50. package/packages/apps/paghiper/src/index.ts +1 -0
  51. package/packages/apps/paghiper/src/paghiper-create-transaction.ts +242 -0
  52. package/packages/apps/paghiper/src/paghiper-list-payments.ts +127 -0
  53. package/packages/apps/paghiper/src/paghiper-webhook.ts +17 -0
  54. package/packages/apps/paghiper/src/paghiper.ts +12 -0
  55. package/packages/apps/paghiper/tsconfig.json +6 -0
  56. package/packages/apps/paghiper/types/config-app.d.ts +34 -0
  57. package/packages/apps/paghiper/webhook.js +1 -0
  58. package/packages/apps/pix/package.json +4 -4
  59. package/packages/apps/tiny-erp/lib/integration/post-tiny-erp.js.map +1 -1
  60. package/packages/apps/tiny-erp/package.json +4 -4
  61. package/packages/apps/tiny-erp/src/integration/post-tiny-erp.ts +1 -1
  62. package/packages/cli/package.json +1 -1
  63. package/packages/config/package.json +1 -1
  64. package/packages/emails/package.json +2 -2
  65. package/packages/events/lib/firebase.js +2 -0
  66. package/packages/events/lib/firebase.js.map +1 -1
  67. package/packages/events/package.json +4 -3
  68. package/packages/events/src/firebase.ts +2 -0
  69. package/packages/firebase/lib/config.d.ts +3 -0
  70. package/packages/firebase/lib/config.js +3 -0
  71. package/packages/firebase/lib/config.js.map +1 -1
  72. package/packages/firebase/package.json +3 -3
  73. package/packages/firebase/src/config.ts +3 -0
  74. package/packages/i18n/package.json +1 -1
  75. package/packages/modules/lib/firebase/call-app-module.js +12 -0
  76. package/packages/modules/lib/firebase/call-app-module.js.map +1 -1
  77. package/packages/modules/package.json +6 -5
  78. package/packages/modules/src/firebase/call-app-module.ts +12 -0
  79. package/packages/passport/package.json +3 -3
  80. package/packages/ssr/package.json +4 -4
  81. package/packages/storefront/.base.eslintrc.cjs +93 -0
  82. package/packages/storefront/.eslintrc.cjs +1 -1
  83. package/packages/storefront/astro.config.mjs +2 -0
  84. package/packages/storefront/client.d.ts +1 -1
  85. package/packages/storefront/config/storefront.cms.mjs +2 -2
  86. package/packages/storefront/dist/client/PitchBar.5ae15bda.js +1 -0
  87. package/packages/storefront/dist/client/Prices.248d1aae.js +1 -0
  88. package/packages/storefront/dist/client/ProductCard.4848304c.js +1 -0
  89. package/packages/storefront/dist/client/assets/{_...slug_.fea84512.css → _...slug_.b701cbb1.css} +1 -1
  90. package/packages/storefront/dist/client/chunks/Prices.vue_vue_type_script_setup_true_lang.2d01aaa2.js +1 -0
  91. package/packages/storefront/dist/client/chunks/ecom-utils.cd6787a7.js +1 -0
  92. package/packages/storefront/dist/client/chunks/modules-info.fcab5bba.js +1 -0
  93. package/packages/storefront/dist/client/chunks/runtime-dom.esm-bundler.923790dc.js +1 -0
  94. package/packages/storefront/dist/client/chunks/session-utm.ceebe967.js +1 -0
  95. package/packages/storefront/dist/client/client.2356f675.js +1 -0
  96. package/packages/storefront/dist/client/{hoisted.4671ed15.js → hoisted.11b849a7.js} +1 -1
  97. package/packages/storefront/dist/client/sw.js +1 -1
  98. package/packages/storefront/dist/server/entry.mjs +432 -92
  99. package/packages/storefront/package.json +3 -3
  100. package/packages/storefront/src/lib/components/Carousel.vue +1 -0
  101. package/packages/storefront/src/lib/components/CarouselControl.vue +1 -1
  102. package/packages/storefront/src/lib/components/PitchBar.vue +27 -10
  103. package/packages/storefront/src/lib/components/StickyHeader.vue +43 -0
  104. package/packages/storefront/src/lib/layouts/Base.astro +6 -0
  105. package/packages/storefront/src/lib/layouts/BaseBody.astro +0 -1
  106. package/packages/storefront/src/lib/layouts/PagesHeader.astro +24 -3
  107. package/packages/storefront/src/lib/scripts/modules-info-preset.ts +60 -0
  108. package/packages/storefront/src/lib/ssr/Picture.astro +13 -0
  109. package/packages/storefront/src/lib/ssr/image.ts +12 -2
  110. package/packages/storefront/src/lib/ssr-context.ts +18 -4
  111. package/packages/storefront/src/lib/state/modules-info.ts +44 -14
  112. package/packages/storefront/src/lib/types/cms-settings.d.ts +2 -1
  113. package/packages/storefront/storefront.config.mjs +20 -8
  114. package/packages/storefront/tailwind.config.cjs +1 -1
  115. package/packages/types/index.ts +17 -0
  116. package/packages/types/package.json +1 -1
  117. package/packages/storefront/dist/client/PitchBar.afe7ff5c.js +0 -1
  118. package/packages/storefront/dist/client/Prices.eaf8a32c.js +0 -1
  119. package/packages/storefront/dist/client/ProductCard.1106b153.js +0 -1
  120. package/packages/storefront/dist/client/chunks/Prices.vue_vue_type_script_setup_true_lang.781b6501.js +0 -1
  121. package/packages/storefront/dist/client/chunks/ecom-utils.63984324.js +0 -1
  122. package/packages/storefront/dist/client/chunks/runtime-core.esm-bundler.fa6cdb60.js +0 -1
  123. package/packages/storefront/dist/client/chunks/session-utm.2de8b604.js +0 -1
  124. package/packages/storefront/dist/client/client.367a6497.js +0 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/storefront",
3
3
  "type": "module",
4
- "version": "0.2.1",
4
+ "version": "0.2.2",
5
5
  "description": "E-Com Plus Cloud Commerce storefront with Astro",
6
6
  "main": "src/index.js",
7
7
  "repository": {
@@ -40,11 +40,11 @@
40
40
  "@iconify-json/heroicons": "^1.1.8",
41
41
  "@iconify-json/logos": "^1.1.22",
42
42
  "@vite-pwa/astro": "^0.0.1",
43
- "@vueuse/core": "^9.10.0",
43
+ "@vueuse/core": "^9.11.1",
44
44
  "astro": "^1.9.2",
45
45
  "chroma-js": "^2.4.2",
46
46
  "dotenv": "^16.0.3",
47
- "firebase": "^9.15.0",
47
+ "firebase": "^9.16.0",
48
48
  "image-size": "^1.0.2",
49
49
  "lodash": "^4.17.21",
50
50
  "semver": "^7.3.8",
@@ -249,6 +249,7 @@ provide(carouselKey, {
249
249
  position: absolute;
250
250
  top: 0;
251
251
  bottom: 0;
252
+ z-index: 1;
252
253
  }
253
254
  [data-carousel-control=previous] {
254
255
  left: 0;
@@ -21,7 +21,7 @@ const { changeSlide } = inject(carouselKey);
21
21
  >
22
22
  <slot>
23
23
  <i
24
- class="mb-0 z-10"
24
+ class="m-0"
25
25
  :class="direction > 0 ? 'i-chevron-right' : 'i-chevron-left'"
26
26
  ></i>
27
27
  </slot>
@@ -1,4 +1,6 @@
1
1
  <script setup lang="ts">
2
+ import { computed } from 'vue';
3
+ import { parseShippingPhrase } from '@@sf/state/modules-info';
2
4
  import Carousel from '@@sf/components/Carousel.vue';
3
5
  import CarouselControl from '@@sf/components/CarouselControl.vue';
4
6
 
@@ -10,27 +12,42 @@ export interface Props {
10
12
  }>;
11
13
  }
12
14
 
13
- defineProps<Props>();
15
+ const props = defineProps<Props>();
16
+ const parsedContents = computed(() => {
17
+ return props.slides.map(({ html }) => {
18
+ return parseShippingPhrase(html).value;
19
+ });
20
+ });
21
+ const countValidSlides = computed(() => {
22
+ return parsedContents.value.filter((html) => html).length;
23
+ });
14
24
  </script>
15
25
 
16
26
  <template>
17
27
  <div data-pitch-bar class="bg-base-100">
18
28
  <div class="container md:w-2/3 mx-auto px-3 py-1">
19
- <Carousel :autoplay="7000">
20
- <li v-for="({ href, target, html }, i) in slides" :key="i">
29
+ <Carousel :autoplay="countValidSlides > 1 ? 7000 : null">
30
+ <li v-for="(slide, i) in slides" :key="i">
21
31
  <component
22
- :is="href ? 'ALink' : 'span'"
23
- :href="href"
24
- :target="target"
25
- :class="href ? 'hover:underline' : null"
32
+ :is="slide.href ? 'ALink' : 'span'"
33
+ :href="slide.href"
34
+ :target="slide.target"
35
+ :class="slide.href ? 'hover:underline' : null"
26
36
  >
27
- <slot name="slide">
28
- <span v-html="html" class="prose text-sm text-base-800"></span>
37
+ <slot name="slide" v-bind="{ slide, i, parsedContents }">
38
+ <span
39
+ v-if="parsedContents[i]"
40
+ v-html="parsedContents[i]"
41
+ class="prose text-sm text-base-800"
42
+ ></span>
29
43
  </slot>
30
44
  </component>
31
45
  </li>
32
46
  <template #controls>
33
- <div class="text-xl leading-none text-base-400">
47
+ <div
48
+ v-show="countValidSlides > 1"
49
+ class="text-xl leading-none text-base-400"
50
+ >
34
51
  <CarouselControl
35
52
  :direction="-1"
36
53
  class="pr-2 bg-base-100 hover:text-base-700"
@@ -0,0 +1,43 @@
1
+ <script setup lang="ts">
2
+ import type { ImgHTMLAttributes } from 'vue';
3
+ import { toRefs } from 'vue';
4
+
5
+ export interface Props {
6
+ logo?: ImgHTMLAttributes;
7
+ logoAltHeading?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | null;
8
+ }
9
+
10
+ const props = withDefaults(defineProps<Props>(), {
11
+ logoAltHeading: 'h2',
12
+ });
13
+ const { logo } = toRefs(props);
14
+ </script>
15
+
16
+ <template>
17
+ <header class="header bg-opacity-90 backdrop-blur-md
18
+ sticky top-0 z-50 py-1 sm:py-2" data-sticky-header>
19
+ <div class="container">
20
+ <div class="grid grid-flow-col auto-cols-max justify-between items-center">
21
+ <slot name="aside">
22
+ <div class="header__aside md:hidden">
23
+ <div class="i-bars-3-bottom-left"></div>
24
+ </div>
25
+ </slot>
26
+ <slot name="logo" v-bind="{ logo }">
27
+ <a v-if="logo" href="/">
28
+ <component :is="(logo.alt && logoAltHeading) || 'span'" class="m-0">
29
+ <img v-bind="logo" />
30
+ </component>
31
+ </a>
32
+ </slot>
33
+ <div class="flex items-center">
34
+ <slot name="actions">
35
+ <slot name="nav" />
36
+ <slot name="search" />
37
+ <slot name="buttons" />
38
+ </slot>
39
+ </div>
40
+ </div>
41
+ </div>
42
+ </header>
43
+ </template>
@@ -20,10 +20,16 @@ const cmsCustomCode = cms('code') as CmsCode;
20
20
  <BaseStateJson pageContext={pageContext} />
21
21
  {cmsCustomCode.css && <style>{cmsCustomCode.css}</style>}
22
22
  {cmsCustomCode.html_head && <Fragment set:html={cmsCustomCode.html_head} />}
23
+ <slot name="base-head-scripts">
24
+ <script src="../scripts/modules-info-preset"></script>
25
+ </slot>
23
26
  <slot name="before-head-end" />
24
27
  </head>
25
28
  <BaseBody pageContext={pageContext}>
26
29
  <slot />
27
30
  {cmsCustomCode.html_body && <Fragment set:html={cmsCustomCode.html_body} />}
31
+ <slot name="base-body-scripts">
32
+ <script src="../scripts/session-utm"></script>
33
+ </slot>
28
34
  <slot name="before-body-end" />
29
35
  </BaseBody>
@@ -13,6 +13,5 @@ export interface Props {
13
13
 
14
14
  <body>
15
15
  <slot />
16
- <script src="../scripts/session-utm"></script>
17
16
  <slot name="before-body-end" />
18
17
  </body>
@@ -3,23 +3,25 @@ import type { Categories } from '@cloudcommerce/api/types';
3
3
  import type CmsHeader from '@@sf/types/cms-header';
4
4
  import type CmsContacts from '@@sf/types/cms-contacts';
5
5
  import type { PageContext } from '@@sf/ssr-context';
6
- import { i19buyOnWhatsApp } from '@@i18n';
7
- import { getImage } from '@@sf/ssr/image';
6
+ import Picture from '@@sf/ssr/Picture.astro';
8
7
  import PitchBar, { Props as PitchBarProps } from '@@sf/components/PitchBar.vue';
8
+ import StickyHeader from '@@sf/components/StickyHeader.vue';
9
9
 
10
10
  export interface Props {
11
11
  pageContext: PageContext;
12
+ logoHeading?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | null;
12
13
  }
13
14
 
14
15
  const {
15
16
  pageContext: {
17
+ isHomepage,
16
18
  apiState,
17
19
  settings,
18
20
  cms,
19
21
  },
20
22
  } = Astro.props as Props;
21
23
  const header = cms('header') as CmsHeader &
22
- { marketing_stripe?: { text: string, link: string } };
24
+ { marketing_stripe?: { text: string, link: string }, logo?: string };
23
25
  const pitchBar: PitchBarProps = { slides: [] };
24
26
  if (header.pitch_bar) {
25
27
  pitchBar.slides = header.pitch_bar;
@@ -29,10 +31,29 @@ if (header.pitch_bar) {
29
31
  html: header.marketing_stripe.text,
30
32
  }];
31
33
  }
34
+ const logoSrc = header.logo || settings.logo;
35
+ const LogoHeading = Astro.props.logoHeading || (isHomepage ? 'h1' : 'h2');
32
36
  ---
33
37
 
34
38
  <Fragment>
35
39
  <slot name="pitch-bar">
36
40
  {pitchBar.slides.length && <PitchBar {...pitchBar} client:idle />}
37
41
  </slot>
42
+ <slot name="sticky-header">
43
+ <StickyHeader>
44
+ <Fragment slot="logo">
45
+ <slot name="logo">
46
+ <LogoHeading>
47
+ <Picture
48
+ src={logoSrc}
49
+ alt={settings.name}
50
+ widths={[300]}
51
+ sizes="150px"
52
+ fetchpriority="high"
53
+ />
54
+ </LogoHeading>
55
+ </slot>
56
+ </Fragment>
57
+ </StickyHeader>
58
+ </slot>
38
59
  </Fragment>
@@ -0,0 +1,60 @@
1
+ type ModulesInfoPreset = typeof window.storefront.modulesInfoPreset;
2
+
3
+ const checkObjNotNull = (obj: { [k: string]: any }) => {
4
+ return Object.values(obj).filter((val) => val).length;
5
+ };
6
+
7
+ const getModulesInfoPreset = (settingsModules = globalThis.storefront.settings.modules) => {
8
+ const modulesInfoPreset: ModulesInfoPreset = {};
9
+ if (settingsModules) {
10
+ const settingsPayments = settingsModules.list_payments;
11
+ if (settingsPayments) {
12
+ const settingsDiscount = settingsPayments.discount_option;
13
+ if (settingsDiscount && checkObjNotNull(settingsDiscount)) {
14
+ modulesInfoPreset.list_payments = { discount_option: settingsDiscount };
15
+ }
16
+
17
+ const settingsInstallments = settingsPayments.installments_option;
18
+ if (settingsInstallments?.max_number) {
19
+ if (!modulesInfoPreset.list_payments) modulesInfoPreset.list_payments = {};
20
+ modulesInfoPreset.list_payments.installments_option = settingsInstallments as
21
+ { max_number: number };
22
+ }
23
+
24
+ const settingsPointsPrograms = settingsPayments.loyalty_points_programs || {};
25
+ if (!Object.keys(settingsPointsPrograms).length) {
26
+ const pointsProgram = { ...settingsPayments.loyalty_points_program };
27
+ if (pointsProgram?.id && pointsProgram.ratio) {
28
+ const { id } = pointsProgram;
29
+ delete pointsProgram.id;
30
+ settingsPointsPrograms[id] = pointsProgram as { ratio: number };
31
+ }
32
+ }
33
+ if (Object.keys(settingsPointsPrograms).length) {
34
+ if (!modulesInfoPreset.list_payments) modulesInfoPreset.list_payments = {};
35
+ modulesInfoPreset.list_payments.loyalty_points_programs = settingsPointsPrograms;
36
+ }
37
+ }
38
+
39
+ const settingsShipping = settingsModules.calculate_shipping;
40
+ if (settingsShipping && settingsShipping.free_shipping_from_value) {
41
+ modulesInfoPreset.calculate_shipping = settingsShipping;
42
+ }
43
+ }
44
+ return modulesInfoPreset;
45
+ };
46
+
47
+ const loadingGlobalInfoPreset: Promise<ModulesInfoPreset> = new Promise((resolve) => {
48
+ if (import.meta.env.SSR) {
49
+ global.storefront.onLoad(() => {
50
+ resolve(getModulesInfoPreset());
51
+ });
52
+ } else {
53
+ window.storefront.modulesInfoPreset = getModulesInfoPreset();
54
+ resolve(window.storefront.modulesInfoPreset);
55
+ }
56
+ });
57
+
58
+ export default loadingGlobalInfoPreset;
59
+
60
+ export { getModulesInfoPreset, loadingGlobalInfoPreset };
@@ -0,0 +1,13 @@
1
+ ---
2
+ import { Picture } from '@astrojs/image/components';
3
+ import { getAspectRatio } from '@@sf/ssr/image';
4
+
5
+ export type Props = Parameters<typeof Picture>[0];
6
+
7
+ const props = Astro.props as Props;
8
+ if (!props.aspectRatio && typeof props.src === 'string') {
9
+ props.aspectRatio = getAspectRatio(props.src);
10
+ }
11
+ ---
12
+
13
+ <Picture {...props} />
@@ -15,6 +15,16 @@ const tryImageSize = (src: string) => {
15
15
  return dimensions;
16
16
  };
17
17
 
18
+ const getAspectRatio = (src: string | { width?: number, height?: number }) => {
19
+ if (typeof src === 'string') {
20
+ src = tryImageSize(src);
21
+ }
22
+ if (src.width) {
23
+ return src.height ? src.width / src.height : 1;
24
+ }
25
+ return 0;
26
+ };
27
+
18
28
  type TransformOptions = Omit<Parameters<typeof _getImage>[0], 'alt'> & {
19
29
  isLowResolution?: boolean,
20
30
  alt?: string,
@@ -38,7 +48,7 @@ const getImage = async (options: TransformOptions) => {
38
48
  if (!options.width) {
39
49
  options.width = width;
40
50
  }
41
- options.aspectRatio = height ? width / height : 1;
51
+ options.aspectRatio = getAspectRatio({ width, height });
42
52
  }
43
53
  }
44
54
  const imgAttrs = await _getImage({ alt: '', ...options });
@@ -55,4 +65,4 @@ const getImage = async (options: TransformOptions) => {
55
65
 
56
66
  export default getImage;
57
67
 
58
- export { tryImageSize, getImage };
68
+ export { tryImageSize, getAspectRatio, getImage };
@@ -2,6 +2,7 @@ import type { AstroGlobal } from 'astro';
2
2
  import type { BaseConfig } from '@cloudcommerce/config';
3
3
  import type { CategoriesList, BrandsList } from '@cloudcommerce/api/types';
4
4
  import type CmsSettings from './types/cms-settings';
5
+ import { EventEmitter } from 'node:events';
5
6
  import api, { ApiError, ApiEndpoint } from '@cloudcommerce/api';
6
7
  import _getConfig from '../../storefront.config.mjs';
7
8
 
@@ -21,19 +22,28 @@ type StorefrontConfig = {
21
22
  ? Array<string> : Record<string, any>,
22
23
  };
23
24
 
25
+ const emitter = new EventEmitter();
24
26
  const getConfig: () => StorefrontConfig = _getConfig;
25
27
 
26
28
  declare global {
27
29
  // eslint-disable-next-line
28
30
  var api_prefetch_endpoints: ApiEndpoint[];
29
31
  // eslint-disable-next-line
30
- var storefront: { settings: Partial<CmsSettings> };
32
+ var storefront: {
33
+ settings: Partial<CmsSettings>,
34
+ onLoad: (callback: (...args: any[]) => void) => void,
35
+ };
31
36
  }
32
37
  if (!globalThis.api_prefetch_endpoints) {
33
38
  globalThis.api_prefetch_endpoints = ['categories'];
34
39
  }
35
40
  if (!globalThis.storefront) {
36
- globalThis.storefront = { settings: {} };
41
+ globalThis.storefront = {
42
+ settings: {},
43
+ onLoad(callback: (...args: any[]) => void) {
44
+ emitter.on('load', callback);
45
+ },
46
+ };
37
47
  }
38
48
 
39
49
  type ApiPrefetchEndpoints = Array<ApiEndpoint>;
@@ -56,6 +66,7 @@ const loadPageContext = async (Astro: AstroGlobal, {
56
66
  } = {}) => {
57
67
  const startedAt = Date.now();
58
68
  const urlPath = Astro.url.pathname;
69
+ const isHomepage = urlPath === '/';
59
70
  const { slug } = Astro.params;
60
71
  const config = getConfig();
61
72
  globalThis.storefront.settings = config.settings;
@@ -118,18 +129,21 @@ const loadPageContext = async (Astro: AstroGlobal, {
118
129
  Astro.response.headers.set('X-Load-Took', String(Date.now() - startedAt));
119
130
  if (urlPath === '/fallback') {
120
131
  setResponseCache(Astro, 3600, 86400);
121
- } else if (urlPath === '/') {
132
+ } else if (isHomepage) {
122
133
  setResponseCache(Astro, 180, 300);
123
134
  } else {
124
135
  setResponseCache(Astro, 120, 300);
125
136
  }
126
- return {
137
+ const pageContext = {
127
138
  ...config,
139
+ isHomepage,
128
140
  cmsContent,
129
141
  apiResource,
130
142
  apiDoc,
131
143
  apiState,
132
144
  };
145
+ emitter.emit('load', pageContext);
146
+ return pageContext;
133
147
  };
134
148
 
135
149
  export default loadPageContext;
@@ -3,9 +3,11 @@ import type {
3
3
  CalculateShippingResponse,
4
4
  ApplyDiscountResponse,
5
5
  } from '@cloudcommerce/types';
6
- import { reactive } from 'vue';
6
+ import { reactive, computed } from 'vue';
7
+ import { formatMoney } from '@ecomplus/utils';
8
+ import loadingGlobalInfoPreset from '@@sf/scripts/modules-info-preset';
9
+ import utm from '@@sf/scripts/session-utm';
7
10
  import afetch from '../../helpers/afetch';
8
- import utm from '../scripts/session-utm';
9
11
 
10
12
  const emptyInfo = {
11
13
  list_payments: {},
@@ -25,31 +27,28 @@ const modulesInfo = reactive<{
25
27
  available_extra_discount?: ApplyDiscountResponse['available_extra_discount'],
26
28
  },
27
29
  }>(emptyInfo);
30
+ loadingGlobalInfoPreset.then((modulesInfoPreset) => {
31
+ Object.assign(modulesInfo, modulesInfoPreset);
32
+ });
28
33
 
29
34
  if (!import.meta.env.SSR) {
30
35
  const storageKey = 'MODULES_INFO';
31
36
  const sessionJson = sessionStorage.getItem(storageKey);
32
- let persistedValue;
33
37
  if (sessionJson) {
34
38
  try {
35
- persistedValue = JSON.parse(sessionJson);
36
- if (persistedValue.__timestamp < Date.now() - 1000 * 60 * 5) {
37
- persistedValue = null;
39
+ const persistedValue = JSON.parse(sessionJson);
40
+ if (persistedValue.__timestamp >= Date.now() - 1000 * 60 * 5) {
41
+ delete persistedValue.__timestamp;
42
+ Object.assign(modulesInfo, persistedValue);
43
+ } else {
38
44
  sessionStorage.removeItem(storageKey);
39
45
  }
40
- delete persistedValue.__timestamp;
41
46
  } catch (e) {
42
47
  sessionStorage.removeItem(storageKey);
43
48
  }
44
49
  }
45
50
 
46
- if (persistedValue?.list_payments) {
47
- Object.assign(modulesInfo, persistedValue);
48
- } else {
49
- const modulesInfoPreset = window.storefront?.modulesInfoPreset;
50
- if (modulesInfoPreset) {
51
- Object.assign(modulesInfo, modulesInfoPreset);
52
- }
51
+ const fetchInfo = () => {
53
52
  const modulesToFetch: { modName: string, reqOptions?: Record<string, any> }[] = [];
54
53
  ['list_payments', 'calculate_shipping'].forEach((modName) => {
55
54
  if (!Object.keys(modulesInfo[modName]).length) {
@@ -140,7 +139,38 @@ if (!import.meta.env.SSR) {
140
139
  })
141
140
  .catch(console.error);
142
141
  });
142
+ };
143
+ if (typeof window.requestIdleCallback === 'function') {
144
+ window.requestIdleCallback(fetchInfo);
145
+ } else {
146
+ setTimeout(fetchInfo, 300);
143
147
  }
144
148
  }
145
149
 
146
150
  export default modulesInfo;
151
+
152
+ const parsePhrase = <T extends keyof typeof modulesInfo>(
153
+ phrase: string,
154
+ modName: T,
155
+ varName: string & keyof typeof modulesInfo[T],
156
+ formatValue: (x: any) => string = formatMoney,
157
+ ) => {
158
+ return computed(() => {
159
+ const searchString = `{{${varName}}}`;
160
+ const index = phrase.indexOf(searchString);
161
+ if (index > -1) {
162
+ const fieldValue = modulesInfo[modName][varName];
163
+ if (fieldValue) {
164
+ const replacement = formatValue(fieldValue);
165
+ return phrase.substring(0, index) + replacement
166
+ + phrase.substring(index + searchString.length);
167
+ }
168
+ return '';
169
+ }
170
+ return phrase;
171
+ });
172
+ };
173
+
174
+ export const parseShippingPhrase = (phrase: string) => {
175
+ return parsePhrase(phrase, 'calculate_shipping', 'free_shipping_from_value');
176
+ };
@@ -1,6 +1,7 @@
1
1
  import { CmsSettings as _CmsSettings } from '@cloudcommerce/types';
2
2
 
3
- type CmsSettings = _CmsSettings & typeof import('content/settings.json');
3
+ type CmsSettings = _CmsSettings &
4
+ Omit<typeof import('content/settings.json'), keyof _CmsSettings>;
4
5
 
5
6
  export default CmsSettings;
6
7
 
@@ -1,3 +1,5 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join as joinPath } from 'node:path';
1
3
  import config from '@cloudcommerce/config';
2
4
  import getCMS from './config/storefront.cms.mjs';
3
5
 
@@ -7,14 +9,6 @@ export default () => {
7
9
  config.set({ storeId: Number(VITE_ECOM_STORE_ID) });
8
10
  }
9
11
 
10
- const {
11
- storeId,
12
- lang,
13
- countryCode,
14
- currency,
15
- currencySymbol,
16
- } = config.get();
17
-
18
12
  const {
19
13
  domain,
20
14
  primaryColor,
@@ -24,6 +18,24 @@ export default () => {
24
18
  } = getCMS();
25
19
  config.set({ cmsSettings: settings });
26
20
 
21
+ let { storeId } = config.get();
22
+ if (!storeId) {
23
+ const configFilepath = joinPath(process.cwd(), 'config.json');
24
+ try {
25
+ const mergeConfig = JSON.parse(readFileSync(configFilepath), 'utf8');
26
+ if (mergeConfig.storeId) {
27
+ storeId = mergeConfig.storeId;
28
+ config.set({ storeId });
29
+ }
30
+ } catch { /* */ }
31
+ }
32
+ const {
33
+ lang,
34
+ countryCode,
35
+ currency,
36
+ currencySymbol,
37
+ } = config.get();
38
+
27
39
  return {
28
40
  storeId,
29
41
  lang,
@@ -66,7 +66,7 @@ Object.keys(brandColors).forEach((colorName) => {
66
66
  const luminance = color.luminance();
67
67
  if (luminance >= 0.1) {
68
68
  subtle = chroma(hex).brighten(1.5);
69
- bold = chroma(hex).darken(1.5);
69
+ bold = chroma(hex).darken(1.25);
70
70
  } else if (luminance > 0.03) {
71
71
  subtle = chroma(hex).brighten();
72
72
  bold = chroma(hex).darken();
@@ -96,6 +96,23 @@ type CmsSettings = {
96
96
  currency: string,
97
97
  currency_symbol: string,
98
98
  country_code: string,
99
+ modules?: {
100
+ list_payments?: {
101
+ installments_option?: Partial<ListPaymentsResponse['installments_option']>,
102
+ discount_option?: Partial<ListPaymentsResponse['discount_option']>,
103
+ loyalty_points_program?: Partial<
104
+ Exclude<ListPaymentsResponse['loyalty_points_programs'], undefined>[''] & {
105
+ id: string,
106
+ }>,
107
+ loyalty_points_programs?: ListPaymentsResponse['loyalty_points_programs'],
108
+ },
109
+ calculate_shipping?: {
110
+ free_shipping_from_value?: CalculateShippingResponse['free_shipping_from_value'] | null,
111
+ },
112
+ apply_discount?: {
113
+ available_extra_discount?: Partial<ApplyDiscountResponse['available_extra_discount']>,
114
+ },
115
+ },
99
116
  };
100
117
 
101
118
  export type {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/types",
3
3
  "type": "module",
4
- "version": "0.2.1",
4
+ "version": "0.2.2",
5
5
  "description": "E-Com Plus Cloud Commerce reusable type definitions",
6
6
  "main": "index.ts",
7
7
  "repository": {
@@ -1 +0,0 @@
1
- import{u as le,q as ye,s as he,k as m,v as R,d as D,o as O,a as j,b as S,f as F,x as ue,y as _e,z as K,A as Oe,B as Te,C as we,D as Se,l as ce,w as x,p as de,n as xe,g as Ee,i as L,F as Ie,E as $e}from"./chunks/runtime-core.esm-bundler.fa6cdb60.js";/* empty css */var A=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function je(e){var t=typeof e;return e!=null&&(t=="object"||t=="function")}var fe=je,Le=typeof A=="object"&&A&&A.Object===Object&&A,Pe=Le,Ce=Pe,Be=typeof self=="object"&&self&&self.Object===Object&&self,We=Ce||Be||Function("return this")(),ve=We,ke=ve,Ne=function(){return ke.Date.now()},Ae=Ne,Re=/\s/;function Fe(e){for(var t=e.length;t--&&Re.test(e.charAt(t)););return t}var Me=Fe,Ge=Me,Qe=/^\s+/;function Ve(e){return e&&e.slice(0,Ge(e)+1).replace(Qe,"")}var He=Ve,Ue=ve,ze=Ue.Symbol,pe=ze,X=pe,me=Object.prototype,De=me.hasOwnProperty,qe=me.toString,$=X?X.toStringTag:void 0;function Ke(e){var t=De.call(e,$),n=e[$];try{e[$]=void 0;var a=!0}catch{}var u=qe.call(e);return a&&(t?e[$]=n:delete e[$]),u}var Xe=Ke,Ze=Object.prototype,Je=Ze.toString;function Ye(e){return Je.call(e)}var et=Ye,Z=pe,tt=Xe,nt=et,rt="[object Null]",at="[object Undefined]",J=Z?Z.toStringTag:void 0;function ot(e){return e==null?e===void 0?at:rt:J&&J in Object(e)?tt(e):nt(e)}var st=ot;function it(e){return e!=null&&typeof e=="object"}var lt=it,ut=st,ct=lt,dt="[object Symbol]";function ft(e){return typeof e=="symbol"||ct(e)&&ut(e)==dt}var vt=ft,pt=He,Y=fe,mt=vt,ee=0/0,bt=/^[-+]0x[0-9a-f]+$/i,gt=/^0b[01]+$/i,yt=/^0o[0-7]+$/i,ht=parseInt;function _t(e){if(typeof e=="number")return e;if(mt(e))return ee;if(Y(e)){var t=typeof e.valueOf=="function"?e.valueOf():e;e=Y(t)?t+"":t}if(typeof e!="string")return e===0?e:+e;e=pt(e);var n=gt.test(e);return n||yt.test(e)?ht(e.slice(2),n?2:8):bt.test(e)?ee:+e}var Ot=_t,Tt=fe,H=Ae,te=Ot,wt="Expected a function",St=Math.max,xt=Math.min;function Et(e,t,n){var a,u,v,i,o,d,p=0,c=!1,f=!1,b=!0;if(typeof e!="function")throw new TypeError(wt);t=te(t)||0,Tt(n)&&(c=!!n.leading,f="maxWait"in n,v=f?St(te(n.maxWait)||0,t):v,b="trailing"in n?!!n.trailing:b);function y(s){var g=a,h=u;return a=u=void 0,p=s,i=e.apply(h,g),i}function C(s){return p=s,o=setTimeout(_,t),c?y(s):i}function E(s){var g=s-d,h=s-p,W=t-g;return f?xt(W,v-h):W}function T(s){var g=s-d,h=s-p;return d===void 0||g>=t||g<0||f&&h>=v}function _(){var s=H();if(T(s))return B(s);o=setTimeout(_,E(s))}function B(s){return o=void 0,b&&a?y(s):(a=u=void 0,i)}function G(){o!==void 0&&clearTimeout(o),p=0,a=d=u=o=void 0}function Q(){return o===void 0?i:B(H())}function w(){var s=H(),g=T(s);if(a=arguments,u=this,d=s,g){if(o===void 0)return C(d);if(f)return clearTimeout(o),o=setTimeout(_,t),y(d)}return o===void 0&&(o=setTimeout(_,t)),i}return w.cancel=G,w.flush=Q,w}var ne=Et,re;const P=typeof window<"u",It=e=>typeof e=="string",$t=()=>{};P&&((re=window?.navigator)==null?void 0:re.userAgent)&&/iP(ad|hone|od)/.test(window.navigator.userAgent);function jt(e){return typeof e=="function"?e():le(e)}function Lt(e){return e}function Pt(e){return ye()?(he(e),!0):!1}function Ct(e){var t;const n=jt(e);return(t=n?.$el)!=null?t:n}const Bt=P?window:void 0;P&&window.document;P&&window.navigator;P&&window.location;function ae(...e){let t,n,a,u;if(It(e[0])||Array.isArray(e[0])?([n,a,u]=e,t=Bt):[t,n,a,u]=e,!t)return $t;Array.isArray(n)||(n=[n]),Array.isArray(a)||(a=[a]);const v=[],i=()=>{v.forEach(c=>c()),v.length=0},o=(c,f,b)=>(c.addEventListener(f,b,u),()=>c.removeEventListener(f,b,u)),d=R(()=>Ct(t),c=>{i(),c&&v.push(...n.flatMap(f=>a.map(b=>o(c,f,b))))},{immediate:!0,flush:"post"}),p=()=>{d(),i()};return Pt(p),p}const U=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},z="__vueuse_ssr_handlers__";U[z]=U[z]||{};U[z];function Wt(e){const t=m(!1);return ae(e,"mouseenter",()=>t.value=!0),ae(e,"mouseleave",()=>t.value=!1),t}var oe;(function(e){e.UP="UP",e.RIGHT="RIGHT",e.DOWN="DOWN",e.LEFT="LEFT",e.NONE="NONE"})(oe||(oe={}));var kt=Object.defineProperty,se=Object.getOwnPropertySymbols,Nt=Object.prototype.hasOwnProperty,At=Object.prototype.propertyIsEnumerable,ie=(e,t,n)=>t in e?kt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,Rt=(e,t)=>{for(var n in t||(t={}))Nt.call(t,n)&&ie(e,n,t[n]);if(se)for(var n of se(t))At.call(t,n)&&ie(e,n,t[n]);return e};const Ft={easeInSine:[.12,0,.39,0],easeOutSine:[.61,1,.88,1],easeInOutSine:[.37,0,.63,1],easeInQuad:[.11,0,.5,0],easeOutQuad:[.5,1,.89,1],easeInOutQuad:[.45,0,.55,1],easeInCubic:[.32,0,.67,0],easeOutCubic:[.33,1,.68,1],easeInOutCubic:[.65,0,.35,1],easeInQuart:[.5,0,.75,0],easeOutQuart:[.25,1,.5,1],easeInOutQuart:[.76,0,.24,1],easeInQuint:[.64,0,.78,0],easeOutQuint:[.22,1,.36,1],easeInOutQuint:[.83,0,.17,1],easeInExpo:[.7,0,.84,0],easeOutExpo:[.16,1,.3,1],easeInOutExpo:[.87,0,.13,1],easeInCirc:[.55,0,1,.45],easeOutCirc:[0,.55,.45,1],easeInOutCirc:[.85,0,.15,1],easeInBack:[.36,0,.66,-.56],easeOutBack:[.34,1.56,.64,1],easeInOutBack:[.68,-.6,.32,1.6]};Rt({linear:Lt},Ft);const be=Symbol("carousel"),Mt=["aria-label","data-carousel-control"],M=D({__name:"CarouselControl",props:{direction:{default:1}},setup(e){const{changeSlide:t}=_e(be);return(n,a)=>(O(),j("button",{type:"button","aria-label":e.direction>0?"Pr\xF3ximo":"Anterior",onClick:a[0]||(a[0]=u=>le(t)(e.direction)),"data-carousel-control":e.direction>0?"next":"previous"},[S(n.$slots,"default",{},()=>[F("i",{class:ue(["mb-0 z-10",e.direction>0?"i-chevron-right":"i-chevron-left"])},null,2)])],8,Mt))}}),Gt=D({__name:"Carousel",props:{as:{default:"ul"},modelValue:{default:1},autoplay:null},emits:["update:modelValue","bound-left","bound-right"],setup(e,{emit:t}){const n=e,a=(r,l,N)=>Math.abs(r-l)<=N,u=100,v=410,i=m(n.modelValue-1);R(K(n,"modelValue"),r=>{i.value=r-1}),R(i,(r,l)=>{r!==l&&t("update:modelValue",r+1)});const o=m(null),d=m(!0),p=m(!1),c=m([]),f=m(0),b=m(0),y=m(0),C=m(0),E=m(null),T=m(null),_=()=>{const r=a(y.value,0,5),l=a(f.value-b.value,y.value,5);r&&t("bound-left",!0),d.value=r,l&&t("bound-right",!0),p.value=l},B=()=>{f.value=o.value.scrollWidth,b.value=o.value.offsetWidth},G=()=>{const r=[...o.value.children];c.value=r.map(l=>({offsetLeft:l.offsetLeft,width:l.offsetWidth}))},Q=r=>{const l=r>0?i.value:i.value+r,N=c.value[l].width||0;return N?N*r:0},w=()=>{const r=c.value.findIndex(l=>a(l.offsetLeft,y.value,5));r!==-1&&r!==-2&&(i.value=r||0)},s=()=>{y.value=o.value.scrollLeft||0},g=()=>{const r=f.value-b.value;C.value=c.value.findIndex(({offsetLeft:l})=>l>=r)},h=()=>{!o.value||(B(),G(),s(),w(),_(),g())},W=()=>{!o.value||(s(),w(),_())};let k=null;const V=()=>{n.autoplay&&(clearTimeout(k),k=setTimeout(()=>{I(1)},n.autoplay))},I=r=>{if(r<0){if(d.value){g(),i.value=C.value-1,I(1);return}}else if(p.value){i.value=1,I(-1);return}const l=Q(r);l&&(o.value.scrollBy({left:l,behavior:"smooth"}),V())},q=m(null),ge=Wt(q);return R(ge,r=>{r?clearTimeout(k):V()}),Oe(()=>{h(),T.value=ne(W,u),E.value=ne(h,v),o.value.addEventListener("scroll",T.value),window.addEventListener("resize",E.value),Te(()=>{[...o.value.children].forEach(r=>{r.setAttribute("tabindex","0")})}),V()}),we(()=>{o.value.removeEventListener("scroll",T.value),window.removeEventListener("resize",E.value),clearTimeout(k)}),Se(be,{autoplay:K(n,"autoplay"),changeSlide:I,isBoundLeft:d,isBoundRight:p}),(r,l)=>(O(),j("div",{ref_key:"carousel",ref:q,"data-carousel":""},[(O(),ce(de(e.as),{ref_key:"wrapper",ref:o,"data-carousel-wrapper":""},{default:x(()=>[S(r.$slots,"default")]),_:3},512)),S(r.$slots,"controls",xe(Ee({changeSlide:I,isBoundLeft:d.value,isBoundRight:p.value})),()=>[L(M,{direction:-1},{default:x(()=>[S(r.$slots,"previous")]),_:3}),L(M,null,{default:x(()=>[S(r.$slots,"next")]),_:3})])],512))}}),Qt={"data-pitch-bar":"",class:"bg-base-100"},Vt={class:"container md:w-2/3 mx-auto px-3 py-1"},Ht=["innerHTML"],Ut={class:"text-xl leading-none text-base-400"},qt=D({__name:"PitchBar",props:{slides:null},setup(e){return(t,n)=>(O(),j("div",Qt,[F("div",Vt,[L(Gt,{autoplay:7e3},{controls:x(()=>[F("div",Ut,[L(M,{direction:-1,class:"pr-2 bg-base-100 hover:text-base-700"}),L(M,{class:"pl-2 bg-base-100 hover:text-base-700"})])]),default:x(()=>[(O(!0),j(Ie,null,$e(e.slides,({href:a,target:u,html:v},i)=>(O(),j("li",{key:i},[(O(),ce(de(a?"ALink":"span"),{href:a,target:u,class:ue(a?"hover:underline":null)},{default:x(()=>[S(t.$slots,"slide",{},()=>[F("span",{innerHTML:v,class:"prose text-sm text-base-800"},null,8,Ht)])]),_:2},1032,["href","target","class"]))]))),128))]),_:3})])]))}});export{qt as default};
@@ -1 +0,0 @@
1
- import"./chunks/Prices.vue_vue_type_script_setup_true_lang.781b6501.js";import{_}from"./chunks/Prices.vue_vue_type_script_setup_true_lang.781b6501.js";/* empty css */import"./chunks/session-utm.2de8b604.js";import"./chunks/runtime-core.esm-bundler.fa6cdb60.js";import"./chunks/ecom-utils.63984324.js";export{_ as default};
@@ -1 +0,0 @@
1
- import{_ as e}from"./chunks/Prices.vue_vue_type_script_setup_true_lang.781b6501.js";/* empty css */import{d as u,k as c,l as n,w as t,p as d,o as m,i as a,h as l,t as o}from"./chunks/runtime-core.esm-bundler.fa6cdb60.js";import"./chunks/session-utm.2de8b604.js";import"./chunks/ecom-utils.63984324.js";const h=u({__name:"ProductCard",props:{as:{default:"div"}},setup(p){const s=c(12),r=c(!1);return setTimeout(()=>{s.value=8,r.value=!0},5e3),(_,f)=>(m(),n(d(p.as),null,{default:t(()=>[a(e,null,{default:t(({salePrice:i})=>[l(" ProductCard "+o(i),1)]),_:1}),a(e,{product:{price:s.value}},null,8,["product"]),a(e,{price:12,"base-price":17}),a(e,{price:12,"base-price":16,"is-literal":!0}),a(e,{price:12,"is-big":r.value},null,8,["is-big"]),a(e,{price:14,"base-price":18,"is-big":r.value,"is-literal":!0},null,8,["is-big"]),a(e,{price:12,"base-price":16},{"compare-value":t(({comparePrice:i})=>[l(" x"+o(i),1)]),_:1})]),_:1}))}});export{h as default};
@@ -1 +0,0 @@
1
- import{u as T}from"./session-utm.2de8b604.js";import{r as M,c as u,d as z,a as _,u as e,b as c,n as $,m as L,e as h,g as D,o as v,f as O,t as y,h as W,i as B,w as A,j as R}from"./runtime-core.esm-bundler.fa6cdb60.js";import{g as S,c as q}from"./ecom-utils.63984324.js";const K=(n,r,m=1e4)=>{let d,t;m&&(d=new AbortController,t=setTimeout(()=>{d.abort()},m)),r?.body&&typeof r.body=="object"&&(r.body=JSON.stringify(r.body),r.headers={...r.headers,"Content-Type":"application/json","Content-Length":r.body.length.toString()});const p=fetch(n,{...r,signal:d?.signal});return p.finally(()=>{t&&clearTimeout(t)}),p},U={list_payments:{},calculate_shipping:{},apply_discount:{}},I=M(U);{const n="MODULES_INFO",r=sessionStorage.getItem(n);let m;if(r)try{m=JSON.parse(r),m.__timestamp<Date.now()-1e3*60*5&&(m=null,sessionStorage.removeItem(n)),delete m.__timestamp}catch{sessionStorage.removeItem(n)}if(m?.list_payments)Object.assign(I,m);else{const d=window.storefront?.modulesInfoPreset;d&&Object.assign(I,d);const t=[];["list_payments","calculate_shipping"].forEach(p=>{Object.keys(I[p]).length||t.push({modName:p})}),Object.keys(T).length&&t.push({modName:"apply_discount",reqOptions:{method:"post",body:{utm:T}}}),t.forEach(({modName:p,reqOptions:g})=>{K(`/api/modules/${p}`,g).then(async b=>{if(b.ok){const i={};I[p]=i;const{result:V}=await b.json();Array.isArray(V)&&V.forEach(({error:k,response:f})=>{if(!k){let s,l;switch(p){case"calculate_shipping":s="free_shipping_from_value",l=f[s],typeof l=="number"&&(i[s]===void 0||l<i[s])&&(i[s]=l);break;case"list_payments":s="installments_option",l=f[s],l&&(!i[s]||l.monthly_interest<i[s].monthly_interest||l.max_number>i[s].max_number)&&(i[s]=l),s="discount_option",l=f[s],l&&(!i[s]||l.value>i[s].value)&&f.payment_gateways.forEach(({discount:a})=>{a&&a.apply_at!=="freight"&&a.value===l.value&&(i[s]={apply_at:a.apply_at,...l})}),s="loyalty_points_programs",l=f[s],l&&(i[s]={...i[s],...l});break;default:s="available_extra_discount",l=f[s],l&&(!i[s]||l.value>i[s].value)&&(i[s]=l)}}}),sessionStorage.setItem(n,JSON.stringify({...I,__timestamp:Date.now()}))}}).catch(console.error)})}}const F=(n,r)=>{const{type:m,value:d}=r;let t;return d?(m==="percentage"?t=n*((100-d)/100):t=n-d,t>0?t:0):n},G=n=>{const r=u(()=>n.product||{price:n.price||0,base_price:n.basePrice}),m=u(()=>{const{variations:o}=r.value;if(o){const P=S(r.value);for(let j=0;j<o.length;j++)if(S({...r.value,...o[j]})>P)return!0}return!1}),d=u(()=>I.apply_discount.available_extra_discount),t=u(()=>{const o=S(r.value),P=d.value;return P&&(!P.min_amount||o>P.min_amount)?F(o,P):o}),p=u(()=>{if(q(r.value))return r.value.base_price;const o=S(r.value);return o>t.value?o:0}),g=u(()=>n.installmentsOption||I.list_payments.installments_option||{max_number:1}),b=u(()=>{if(g.value.max_number<=1)return 1;const o=g.value.min_installment||5,P=Math.round(t.value/o);return Math.min(P,g.value.max_number)}),i=u(()=>g.value.monthly_interest||0),V=u(()=>{if(b.value>=2){if(!i.value)return t.value/b.value;const o=i.value/100;return t.value*o/(1-(1+o)**-b.value)}return 0}),k=u(()=>{const o=n.discountOption||I.list_payments.discount_option;return o&&(!o.min_amount||o.min_amount<=t.value)&&(!n.isAmountTotal||o.apply_at==="total")?o:{}}),f=u(()=>{const{label:o}=k.value;return o?o.includes(" ")?o:`via ${o}`:""}),s=u(()=>F(t.value,k.value)),l=u(()=>{if(n.loyaltyPointsProgram)return n.loyaltyPointsProgram;const o=I.list_payments.loyalty_points_programs;if(o){const P=Object.keys(o);for(let j=0;j<P.length;j++){const N=o[P[j]];if(N&&N.earn_percentage>0)return N}}return{ratio:0}}),a=u(()=>l.value.min_subtotal_to_earn||0),E=u(()=>l.value.name||""),w=u(()=>l.value.earn_percentage||0),C=u(()=>w.value*l.value.ratio),J=u(()=>C.value>=1?t.value*(C.value/100):0);return{hasVariedPrices:m,salePrice:t,comparePrice:p,installmentsObject:g,installmentsNumber:b,monthlyInterest:i,installmentValue:V,discountObject:k,discountLabel:f,priceWithDiscount:s,pointsProgramObject:l,pointsMinPrice:a,pointsProgramName:E,earnPointsPercentage:w,cashbackPercentage:C,cashbackValue:J}},H=n=>u(()=>{let r="";return Object.keys(n).forEach(m=>{n[m]===!0&&(r+=` ${m.replace(/^(is|has)/,"")}`)}),r.slice(1)}),Q=["data-prices"],X={"data-prices-compare":"",class:"text-base-500 mr-1"},Y={key:0},Z={key:0},x={"data-prices-sale":"",class:"inline-block text-base-800"},ee={key:0},te={key:0,"data-prices-cashback":"",class:"relative z-10"},se=["data-tooltip"],ae=O("i",{class:"i-cashback mr-1"},null,-1),ne={class:"font-medium"},oe=O("small",null," cashback",-1),le={key:0,"data-prices-installment":""},re={key:0},ie={key:0},ce={key:0},ue={key:0,"data-prices-discount":""},me={key:0},pe={key:0},fe=z({__name:"Prices",props:{product:null,price:null,basePrice:null,isAmountTotal:{type:Boolean},installmentsOption:null,discountOption:null,isBig:{type:Boolean},isLiteral:{type:Boolean},hasCashback:{type:Boolean,default:!0},hasPriceOptions:{type:Boolean,default:!0}},setup(n){const r=n,m=G(r),{hasVariedPrices:d,salePrice:t,comparePrice:p,cashbackPercentage:g,cashbackValue:b,installmentsNumber:i,monthlyInterest:V,installmentValue:k,priceWithDiscount:f,discountLabel:s}=m,l=H(r);return(a,E)=>{const w=R("Fade");return v(),_("div",{"data-prices":e(l),class:"text-base-600"},[e(p)?c(a.$slots,"compare",$(L({key:0},{salePrice:e(t),comparePrice:e(p)})),()=>[O("span",X,[c(a.$slots,"compare-pre",{},()=>[n.isLiteral?(v(),_("small",Y,y("De "))):h("",!0)]),c(a.$slots,"compare-value",$(D({salePrice:e(t),comparePrice:e(p)})),()=>[O("s",null,y(a.$money(e(p))),1)]),c(a.$slots,"compare-post",{},()=>[n.isLiteral?(v(),_("small",Z,y(" Por"))):h("",!0)])])]):h("",!0),c(a.$slots,"sale",$(D({salePrice:e(t)})),()=>[O("strong",x,[c(a.$slots,"sale-pre",{},()=>[e(d)?(v(),_("small",ee,y("A partir de "))):h("",!0)]),c(a.$slots,"sale-value",$(D({salePrice:e(t)})),()=>[W(y(a.$money(e(t))),1)]),c(a.$slots,"sale-post")])]),e(b)?c(a.$slots,"cashback",$(L({key:1},{salePrice:e(t),cashbackValue:e(b),cashbackPercentage:e(g)})),()=>[B(w,{slide:"down"},{default:A(()=>[n.hasCashback?(v(),_("div",te,[O("span",{"data-tooltip":"Receba $1 de volta".replace("$1",a.$percentage(e(g)))},[c(a.$slots,"cashback-pre",{},()=>[ae]),c(a.$slots,"cashback-value",$(D({salePrice:e(t),cashbackValue:e(b),cashbackPercentage:e(g)})),()=>[O("span",ne,y(a.$money(e(b))),1)]),c(a.$slots,"cashback-post",{},()=>[oe])],8,se)])):h("",!0)]),_:3})]):h("",!0),e(k)?c(a.$slots,"installment",$(L({key:2},{salePrice:e(t),installmentValue:e(k),installmentsNumber:e(i),monthlyInterest:e(V)})),()=>[B(w,{slide:"down"},{default:A(()=>[n.hasPriceOptions?(v(),_("div",le,[c(a.$slots,"installment-pre",{},()=>[n.isLiteral?(v(),_("small",re,y("At\xE9 "))):h("",!0)]),c(a.$slots,"installment-value",$(D({salePrice:e(t),installmentValue:e(k),installmentsNumber:e(i),monthlyInterest:e(V)})),()=>[W(y(e(i))+"x ",1),n.isLiteral?(v(),_("small",ie,y(" De "))):h("",!0),O("span",null,y(a.$money(e(k))),1)]),c(a.$slots,"installment-post",{},()=>[!e(V)&&n.isLiteral?(v(),_("small",ce,y("Sem juros"))):h("",!0)])])):h("",!0)]),_:3})]):h("",!0),e(f)<e(t)?c(a.$slots,"discount",$(L({key:3},{salePrice:e(t),priceWithDiscount:e(f),discountLabel:e(s)})),()=>[B(w,{slide:"down"},{default:A(()=>[n.hasPriceOptions?(v(),_("div",ue,[c(a.$slots,"discount-pre",{},()=>[e(s)?h("",!0):(v(),_("small",me,y("A partir de ")))]),c(a.$slots,"discount-value",$(D({salePrice:e(t),priceWithDiscount:e(f),discountLabel:e(s)})),()=>[O("span",null,y(a.$money(e(f))),1)]),c(a.$slots,"discount-post",{},()=>[e(s)?(v(),_("small",pe,y(` ${e(s)}`),1)):h("",!0)])])):h("",!0)]),_:3})]):h("",!0)],8,Q)}}});export{fe as _};