@gem-sdk/core 1.0.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 (214) hide show
  1. package/dist/cjs/components/AddOn.js +18 -0
  2. package/dist/cjs/components/ComponentWrapper.js +45 -0
  3. package/dist/cjs/components/ComponentWrapperPreview.js +58 -0
  4. package/dist/cjs/components/Empty.js +7 -0
  5. package/dist/cjs/components/Render.js +28 -0
  6. package/dist/cjs/components/RenderBlock.js +21 -0
  7. package/dist/cjs/components/RenderPreview.js +28 -0
  8. package/dist/cjs/components/RenderSection.js +19 -0
  9. package/dist/cjs/contexts/AddonContext.js +25 -0
  10. package/dist/cjs/contexts/BuilderComponent.js +30 -0
  11. package/dist/cjs/contexts/BuilderContext.js +29 -0
  12. package/dist/cjs/contexts/BuilderPreviewContext.js +353 -0
  13. package/dist/cjs/contexts/CartLineContext.js +24 -0
  14. package/dist/cjs/contexts/CollectionContext.js +24 -0
  15. package/dist/cjs/contexts/ProductContext.js +126 -0
  16. package/dist/cjs/contexts/ProductListContext.js +24 -0
  17. package/dist/cjs/contexts/SectionContext.js +49 -0
  18. package/dist/cjs/contexts/ShopContext.js +43 -0
  19. package/dist/cjs/graphql/fragments/analytic.generated.js +11 -0
  20. package/dist/cjs/graphql/fragments/collection-detail.generated.js +13 -0
  21. package/dist/cjs/graphql/fragments/collection-product.generated.js +26 -0
  22. package/dist/cjs/graphql/fragments/data-seo.generated.js +11 -0
  23. package/dist/cjs/graphql/fragments/media.generated.js +14 -0
  24. package/dist/cjs/graphql/fragments/product-little.generated.js +25 -0
  25. package/dist/cjs/graphql/fragments/product-option-value.generated.js +13 -0
  26. package/dist/cjs/graphql/fragments/product-option.generated.js +14 -0
  27. package/dist/cjs/graphql/fragments/product.generated.js +33 -0
  28. package/dist/cjs/graphql/fragments/published-custom-section.generated.js +12 -0
  29. package/dist/cjs/graphql/fragments/published-page-section.generated.js +11 -0
  30. package/dist/cjs/graphql/fragments/published-theme-page.generated.js +27 -0
  31. package/dist/cjs/graphql/fragments/published-theme-style.generated.js +11 -0
  32. package/dist/cjs/graphql/fragments/selected-option.generated.js +11 -0
  33. package/dist/cjs/graphql/fragments/variant.generated.js +35 -0
  34. package/dist/cjs/graphql/queries/collection-detail-filter.generated.js +34 -0
  35. package/dist/cjs/graphql/queries/collection.generated.js +52 -0
  36. package/dist/cjs/graphql/queries/preview-page.generated.js +23 -0
  37. package/dist/cjs/graphql/queries/product-little-detail.generated.js +24 -0
  38. package/dist/cjs/graphql/queries/product-medias.generated.js +29 -0
  39. package/dist/cjs/graphql/queries/product-variants.generated.js +33 -0
  40. package/dist/cjs/graphql/queries/products.generated.js +41 -0
  41. package/dist/cjs/graphql/queries/published-theme-pages.generated.js +23 -0
  42. package/dist/cjs/graphql/queries/storeProperty.generated.js +12 -0
  43. package/dist/cjs/helpers/GlobalEvent.js +17 -0
  44. package/dist/cjs/helpers/background.js +104 -0
  45. package/dist/cjs/helpers/borders.js +138 -0
  46. package/dist/cjs/helpers/clone-deep.js +5 -0
  47. package/dist/cjs/helpers/cls.js +20 -0
  48. package/dist/cjs/helpers/colors.js +157 -0
  49. package/dist/cjs/helpers/compose-advance-style.js +132 -0
  50. package/dist/cjs/helpers/constant.js +17 -0
  51. package/dist/cjs/helpers/css-variable.js +7 -0
  52. package/dist/cjs/helpers/email.js +11 -0
  53. package/dist/cjs/helpers/flatten-connection.js +10 -0
  54. package/dist/cjs/helpers/fpixel.js +29 -0
  55. package/dist/cjs/helpers/get-resonsive-value.js +32 -0
  56. package/dist/cjs/helpers/get-shortname.js +92 -0
  57. package/dist/cjs/helpers/gtag.js +48 -0
  58. package/dist/cjs/helpers/is-browser.js +9 -0
  59. package/dist/cjs/helpers/is-defined.js +7 -0
  60. package/dist/cjs/helpers/is-empty-children.js +12 -0
  61. package/dist/cjs/helpers/layout.js +17 -0
  62. package/dist/cjs/helpers/load-script.js +32 -0
  63. package/dist/cjs/helpers/make-style.js +99 -0
  64. package/dist/cjs/helpers/normalize-builder-data.js +17 -0
  65. package/dist/cjs/helpers/prefetch-queries.js +68 -0
  66. package/dist/cjs/helpers/product.js +35 -0
  67. package/dist/cjs/helpers/queries/get-collection.js +173 -0
  68. package/dist/cjs/helpers/queries/get-product-by-slug.js +99 -0
  69. package/dist/cjs/helpers/queries/get-product.js +113 -0
  70. package/dist/cjs/helpers/queries/get-products.js +135 -0
  71. package/dist/cjs/helpers/radius.js +91 -0
  72. package/dist/cjs/helpers/shadow.js +48 -0
  73. package/dist/cjs/helpers/size.js +20 -0
  74. package/dist/cjs/helpers/spacing.js +45 -0
  75. package/dist/cjs/helpers/tiktokpixel.js +17 -0
  76. package/dist/cjs/helpers/typography.js +7 -0
  77. package/dist/cjs/hooks/cart/use-add-to-cart.js +20 -0
  78. package/dist/cjs/hooks/cart/use-cart-data.js +26 -0
  79. package/dist/cjs/hooks/cart/use-cart-discount-codes-update.js +20 -0
  80. package/dist/cjs/hooks/cart/use-cart-note-update.js +20 -0
  81. package/dist/cjs/hooks/cart/use-create-cart.js +22 -0
  82. package/dist/cjs/hooks/cart/use-remove-cart-item.js +20 -0
  83. package/dist/cjs/hooks/cart/use-update-cart-item.js +20 -0
  84. package/dist/cjs/hooks/shop/use-collection-query.js +16 -0
  85. package/dist/cjs/hooks/shop/use-product-query.js +16 -0
  86. package/dist/cjs/hooks/shop/use-products-query.js +16 -0
  87. package/dist/cjs/hooks/shop.js +80 -0
  88. package/dist/cjs/hooks/use-current-device.js +23 -0
  89. package/dist/cjs/hooks/use-lazy-video.js +15 -0
  90. package/dist/cjs/hooks/useCartId.js +36 -0
  91. package/dist/cjs/hooks/useCartLine.js +11 -0
  92. package/dist/cjs/hooks/useCartUI.js +42 -0
  93. package/dist/cjs/hooks/useCollection.js +9 -0
  94. package/dist/cjs/hooks/useFetchHandle.js +13 -0
  95. package/dist/cjs/hooks/useFormatMoney.js +17 -0
  96. package/dist/cjs/hooks/useIsomorphicLayoutEffect.js +10 -0
  97. package/dist/cjs/hooks/useLoadScript.js +30 -0
  98. package/dist/cjs/hooks/useMoney.js +52 -0
  99. package/dist/cjs/hooks/usePrevious.js +17 -0
  100. package/dist/cjs/hooks/useProduct.js +90 -0
  101. package/dist/cjs/hooks/useProductList.js +21 -0
  102. package/dist/cjs/hooks/useSuspenseFetch.js +24 -0
  103. package/dist/cjs/hooks/useSwatchesOptions.js +39 -0
  104. package/dist/cjs/index.js +229 -0
  105. package/dist/cjs/types/global-style.js +7 -0
  106. package/dist/cjs/types/shop.js +2 -0
  107. package/dist/esm/components/AddOn.js +14 -0
  108. package/dist/esm/components/ComponentWrapper.js +40 -0
  109. package/dist/esm/components/ComponentWrapperPreview.js +54 -0
  110. package/dist/esm/components/Empty.js +3 -0
  111. package/dist/esm/components/Render.js +24 -0
  112. package/dist/esm/components/RenderBlock.js +17 -0
  113. package/dist/esm/components/RenderPreview.js +24 -0
  114. package/dist/esm/components/RenderSection.js +15 -0
  115. package/dist/esm/contexts/AddonContext.js +21 -0
  116. package/dist/esm/contexts/BuilderComponent.js +27 -0
  117. package/dist/esm/contexts/BuilderContext.js +26 -0
  118. package/dist/esm/contexts/BuilderPreviewContext.js +350 -0
  119. package/dist/esm/contexts/CartLineContext.js +21 -0
  120. package/dist/esm/contexts/CollectionContext.js +20 -0
  121. package/dist/esm/contexts/ProductContext.js +123 -0
  122. package/dist/esm/contexts/ProductListContext.js +20 -0
  123. package/dist/esm/contexts/SectionContext.js +45 -0
  124. package/dist/esm/contexts/ShopContext.js +40 -0
  125. package/dist/esm/graphql/fragments/analytic.generated.js +9 -0
  126. package/dist/esm/graphql/fragments/collection-detail.generated.js +11 -0
  127. package/dist/esm/graphql/fragments/collection-product.generated.js +24 -0
  128. package/dist/esm/graphql/fragments/data-seo.generated.js +9 -0
  129. package/dist/esm/graphql/fragments/media.generated.js +12 -0
  130. package/dist/esm/graphql/fragments/product-little.generated.js +23 -0
  131. package/dist/esm/graphql/fragments/product-option-value.generated.js +11 -0
  132. package/dist/esm/graphql/fragments/product-option.generated.js +12 -0
  133. package/dist/esm/graphql/fragments/product.generated.js +31 -0
  134. package/dist/esm/graphql/fragments/published-custom-section.generated.js +10 -0
  135. package/dist/esm/graphql/fragments/published-page-section.generated.js +9 -0
  136. package/dist/esm/graphql/fragments/published-theme-page.generated.js +25 -0
  137. package/dist/esm/graphql/fragments/published-theme-style.generated.js +9 -0
  138. package/dist/esm/graphql/fragments/selected-option.generated.js +9 -0
  139. package/dist/esm/graphql/fragments/variant.generated.js +33 -0
  140. package/dist/esm/graphql/queries/collection-detail-filter.generated.js +32 -0
  141. package/dist/esm/graphql/queries/collection.generated.js +50 -0
  142. package/dist/esm/graphql/queries/preview-page.generated.js +21 -0
  143. package/dist/esm/graphql/queries/product-little-detail.generated.js +22 -0
  144. package/dist/esm/graphql/queries/product-medias.generated.js +27 -0
  145. package/dist/esm/graphql/queries/product-variants.generated.js +31 -0
  146. package/dist/esm/graphql/queries/products.generated.js +38 -0
  147. package/dist/esm/graphql/queries/published-theme-pages.generated.js +21 -0
  148. package/dist/esm/graphql/queries/storeProperty.generated.js +10 -0
  149. package/dist/esm/helpers/GlobalEvent.js +13 -0
  150. package/dist/esm/helpers/background.js +102 -0
  151. package/dist/esm/helpers/borders.js +133 -0
  152. package/dist/esm/helpers/clone-deep.js +3 -0
  153. package/dist/esm/helpers/cls.js +18 -0
  154. package/dist/esm/helpers/colors.js +145 -0
  155. package/dist/esm/helpers/compose-advance-style.js +130 -0
  156. package/dist/esm/helpers/constant.js +13 -0
  157. package/dist/esm/helpers/css-variable.js +5 -0
  158. package/dist/esm/helpers/email.js +6 -0
  159. package/dist/esm/helpers/flatten-connection.js +8 -0
  160. package/dist/esm/helpers/fpixel.js +25 -0
  161. package/dist/esm/helpers/get-resonsive-value.js +28 -0
  162. package/dist/esm/helpers/get-shortname.js +90 -0
  163. package/dist/esm/helpers/gtag.js +45 -0
  164. package/dist/esm/helpers/is-browser.js +5 -0
  165. package/dist/esm/helpers/is-defined.js +5 -0
  166. package/dist/esm/helpers/is-empty-children.js +7 -0
  167. package/dist/esm/helpers/layout.js +15 -0
  168. package/dist/esm/helpers/load-script.js +30 -0
  169. package/dist/esm/helpers/make-style.js +91 -0
  170. package/dist/esm/helpers/normalize-builder-data.js +15 -0
  171. package/dist/esm/helpers/prefetch-queries.js +66 -0
  172. package/dist/esm/helpers/product.js +32 -0
  173. package/dist/esm/helpers/queries/get-collection.js +170 -0
  174. package/dist/esm/helpers/queries/get-product-by-slug.js +97 -0
  175. package/dist/esm/helpers/queries/get-product.js +109 -0
  176. package/dist/esm/helpers/queries/get-products.js +133 -0
  177. package/dist/esm/helpers/radius.js +86 -0
  178. package/dist/esm/helpers/shadow.js +45 -0
  179. package/dist/esm/helpers/size.js +18 -0
  180. package/dist/esm/helpers/spacing.js +42 -0
  181. package/dist/esm/helpers/tiktokpixel.js +15 -0
  182. package/dist/esm/helpers/typography.js +5 -0
  183. package/dist/esm/hooks/cart/use-add-to-cart.js +18 -0
  184. package/dist/esm/hooks/cart/use-cart-data.js +24 -0
  185. package/dist/esm/hooks/cart/use-cart-discount-codes-update.js +18 -0
  186. package/dist/esm/hooks/cart/use-cart-note-update.js +18 -0
  187. package/dist/esm/hooks/cart/use-create-cart.js +20 -0
  188. package/dist/esm/hooks/cart/use-remove-cart-item.js +18 -0
  189. package/dist/esm/hooks/cart/use-update-cart-item.js +18 -0
  190. package/dist/esm/hooks/shop/use-collection-query.js +14 -0
  191. package/dist/esm/hooks/shop/use-product-query.js +14 -0
  192. package/dist/esm/hooks/shop/use-products-query.js +14 -0
  193. package/dist/esm/hooks/shop.js +68 -0
  194. package/dist/esm/hooks/use-current-device.js +21 -0
  195. package/dist/esm/hooks/use-lazy-video.js +13 -0
  196. package/dist/esm/hooks/useCartId.js +32 -0
  197. package/dist/esm/hooks/useCartLine.js +7 -0
  198. package/dist/esm/hooks/useCartUI.js +38 -0
  199. package/dist/esm/hooks/useCollection.js +7 -0
  200. package/dist/esm/hooks/useFetchHandle.js +11 -0
  201. package/dist/esm/hooks/useFormatMoney.js +13 -0
  202. package/dist/esm/hooks/useIsomorphicLayoutEffect.js +6 -0
  203. package/dist/esm/hooks/useLoadScript.js +26 -0
  204. package/dist/esm/hooks/useMoney.js +48 -0
  205. package/dist/esm/hooks/usePrevious.js +15 -0
  206. package/dist/esm/hooks/useProduct.js +78 -0
  207. package/dist/esm/hooks/useProductList.js +16 -0
  208. package/dist/esm/hooks/useSuspenseFetch.js +20 -0
  209. package/dist/esm/hooks/useSwatchesOptions.js +35 -0
  210. package/dist/esm/index.js +82 -0
  211. package/dist/esm/types/global-style.js +4 -0
  212. package/dist/esm/types/shop.js +1 -0
  213. package/dist/types/index.d.ts +7393 -0
  214. package/package.json +50 -0
@@ -0,0 +1,7 @@
1
+ import { Children } from 'react';
2
+
3
+ const isEmptyChildren = (children) => {
4
+ return Children.count(children) < 1 || !children;
5
+ };
6
+
7
+ export { isEmptyChildren as default, isEmptyChildren };
@@ -0,0 +1,15 @@
1
+ import { devicesMapping } from './constant.js';
2
+
3
+ const optionLayoutStyle = (column) => {
4
+ if (!column)
5
+ return {};
6
+ const style = {};
7
+ for (const [key, value] of Object.entries(column)) {
8
+ Object.assign(style, {
9
+ [`--gtc${devicesMapping?.[key]}`]: `repeat(${parseFloat(value + '') || 1}, minmax(0, 1fr))`,
10
+ });
11
+ }
12
+ return style;
13
+ };
14
+
15
+ export { optionLayoutStyle };
@@ -0,0 +1,30 @@
1
+ const SCRIPTS_LOADED = {};
2
+ function loadScript(src, options) {
3
+ const isScriptLoaded = SCRIPTS_LOADED[src];
4
+ if (isScriptLoaded) {
5
+ return isScriptLoaded;
6
+ }
7
+ const promise = new Promise((resolve, reject) => {
8
+ const script = document.createElement('script');
9
+ if (options?.module) {
10
+ script.type = 'module';
11
+ }
12
+ script.src = src;
13
+ script.onload = () => {
14
+ resolve(true);
15
+ };
16
+ script.onerror = () => {
17
+ reject(false);
18
+ };
19
+ if (options?.in === 'head') {
20
+ document.head.appendChild(script);
21
+ }
22
+ else {
23
+ document.body.appendChild(script);
24
+ }
25
+ });
26
+ SCRIPTS_LOADED[src] = promise;
27
+ return promise;
28
+ }
29
+
30
+ export { loadScript };
@@ -0,0 +1,91 @@
1
+ import { getResponsiveValueByScreen } from './get-resonsive-value.js';
2
+
3
+ const makeStyle = (style) => {
4
+ return Object.fromEntries(Object.entries(style).map(([key, value]) => [`--${key}`, value]));
5
+ };
6
+ const makeStyleState = (name, value) => {
7
+ if (!value)
8
+ return {};
9
+ return {
10
+ [`--${name}`]: value?.normal,
11
+ [`--hvr-${name}`]: value?.hover,
12
+ [`--focus-${name}`]: value?.focus,
13
+ };
14
+ };
15
+ const makeStyleResponsiveState = (name, value) => {
16
+ if (!value)
17
+ return {};
18
+ return {
19
+ [`--${name}`]: value?.desktop?.normal,
20
+ [`--hvr-${name}`]: value?.desktop?.hover,
21
+ [`--focus-${name}`]: value?.desktop?.focus,
22
+ [`--${name}-tablet`]: value?.tablet?.normal,
23
+ [`--hvr-${name}-tablet`]: value?.tablet?.hover,
24
+ [`--focus-${name}-tablet`]: value?.tablet?.focus,
25
+ [`--${name}-mobile`]: value?.mobile?.normal,
26
+ [`--hvr-${name}-mobile`]: value?.mobile?.hover,
27
+ [`--focus-${name}-mobile`]: value?.mobile?.focus,
28
+ };
29
+ };
30
+ const makeStyleResponsive = (name, value) => {
31
+ return {
32
+ [`--${name}`]: value?.desktop,
33
+ [`--${name}-tablet`]: value?.tablet,
34
+ [`--${name}-mobile`]: value?.mobile,
35
+ };
36
+ };
37
+ const makeWidth = (widthValue, fullWidthValue) => {
38
+ const getVal = (deviceValue, widthValue, fullWidthValue) => {
39
+ const widthVal = widthValue?.[deviceValue];
40
+ const fullWidthVal = fullWidthValue?.[deviceValue];
41
+ if (fullWidthVal) {
42
+ return '100%';
43
+ }
44
+ else if (fullWidthVal === false) {
45
+ return widthVal ?? widthVal;
46
+ }
47
+ else {
48
+ return widthVal;
49
+ }
50
+ };
51
+ return {
52
+ desktop: getVal('desktop', widthValue, fullWidthValue),
53
+ tablet: getVal('tablet', widthValue, fullWidthValue),
54
+ mobile: getVal('mobile', widthValue, fullWidthValue),
55
+ };
56
+ };
57
+ const makeHeight = (heighValue, autoHeight) => {
58
+ const getVal = (deviceValue, heighValue, autoHeight) => {
59
+ const heightVal = heighValue?.[deviceValue];
60
+ const isAuto = autoHeight?.[deviceValue];
61
+ if (isAuto) {
62
+ return 'auto';
63
+ }
64
+ else if (isAuto === false) {
65
+ return heightVal ?? heightVal;
66
+ }
67
+ else {
68
+ return heightVal;
69
+ }
70
+ };
71
+ return {
72
+ desktop: getVal('desktop', heighValue, autoHeight),
73
+ tablet: getVal('tablet', heighValue, autoHeight),
74
+ mobile: getVal('mobile', heighValue, autoHeight),
75
+ };
76
+ };
77
+ const makeAspectRatio = (aspectRatio, aspectWidth, aspectHeight) => {
78
+ return {
79
+ desktop: aspectRatio?.desktop === 'custom'
80
+ ? `${getResponsiveValueByScreen(aspectWidth, 'desktop')}/${getResponsiveValueByScreen(aspectHeight, 'desktop')}`
81
+ : aspectRatio?.desktop,
82
+ tablet: aspectRatio?.tablet === 'custom'
83
+ ? `${getResponsiveValueByScreen(aspectWidth, 'tablet')}/${getResponsiveValueByScreen(aspectHeight, 'tablet')}`
84
+ : aspectRatio?.tablet,
85
+ mobile: aspectRatio?.mobile === 'custom'
86
+ ? `${getResponsiveValueByScreen(aspectWidth, 'mobile')}/${getResponsiveValueByScreen(aspectHeight, 'mobile')}`
87
+ : aspectRatio?.mobile,
88
+ };
89
+ };
90
+
91
+ export { makeAspectRatio, makeHeight, makeStyle, makeStyleResponsive, makeStyleResponsiveState, makeStyleState, makeWidth };
@@ -0,0 +1,15 @@
1
+ function normalizeBuilderData(data) {
2
+ const result = {};
3
+ function compose(data, res = {}) {
4
+ const childrens = data.childrens;
5
+ const items = childrens?.map((child) => child.uid) ?? [];
6
+ res[data.uid] = { ...data, childrens: items, type: 'component' };
7
+ if (childrens) {
8
+ childrens.map((child) => compose(child, res));
9
+ }
10
+ }
11
+ compose(data, result);
12
+ return { ...result };
13
+ }
14
+
15
+ export { normalizeBuilderData };
@@ -0,0 +1,66 @@
1
+ import { unstable_serialize } from 'swr';
2
+ import { getCollection } from './queries/get-collection.js';
3
+ import { getProduct } from './queries/get-product.js';
4
+ import { getProducts } from './queries/get-products.js';
5
+
6
+ const prefetchQueries = (input, isSample) => {
7
+ const queries = [];
8
+ Object.keys(input).forEach((key) => {
9
+ const item = input[key];
10
+ let data = undefined;
11
+ switch (item.tag) {
12
+ case 'Product': {
13
+ if (item.settings?.isAuto)
14
+ break;
15
+ data = {
16
+ key: unstable_serialize([
17
+ 'query/product',
18
+ { id: item.settings?.productSetting?.productId ?? 'latest', isSample },
19
+ ]),
20
+ func: getProduct,
21
+ variables: { id: item.settings?.productSetting?.productId ?? 'latest', isSample },
22
+ };
23
+ break;
24
+ }
25
+ case 'ProductList': {
26
+ if (item?.settings?.productSrc === 'Collection') {
27
+ data = {
28
+ key: unstable_serialize([
29
+ 'query/collection',
30
+ {
31
+ id: item.settings?.collectionId ?? 'latest',
32
+ numberOfProducts: item.settings?.numberOfProducts ?? 4,
33
+ orderBy: item.settings?.orderBy,
34
+ isSample,
35
+ },
36
+ ]),
37
+ func: getCollection,
38
+ variables: {
39
+ id: item.settings?.collectionId ?? 'latest',
40
+ numberOfProducts: item.settings?.numberOfProducts ?? 4,
41
+ orderBy: item.settings?.orderBy,
42
+ isSample,
43
+ },
44
+ };
45
+ }
46
+ else {
47
+ data = {
48
+ key: unstable_serialize([
49
+ 'query/products',
50
+ { ids: item?.settings?.productIds?.sort(), isSample },
51
+ ]),
52
+ func: getProducts,
53
+ variables: { ids: item?.settings?.productIds?.sort(), isSample },
54
+ };
55
+ }
56
+ break;
57
+ }
58
+ }
59
+ if (data) {
60
+ queries.push(data);
61
+ }
62
+ });
63
+ return queries;
64
+ };
65
+
66
+ export { prefetchQueries };
@@ -0,0 +1,32 @@
1
+ function getSelectedVariant(variants, choices) {
2
+ /**
3
+ * Ensure the user has selected all the required options, not just some.
4
+ */
5
+ if (!variants ||
6
+ !variants.length ||
7
+ !choices ||
8
+ variants[0]?.selectedOptions.length !== Object.keys(choices).length) {
9
+ return;
10
+ }
11
+ return variants.find((variant) => {
12
+ return Object.entries(choices).every(([name, value]) => {
13
+ return variant?.selectedOptions.some((option) => option.name === name && option.value === value);
14
+ });
15
+ });
16
+ }
17
+ function parseSelectedOption(options) {
18
+ if (!options || (options && options.length === 0)) {
19
+ return;
20
+ }
21
+ return options.reduce((acc, { name, value }) => {
22
+ if (name && value) {
23
+ return {
24
+ ...acc,
25
+ [name]: value,
26
+ };
27
+ }
28
+ return acc;
29
+ }, {});
30
+ }
31
+
32
+ export { getSelectedVariant, parseSelectedOption };
@@ -0,0 +1,170 @@
1
+ import { CollectionDetailFilterDocument } from '../../graphql/queries/collection-detail-filter.generated.js';
2
+ import { ProductVariantsDocument } from '../../graphql/queries/product-variants.generated.js';
3
+ import { isDefined } from '../is-defined.js';
4
+
5
+ function productSortedByOrder(key) {
6
+ switch (key) {
7
+ case 'TITLE_ASC':
8
+ return { direction: 'ASC', field: 'TITLE' };
9
+ case 'TITLE_DESC':
10
+ return { direction: 'DESC', field: 'TITLE' };
11
+ case 'CREATED_AT_ASC':
12
+ return { direction: 'ASC', field: 'CREATED_AT' };
13
+ case 'CREATED_AT_DESC':
14
+ return { direction: 'DESC', field: 'CREATED_AT' };
15
+ case 'none':
16
+ return undefined;
17
+ default:
18
+ return undefined;
19
+ }
20
+ }
21
+ const getCollection = async (fetcher, arg) => {
22
+ const collections = await loopFetchCollection(fetcher, arg);
23
+ if (!collections) {
24
+ throw new Error('collections not found');
25
+ }
26
+ // merge product collection variant
27
+ const mergeProducts = await mergeProductCollectionVariant(fetcher, collections, arg.isSample);
28
+ return mergeProducts;
29
+ };
30
+ const fetchCollection = async (fetcher, variables) => {
31
+ return fetcher([
32
+ CollectionDetailFilterDocument,
33
+ variables,
34
+ ]);
35
+ };
36
+ const calculateFirstProduct = (numberOfProducts, currentPage, productsPerPage) => {
37
+ const remainingProducts = numberOfProducts - productsPerPage * currentPage;
38
+ if (numberOfProducts < productsPerPage)
39
+ return numberOfProducts;
40
+ return remainingProducts > 0 ? productsPerPage : productsPerPage + remainingProducts;
41
+ };
42
+ const loopFetchCollection = async (fetcher, arg) => {
43
+ const productsPerPage = 8; // number of products per page
44
+ let variables; // variables of collection query
45
+ let productAfterFetcher; // product after of collection query
46
+ let dataCollection; // data of collection query
47
+ let hasNextPage; //
48
+ let firstCollection;
49
+ let currentPage = 1;
50
+ if (arg.numberOfProducts) {
51
+ const pages = Math.ceil(arg.numberOfProducts / productsPerPage);
52
+ while (currentPage <= pages && hasNextPage !== false) {
53
+ variables = {
54
+ firstVariant: 1,
55
+ firstMedia: 30,
56
+ orderBy: {
57
+ field: 'UPDATED_AT',
58
+ direction: 'DESC',
59
+ },
60
+ firstProduct: calculateFirstProduct(arg.numberOfProducts, currentPage, productsPerPage),
61
+ ...(!arg.id || arg.id.toLowerCase() === 'latest'
62
+ ? { where: { hasCollectionProducts: true } }
63
+ : { where: { baseID: arg.id } }),
64
+ orderByProduct: productSortedByOrder(arg.orderBy),
65
+ whereProduct: {
66
+ isStorefront: true,
67
+ isSample: arg.isSample,
68
+ },
69
+ productsAfter: productAfterFetcher,
70
+ };
71
+ const pageData = await fetchCollection(fetcher, variables);
72
+ productAfterFetcher = pageData?.collections?.edges?.[0]?.node?.products?.pageInfo?.endCursor;
73
+ if (currentPage === 1) {
74
+ dataCollection = pageData; // set data of first page
75
+ firstCollection = dataCollection?.collections?.edges?.[0];
76
+ }
77
+ else if (firstCollection?.node?.products &&
78
+ pageData?.collections?.edges?.[0]?.node?.products?.edges) {
79
+ // concat new values to the old ones
80
+ firstCollection.node.products = {
81
+ pageInfo: pageData?.collections?.edges?.[0]?.node?.products?.pageInfo,
82
+ edges: firstCollection.node?.products?.edges.concat(pageData?.collections?.edges?.[0]?.node?.products?.edges),
83
+ };
84
+ }
85
+ currentPage++;
86
+ // hasNextPage = false if there is no more pages then break the loop
87
+ if (!firstCollection?.node?.products?.pageInfo?.hasNextPage) {
88
+ hasNextPage = false;
89
+ break;
90
+ }
91
+ }
92
+ return dataCollection;
93
+ }
94
+ };
95
+ const mergeProductCollectionVariant = async (fetcher, collection, isSample) => {
96
+ const node = collection?.collections?.edges?.[0]?.node;
97
+ if (!node)
98
+ return collection;
99
+ const productList = node?.products?.edges;
100
+ const listBaseId = productList?.map((product) => product?.node?.baseID).filter(isDefined);
101
+ const ProductListWithVariants = await fetchVariantsByBaseIds(fetcher, {
102
+ ids: listBaseId,
103
+ isSample,
104
+ });
105
+ // mapping variant to product list in collections
106
+ const newProductList = productList?.map((product) => {
107
+ const productVariants = ProductListWithVariants?.variants?.edges?.filter((productV) => productV?.node?.id === product?.node?.id);
108
+ return {
109
+ ...product,
110
+ node: product.node
111
+ ? {
112
+ ...product.node,
113
+ variants: product.node?.variants
114
+ ? {
115
+ ...product.node?.variants,
116
+ edges: productVariants?.[0]?.node?.variants?.edges ?? [],
117
+ }
118
+ : undefined,
119
+ }
120
+ : undefined,
121
+ };
122
+ }) ?? [];
123
+ const newCollection = {
124
+ ...collection,
125
+ collections: {
126
+ edges: [
127
+ {
128
+ node: {
129
+ ...node,
130
+ products: {
131
+ edges: newProductList,
132
+ },
133
+ },
134
+ cursor: undefined,
135
+ },
136
+ ],
137
+ },
138
+ };
139
+ return newCollection;
140
+ };
141
+ const fetchVariantsByBaseIds = async (fetcher, { ids, isSample }) => {
142
+ const initVariables = {
143
+ firstVariant: 100,
144
+ first: ids?.length || 1,
145
+ orderBy: {
146
+ field: 'UPDATED_AT',
147
+ direction: 'DESC',
148
+ },
149
+ where: {
150
+ isStorefront: true,
151
+ isSample,
152
+ ...(ids?.length && { baseIDIn: ids.sort() }),
153
+ },
154
+ };
155
+ const query = async (variables) => {
156
+ try {
157
+ const response = await fetcher([
158
+ ProductVariantsDocument,
159
+ variables,
160
+ ]);
161
+ return response;
162
+ }
163
+ catch {
164
+ return {};
165
+ }
166
+ };
167
+ return query(initVariables);
168
+ };
169
+
170
+ export { calculateFirstProduct, getCollection };
@@ -0,0 +1,97 @@
1
+ import { ProductLittleDetailDocument } from '../../graphql/queries/product-little-detail.generated.js';
2
+ import { ProductMediasDocument } from '../../graphql/queries/product-medias.generated.js';
3
+ import { ProductVariantsDocument } from '../../graphql/queries/product-variants.generated.js';
4
+
5
+ const getProductBySlug = async (fetcher, slug) => {
6
+ const [product, variants, medias] = await Promise.all([
7
+ fetchProduct(fetcher, slug),
8
+ fetchVariants(fetcher, slug),
9
+ fetchMedias(fetcher, slug),
10
+ ]);
11
+ if (!product) {
12
+ throw new Error('Product not found');
13
+ }
14
+ return {
15
+ ...product,
16
+ variants: {
17
+ edges: variants,
18
+ },
19
+ medias: {
20
+ edges: medias,
21
+ },
22
+ };
23
+ };
24
+ const orderBy = {
25
+ field: 'UPDATED_AT',
26
+ direction: 'DESC',
27
+ };
28
+ const fetchProduct = async (fetcher, handle) => {
29
+ const variables = {
30
+ orderBy,
31
+ where: { handle, isStorefront: true },
32
+ };
33
+ const response = await fetcher([ProductLittleDetailDocument, variables]);
34
+ return response.product?.edges?.[0]?.node;
35
+ };
36
+ const fetchVariants = async (fetcher, handle) => {
37
+ const initVariables = {
38
+ orderBy,
39
+ where: { handle, isStorefront: true },
40
+ };
41
+ const query = async (variables, olds) => {
42
+ try {
43
+ const response = await fetcher([
44
+ ProductVariantsDocument,
45
+ variables,
46
+ ]);
47
+ const product = response.variants?.edges?.[0];
48
+ const items = olds?.concat(product?.node?.variants?.edges ?? []);
49
+ if (product?.node?.variants?.pageInfo?.hasNextPage) {
50
+ return query({
51
+ ...variables,
52
+ afterVariant: product?.node?.variants?.pageInfo.endCursor,
53
+ }, items);
54
+ }
55
+ return items ?? [];
56
+ }
57
+ catch {
58
+ return olds ?? [];
59
+ }
60
+ };
61
+ return query(initVariables, []);
62
+ };
63
+ const fetchMedias = async (fetcher, handle) => {
64
+ const initVariables = {
65
+ orderBy,
66
+ where: { handle, isStorefront: true },
67
+ };
68
+ const query = async (variables) => {
69
+ try {
70
+ const response = await fetcher([
71
+ ProductMediasDocument,
72
+ variables,
73
+ ]);
74
+ const product = response.medias?.edges?.[0];
75
+ const items = product?.node?.medias?.edges ?? [];
76
+ if (product?.node?.medias?.pageInfo?.hasNextPage) {
77
+ try {
78
+ const newData = await query({
79
+ ...variables,
80
+ afterMedia: product?.node?.medias?.pageInfo.endCursor,
81
+ });
82
+ return items.concat(newData);
83
+ }
84
+ catch {
85
+ return items;
86
+ }
87
+ }
88
+ return items;
89
+ }
90
+ catch {
91
+ return [];
92
+ }
93
+ };
94
+ return query(initVariables);
95
+ };
96
+
97
+ export { getProductBySlug };
@@ -0,0 +1,109 @@
1
+ import { ProductLittleDetailDocument } from '../../graphql/queries/product-little-detail.generated.js';
2
+ import { ProductMediasDocument } from '../../graphql/queries/product-medias.generated.js';
3
+ import { ProductVariantsDocument } from '../../graphql/queries/product-variants.generated.js';
4
+
5
+ const getProduct = async (fetcher, { id, isSample }) => {
6
+ const [product, variants, medias] = await Promise.all([
7
+ fetchProduct(fetcher, { id, isSample }),
8
+ fetchVariants(fetcher, { id, isSample }),
9
+ fetchMedias(fetcher, { id, isSample }),
10
+ ]);
11
+ if (!product) {
12
+ throw new Error('Product not found');
13
+ }
14
+ return {
15
+ ...product,
16
+ variants: {
17
+ edges: variants,
18
+ },
19
+ medias: {
20
+ edges: medias,
21
+ },
22
+ };
23
+ };
24
+ const orderBy = {
25
+ field: 'UPDATED_AT',
26
+ direction: 'DESC',
27
+ };
28
+ const fetchProduct = async (fetcher, { id, isSample }) => {
29
+ const variables = {
30
+ orderBy,
31
+ where: {
32
+ isStorefront: true,
33
+ isSample,
34
+ ...(id && id.toLowerCase() !== 'latest' && { baseID: id }),
35
+ },
36
+ };
37
+ const response = await fetcher([ProductLittleDetailDocument, variables]);
38
+ return response.product?.edges?.[0]?.node;
39
+ };
40
+ const fetchVariants = async (fetcher, { id, isSample }) => {
41
+ const initVariables = {
42
+ orderBy,
43
+ where: {
44
+ isStorefront: true,
45
+ isSample,
46
+ ...(id && id.toLowerCase() !== 'latest' && { baseID: id }),
47
+ },
48
+ };
49
+ const query = async (variables, olds) => {
50
+ try {
51
+ const response = await fetcher([
52
+ ProductVariantsDocument,
53
+ variables,
54
+ ]);
55
+ const product = response.variants?.edges?.[0];
56
+ const items = olds?.concat(product?.node?.variants?.edges ?? []);
57
+ if (product?.node?.variants?.pageInfo?.hasNextPage) {
58
+ return query({
59
+ ...variables,
60
+ afterVariant: product?.node?.variants?.pageInfo.endCursor,
61
+ }, items);
62
+ }
63
+ return items ?? [];
64
+ }
65
+ catch {
66
+ return olds ?? [];
67
+ }
68
+ };
69
+ return query(initVariables, []);
70
+ };
71
+ const fetchMedias = async (fetcher, { id, isSample }) => {
72
+ const initVariables = {
73
+ orderBy,
74
+ where: {
75
+ isStorefront: true,
76
+ isSample,
77
+ ...(id && id.toLowerCase() !== 'latest' && { baseID: id }),
78
+ },
79
+ };
80
+ const query = async (variables) => {
81
+ try {
82
+ const response = await fetcher([
83
+ ProductMediasDocument,
84
+ variables,
85
+ ]);
86
+ const product = response.medias?.edges?.[0];
87
+ const items = product?.node?.medias?.edges ?? [];
88
+ if (product?.node?.medias?.pageInfo?.hasNextPage) {
89
+ try {
90
+ const newData = await query({
91
+ ...variables,
92
+ afterMedia: product?.node?.medias?.pageInfo.endCursor,
93
+ });
94
+ return items.concat(newData);
95
+ }
96
+ catch {
97
+ return items;
98
+ }
99
+ }
100
+ return items;
101
+ }
102
+ catch {
103
+ return [];
104
+ }
105
+ };
106
+ return query(initVariables);
107
+ };
108
+
109
+ export { fetchMedias, fetchVariants, getProduct };