@shopify/hydrogen-react 2024.7.6 → 2024.10.1

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 (186) hide show
  1. package/customer-account.schema.json +1 -1
  2. package/dist/browser-dev/AddToCartButton.mjs.map +1 -1
  3. package/dist/browser-dev/BuyNowButton.mjs.map +1 -1
  4. package/dist/browser-dev/CartCost.mjs.map +1 -1
  5. package/dist/browser-dev/CartLineProvider.mjs.map +1 -1
  6. package/dist/browser-dev/CartProvider.mjs.map +1 -1
  7. package/dist/browser-dev/ExternalVideo.mjs.map +1 -1
  8. package/dist/browser-dev/Image.mjs.map +1 -1
  9. package/dist/browser-dev/ModelViewer.mjs.map +1 -1
  10. package/dist/browser-dev/Money.mjs.map +1 -1
  11. package/dist/browser-dev/ProductPrice.mjs +7 -19
  12. package/dist/browser-dev/ProductPrice.mjs.map +1 -1
  13. package/dist/browser-dev/RichText.mjs.map +1 -1
  14. package/dist/browser-dev/Video.mjs.map +1 -1
  15. package/dist/browser-dev/codegen.helpers.mjs.map +1 -1
  16. package/dist/browser-dev/getProductOptions.mjs +239 -0
  17. package/dist/browser-dev/getProductOptions.mjs.map +1 -0
  18. package/dist/browser-dev/index.mjs +9 -0
  19. package/dist/browser-dev/index.mjs.map +1 -1
  20. package/dist/browser-dev/optionValueDecoder.mjs +91 -0
  21. package/dist/browser-dev/optionValueDecoder.mjs.map +1 -0
  22. package/dist/browser-dev/packages/hydrogen-react/package.json.mjs +1 -1
  23. package/dist/browser-dev/storefront-api-constants.mjs +1 -1
  24. package/dist/browser-dev/storefront-api-constants.mjs.map +1 -1
  25. package/dist/browser-dev/useCartAPIStateMachine.mjs.map +1 -1
  26. package/dist/browser-dev/useCartActions.mjs.map +1 -1
  27. package/dist/browser-dev/useSelectedOptionInUrlParam.mjs +30 -0
  28. package/dist/browser-dev/useSelectedOptionInUrlParam.mjs.map +1 -0
  29. package/dist/browser-prod/AddToCartButton.mjs.map +1 -1
  30. package/dist/browser-prod/BuyNowButton.mjs.map +1 -1
  31. package/dist/browser-prod/CartCost.mjs.map +1 -1
  32. package/dist/browser-prod/CartLineProvider.mjs.map +1 -1
  33. package/dist/browser-prod/CartProvider.mjs.map +1 -1
  34. package/dist/browser-prod/ExternalVideo.mjs.map +1 -1
  35. package/dist/browser-prod/Image.mjs.map +1 -1
  36. package/dist/browser-prod/ModelViewer.mjs.map +1 -1
  37. package/dist/browser-prod/Money.mjs.map +1 -1
  38. package/dist/browser-prod/ProductPrice.mjs +7 -19
  39. package/dist/browser-prod/ProductPrice.mjs.map +1 -1
  40. package/dist/browser-prod/RichText.mjs.map +1 -1
  41. package/dist/browser-prod/Video.mjs.map +1 -1
  42. package/dist/browser-prod/codegen.helpers.mjs.map +1 -1
  43. package/dist/browser-prod/getProductOptions.mjs +239 -0
  44. package/dist/browser-prod/getProductOptions.mjs.map +1 -0
  45. package/dist/browser-prod/index.mjs +9 -0
  46. package/dist/browser-prod/index.mjs.map +1 -1
  47. package/dist/browser-prod/optionValueDecoder.mjs +91 -0
  48. package/dist/browser-prod/optionValueDecoder.mjs.map +1 -0
  49. package/dist/browser-prod/packages/hydrogen-react/package.json.mjs +1 -1
  50. package/dist/browser-prod/storefront-api-constants.mjs +1 -1
  51. package/dist/browser-prod/storefront-api-constants.mjs.map +1 -1
  52. package/dist/browser-prod/useCartAPIStateMachine.mjs.map +1 -1
  53. package/dist/browser-prod/useCartActions.mjs.map +1 -1
  54. package/dist/browser-prod/useSelectedOptionInUrlParam.mjs +30 -0
  55. package/dist/browser-prod/useSelectedOptionInUrlParam.mjs.map +1 -0
  56. package/dist/node-dev/AddToCartButton.js.map +1 -1
  57. package/dist/node-dev/AddToCartButton.mjs.map +1 -1
  58. package/dist/node-dev/BuyNowButton.js.map +1 -1
  59. package/dist/node-dev/BuyNowButton.mjs.map +1 -1
  60. package/dist/node-dev/CartCost.js.map +1 -1
  61. package/dist/node-dev/CartCost.mjs.map +1 -1
  62. package/dist/node-dev/CartLineProvider.js.map +1 -1
  63. package/dist/node-dev/CartLineProvider.mjs.map +1 -1
  64. package/dist/node-dev/CartProvider.js.map +1 -1
  65. package/dist/node-dev/CartProvider.mjs.map +1 -1
  66. package/dist/node-dev/ExternalVideo.js.map +1 -1
  67. package/dist/node-dev/ExternalVideo.mjs.map +1 -1
  68. package/dist/node-dev/Image.js.map +1 -1
  69. package/dist/node-dev/Image.mjs.map +1 -1
  70. package/dist/node-dev/ModelViewer.js.map +1 -1
  71. package/dist/node-dev/ModelViewer.mjs.map +1 -1
  72. package/dist/node-dev/Money.js.map +1 -1
  73. package/dist/node-dev/Money.mjs.map +1 -1
  74. package/dist/node-dev/ProductPrice.js +7 -19
  75. package/dist/node-dev/ProductPrice.js.map +1 -1
  76. package/dist/node-dev/ProductPrice.mjs +7 -19
  77. package/dist/node-dev/ProductPrice.mjs.map +1 -1
  78. package/dist/node-dev/RichText.js.map +1 -1
  79. package/dist/node-dev/RichText.mjs.map +1 -1
  80. package/dist/node-dev/Video.js.map +1 -1
  81. package/dist/node-dev/Video.mjs.map +1 -1
  82. package/dist/node-dev/codegen.helpers.js.map +1 -1
  83. package/dist/node-dev/codegen.helpers.mjs.map +1 -1
  84. package/dist/node-dev/getProductOptions.js +239 -0
  85. package/dist/node-dev/getProductOptions.js.map +1 -0
  86. package/dist/node-dev/getProductOptions.mjs +239 -0
  87. package/dist/node-dev/getProductOptions.mjs.map +1 -0
  88. package/dist/node-dev/index.js +9 -0
  89. package/dist/node-dev/index.js.map +1 -1
  90. package/dist/node-dev/index.mjs +9 -0
  91. package/dist/node-dev/index.mjs.map +1 -1
  92. package/dist/node-dev/optionValueDecoder.js +91 -0
  93. package/dist/node-dev/optionValueDecoder.js.map +1 -0
  94. package/dist/node-dev/optionValueDecoder.mjs +91 -0
  95. package/dist/node-dev/optionValueDecoder.mjs.map +1 -0
  96. package/dist/node-dev/packages/hydrogen-react/package.json.js +1 -1
  97. package/dist/node-dev/packages/hydrogen-react/package.json.mjs +1 -1
  98. package/dist/node-dev/storefront-api-constants.js +1 -1
  99. package/dist/node-dev/storefront-api-constants.js.map +1 -1
  100. package/dist/node-dev/storefront-api-constants.mjs +1 -1
  101. package/dist/node-dev/storefront-api-constants.mjs.map +1 -1
  102. package/dist/node-dev/useCartAPIStateMachine.js.map +1 -1
  103. package/dist/node-dev/useCartAPIStateMachine.mjs.map +1 -1
  104. package/dist/node-dev/useCartActions.js.map +1 -1
  105. package/dist/node-dev/useCartActions.mjs.map +1 -1
  106. package/dist/node-dev/useSelectedOptionInUrlParam.js +30 -0
  107. package/dist/node-dev/useSelectedOptionInUrlParam.js.map +1 -0
  108. package/dist/node-dev/useSelectedOptionInUrlParam.mjs +30 -0
  109. package/dist/node-dev/useSelectedOptionInUrlParam.mjs.map +1 -0
  110. package/dist/node-prod/AddToCartButton.js.map +1 -1
  111. package/dist/node-prod/AddToCartButton.mjs.map +1 -1
  112. package/dist/node-prod/BuyNowButton.js.map +1 -1
  113. package/dist/node-prod/BuyNowButton.mjs.map +1 -1
  114. package/dist/node-prod/CartCost.js.map +1 -1
  115. package/dist/node-prod/CartCost.mjs.map +1 -1
  116. package/dist/node-prod/CartLineProvider.js.map +1 -1
  117. package/dist/node-prod/CartLineProvider.mjs.map +1 -1
  118. package/dist/node-prod/CartProvider.js.map +1 -1
  119. package/dist/node-prod/CartProvider.mjs.map +1 -1
  120. package/dist/node-prod/ExternalVideo.js.map +1 -1
  121. package/dist/node-prod/ExternalVideo.mjs.map +1 -1
  122. package/dist/node-prod/Image.js.map +1 -1
  123. package/dist/node-prod/Image.mjs.map +1 -1
  124. package/dist/node-prod/ModelViewer.js.map +1 -1
  125. package/dist/node-prod/ModelViewer.mjs.map +1 -1
  126. package/dist/node-prod/Money.js.map +1 -1
  127. package/dist/node-prod/Money.mjs.map +1 -1
  128. package/dist/node-prod/ProductPrice.js +7 -19
  129. package/dist/node-prod/ProductPrice.js.map +1 -1
  130. package/dist/node-prod/ProductPrice.mjs +7 -19
  131. package/dist/node-prod/ProductPrice.mjs.map +1 -1
  132. package/dist/node-prod/RichText.js.map +1 -1
  133. package/dist/node-prod/RichText.mjs.map +1 -1
  134. package/dist/node-prod/Video.js.map +1 -1
  135. package/dist/node-prod/Video.mjs.map +1 -1
  136. package/dist/node-prod/codegen.helpers.js.map +1 -1
  137. package/dist/node-prod/codegen.helpers.mjs.map +1 -1
  138. package/dist/node-prod/getProductOptions.js +239 -0
  139. package/dist/node-prod/getProductOptions.js.map +1 -0
  140. package/dist/node-prod/getProductOptions.mjs +239 -0
  141. package/dist/node-prod/getProductOptions.mjs.map +1 -0
  142. package/dist/node-prod/index.js +9 -0
  143. package/dist/node-prod/index.js.map +1 -1
  144. package/dist/node-prod/index.mjs +9 -0
  145. package/dist/node-prod/index.mjs.map +1 -1
  146. package/dist/node-prod/optionValueDecoder.js +91 -0
  147. package/dist/node-prod/optionValueDecoder.js.map +1 -0
  148. package/dist/node-prod/optionValueDecoder.mjs +91 -0
  149. package/dist/node-prod/optionValueDecoder.mjs.map +1 -0
  150. package/dist/node-prod/packages/hydrogen-react/package.json.js +1 -1
  151. package/dist/node-prod/packages/hydrogen-react/package.json.mjs +1 -1
  152. package/dist/node-prod/storefront-api-constants.js +1 -1
  153. package/dist/node-prod/storefront-api-constants.js.map +1 -1
  154. package/dist/node-prod/storefront-api-constants.mjs +1 -1
  155. package/dist/node-prod/storefront-api-constants.mjs.map +1 -1
  156. package/dist/node-prod/useCartAPIStateMachine.js.map +1 -1
  157. package/dist/node-prod/useCartAPIStateMachine.mjs.map +1 -1
  158. package/dist/node-prod/useCartActions.js.map +1 -1
  159. package/dist/node-prod/useCartActions.mjs.map +1 -1
  160. package/dist/node-prod/useSelectedOptionInUrlParam.js +30 -0
  161. package/dist/node-prod/useSelectedOptionInUrlParam.js.map +1 -0
  162. package/dist/node-prod/useSelectedOptionInUrlParam.mjs +30 -0
  163. package/dist/node-prod/useSelectedOptionInUrlParam.mjs.map +1 -0
  164. package/dist/types/CartLineProvider.d.ts +1 -1
  165. package/dist/types/CartProvider.d.ts +6 -5
  166. package/dist/types/Image.d.ts +1 -1
  167. package/dist/types/ModelViewer.d.ts +1 -1
  168. package/dist/types/Money.d.ts +1 -1
  169. package/dist/types/Video.d.ts +1 -1
  170. package/dist/types/codegen.helpers.d.ts +2 -2
  171. package/dist/types/getProductOptions.d.ts +49 -0
  172. package/dist/types/index.d.cts +3 -0
  173. package/dist/types/index.d.ts +3 -0
  174. package/dist/types/optionValueDecoder.d.ts +29 -0
  175. package/dist/types/storefront-api-constants.d.ts +1 -1
  176. package/dist/types/storefront-api-response.types.d.ts +5 -5
  177. package/dist/types/storefront-api-types.d.ts +419 -26
  178. package/dist/types/useCartAPIStateMachine.d.ts +2 -2
  179. package/dist/types/useCartActions.d.ts +2 -2
  180. package/dist/types/useSelectedOptionInUrlParam.d.ts +2 -0
  181. package/dist/umd/hydrogen-react.dev.js +356 -21
  182. package/dist/umd/hydrogen-react.dev.js.map +1 -1
  183. package/dist/umd/hydrogen-react.prod.js +18 -18
  184. package/dist/umd/hydrogen-react.prod.js.map +1 -1
  185. package/package.json +2 -2
  186. package/storefront.schema.json +1 -1
@@ -0,0 +1,239 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const optionValueDecoder = require("./optionValueDecoder.js");
4
+ function mapProductOptions(options) {
5
+ return options.map((option) => {
6
+ return Object.assign(
7
+ {},
8
+ ...(option == null ? void 0 : option.optionValues) ? option.optionValues.map((value, index) => {
9
+ return { [value.name]: index };
10
+ }) : []
11
+ );
12
+ });
13
+ }
14
+ function mapSelectedProductOptionToObject(options) {
15
+ return Object.assign(
16
+ {},
17
+ ...options.map((key) => {
18
+ return { [key.name]: key.value };
19
+ })
20
+ );
21
+ }
22
+ function mapSelectedProductOptionToObjectAsString(options) {
23
+ return JSON.stringify(mapSelectedProductOptionToObject(options));
24
+ }
25
+ function encodeSelectedProductOptionAsKey(selectedOption, productOptionMappings) {
26
+ if (Array.isArray(selectedOption)) {
27
+ return JSON.stringify(
28
+ selectedOption.map((key, index) => {
29
+ return productOptionMappings[index][key.value];
30
+ })
31
+ );
32
+ } else {
33
+ return JSON.stringify(
34
+ Object.keys(selectedOption).map((key, index) => {
35
+ return productOptionMappings[index][selectedOption[key]];
36
+ })
37
+ );
38
+ }
39
+ }
40
+ function mapVariants(variants, productOptionMappings) {
41
+ return Object.assign(
42
+ {},
43
+ ...variants.map((variant) => {
44
+ const variantKey = encodeSelectedProductOptionAsKey(
45
+ variant.selectedOptions || [],
46
+ productOptionMappings
47
+ );
48
+ return { [variantKey]: variant };
49
+ })
50
+ );
51
+ }
52
+ const PRODUCT_INPUTS = [
53
+ "options",
54
+ "selectedOrFirstAvailableVariant",
55
+ "adjacentVariants"
56
+ ];
57
+ const PRODUCT_INPUTS_EXTRA = [
58
+ "handle",
59
+ "encodedVariantExistence",
60
+ "encodedVariantAvailability"
61
+ ];
62
+ function logErrorAndReturnFalse(key) {
63
+ console.error(
64
+ `[h2:error:getProductOptions] product.${key} is missing. Make sure you query for this field from the Storefront API.`
65
+ );
66
+ return false;
67
+ }
68
+ function checkProductParam(product, checkAll = false) {
69
+ var _a;
70
+ let validParam = true;
71
+ const productKeys = Object.keys(product);
72
+ (checkAll ? [...PRODUCT_INPUTS, ...PRODUCT_INPUTS_EXTRA] : PRODUCT_INPUTS).forEach((key) => {
73
+ if (!productKeys.includes(key)) {
74
+ validParam = logErrorAndReturnFalse(key);
75
+ }
76
+ });
77
+ if (product.options) {
78
+ const firstOption = product == null ? void 0 : product.options[0];
79
+ if (checkAll && !(firstOption == null ? void 0 : firstOption.name)) {
80
+ validParam = logErrorAndReturnFalse("options.name");
81
+ }
82
+ if ((_a = product == null ? void 0 : product.options[0]) == null ? void 0 : _a.optionValues) {
83
+ const firstOptionValues = product.options[0].optionValues[0];
84
+ if (checkAll && !(firstOptionValues == null ? void 0 : firstOptionValues.name)) {
85
+ validParam = logErrorAndReturnFalse("options.optionValues.name");
86
+ }
87
+ if (firstOptionValues == null ? void 0 : firstOptionValues.firstSelectableVariant) {
88
+ validParam = checkProductVariantParam(
89
+ firstOptionValues.firstSelectableVariant,
90
+ "options.optionValues.firstSelectableVariant",
91
+ validParam,
92
+ checkAll
93
+ );
94
+ } else {
95
+ validParam = logErrorAndReturnFalse(
96
+ "options.optionValues.firstSelectableVariant"
97
+ );
98
+ }
99
+ } else {
100
+ validParam = logErrorAndReturnFalse("options.optionValues");
101
+ }
102
+ }
103
+ if (product.selectedOrFirstAvailableVariant) {
104
+ validParam = checkProductVariantParam(
105
+ product.selectedOrFirstAvailableVariant,
106
+ "selectedOrFirstAvailableVariant",
107
+ validParam,
108
+ checkAll
109
+ );
110
+ }
111
+ if (!!product.adjacentVariants && product.adjacentVariants[0]) {
112
+ validParam = checkProductVariantParam(
113
+ product.adjacentVariants[0],
114
+ "adjacentVariants",
115
+ validParam,
116
+ checkAll
117
+ );
118
+ }
119
+ return validParam ? product : {};
120
+ }
121
+ function checkProductVariantParam(variant, key, currentValidParamState, checkAll) {
122
+ var _a;
123
+ let validParam = currentValidParamState;
124
+ if (checkAll && !((_a = variant.product) == null ? void 0 : _a.handle)) {
125
+ validParam = logErrorAndReturnFalse(`${key}.product.handle`);
126
+ }
127
+ if (variant.selectedOptions) {
128
+ const firstSelectedOption = variant.selectedOptions[0];
129
+ if (!(firstSelectedOption == null ? void 0 : firstSelectedOption.name)) {
130
+ validParam = logErrorAndReturnFalse(`${key}.selectedOptions.name`);
131
+ }
132
+ if (!(firstSelectedOption == null ? void 0 : firstSelectedOption.value)) {
133
+ validParam = logErrorAndReturnFalse(`${key}.selectedOptions.value`);
134
+ }
135
+ } else {
136
+ validParam = logErrorAndReturnFalse(`${key}.selectedOptions`);
137
+ }
138
+ return validParam;
139
+ }
140
+ function getAdjacentAndFirstAvailableVariants(product) {
141
+ const checkedProduct = checkProductParam(product);
142
+ if (!checkedProduct.options)
143
+ return [];
144
+ const availableVariants = {};
145
+ checkedProduct.options.map((option) => {
146
+ var _a;
147
+ (_a = option.optionValues) == null ? void 0 : _a.map((value) => {
148
+ if (value.firstSelectableVariant) {
149
+ const variantKey = mapSelectedProductOptionToObjectAsString(
150
+ value.firstSelectableVariant.selectedOptions
151
+ );
152
+ availableVariants[variantKey] = value.firstSelectableVariant;
153
+ }
154
+ });
155
+ });
156
+ checkedProduct.adjacentVariants.map((variant) => {
157
+ const variantKey = mapSelectedProductOptionToObjectAsString(
158
+ variant.selectedOptions
159
+ );
160
+ availableVariants[variantKey] = variant;
161
+ });
162
+ const selectedVariant = checkedProduct.selectedOrFirstAvailableVariant;
163
+ if (selectedVariant) {
164
+ const variantKey = mapSelectedProductOptionToObjectAsString(
165
+ selectedVariant.selectedOptions
166
+ );
167
+ availableVariants[variantKey] = selectedVariant;
168
+ }
169
+ return Object.values(availableVariants);
170
+ }
171
+ function getProductOptions(product) {
172
+ const checkedProduct = checkProductParam(product, true);
173
+ if (!checkedProduct.options)
174
+ return [];
175
+ const {
176
+ options,
177
+ selectedOrFirstAvailableVariant: selectedVariant,
178
+ adjacentVariants,
179
+ encodedVariantExistence,
180
+ encodedVariantAvailability,
181
+ handle: productHandle
182
+ } = checkedProduct;
183
+ const productOptionMappings = mapProductOptions(options);
184
+ const variants = mapVariants(
185
+ selectedVariant ? [selectedVariant, ...adjacentVariants] : adjacentVariants,
186
+ productOptionMappings
187
+ );
188
+ const selectedOptions = mapSelectedProductOptionToObject(
189
+ selectedVariant ? selectedVariant.selectedOptions : []
190
+ );
191
+ const productOptions = options.map((option, optionIndex) => {
192
+ return {
193
+ ...option,
194
+ optionValues: option.optionValues.map((value) => {
195
+ var _a;
196
+ const targetOptionParams = { ...selectedOptions };
197
+ targetOptionParams[option.name] = value.name;
198
+ const targetKey = encodeSelectedProductOptionAsKey(
199
+ targetOptionParams || [],
200
+ productOptionMappings
201
+ );
202
+ const topDownKey = JSON.parse(targetKey).slice(
203
+ 0,
204
+ optionIndex + 1
205
+ );
206
+ const exists = optionValueDecoder.isOptionValueCombinationInEncodedVariant(
207
+ topDownKey,
208
+ encodedVariantExistence || ""
209
+ );
210
+ const available = optionValueDecoder.isOptionValueCombinationInEncodedVariant(
211
+ topDownKey,
212
+ encodedVariantAvailability || ""
213
+ );
214
+ const variant = variants[targetKey] || value.firstSelectableVariant;
215
+ const variantOptionParam = mapSelectedProductOptionToObject(
216
+ variant.selectedOptions || []
217
+ );
218
+ const searchParams = new URLSearchParams(variantOptionParam);
219
+ const handle = (_a = variant == null ? void 0 : variant.product) == null ? void 0 : _a.handle;
220
+ return {
221
+ ...value,
222
+ variant,
223
+ handle,
224
+ variantUriQuery: searchParams.toString(),
225
+ selected: selectedOptions[option.name] === value.name,
226
+ exists,
227
+ available,
228
+ isDifferentProduct: handle !== productHandle
229
+ };
230
+ })
231
+ };
232
+ });
233
+ return productOptions;
234
+ }
235
+ exports.checkProductParam = checkProductParam;
236
+ exports.getAdjacentAndFirstAvailableVariants = getAdjacentAndFirstAvailableVariants;
237
+ exports.getProductOptions = getProductOptions;
238
+ exports.mapSelectedProductOptionToObject = mapSelectedProductOptionToObject;
239
+ //# sourceMappingURL=getProductOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getProductOptions.js","sources":["../../src/getProductOptions.ts"],"sourcesContent":["import {isOptionValueCombinationInEncodedVariant} from './optionValueDecoder.js';\nimport type {\n Product,\n ProductOption,\n ProductOptionValue,\n ProductVariant,\n SelectedOption,\n} from './storefront-api-types';\n\nexport type RecursivePartial<T> = {\n [P in keyof T]?: RecursivePartial<T[P]>;\n};\ntype ProductOptionsMapping = Record<string, number>;\ntype ProductOptionValueState = {\n variant: ProductVariant;\n handle: string;\n variantUriQuery: string;\n selected: boolean;\n exists: boolean;\n available: boolean;\n isDifferentProduct: boolean;\n};\ntype MappedProductOptionValue = ProductOptionValue & ProductOptionValueState;\n\n/**\n * Creates a mapping of product options to their index for matching encoded values\n * For example, a product option of\n * [\n * \\{\n * name: 'Color',\n * optionValues: [\\{name: 'Red'\\}, \\{name: 'Blue'\\}]\n * \\},\n * \\{\n * name: 'Size',\n * optionValues: [\\{name: 'Small'\\}, \\{name: 'Medium'\\}, \\{name: 'Large'\\}]\n * \\}\n * ]\n * Would return\n * [\n * \\{Red: 0, Blue: 1\\},\n * \\{Small: 0, Medium: 1, Large: 2\\}\n * ]\n */\nfunction mapProductOptions(options: ProductOption[]): ProductOptionsMapping[] {\n return options.map((option: ProductOption) => {\n return Object.assign(\n {},\n ...(option?.optionValues\n ? option.optionValues.map((value, index) => {\n return {[value.name]: index};\n })\n : []),\n ) as ProductOptionsMapping;\n });\n}\n\n/**\n * Converts the product option into an Object\\<key, value\\> for building query params\n * For example, a selected product option of\n * [\n * \\{\n * name: 'Color',\n * value: 'Red',\n * \\},\n * \\{\n * name: 'Size',\n * value: 'Medium',\n * \\}\n * ]\n * Would return\n * \\{\n * Color: 'Red',\n * Size: 'Medium',\n * \\}\n */\nexport function mapSelectedProductOptionToObject(\n options: Pick<SelectedOption, 'name' | 'value'>[],\n): Record<string, string> {\n return Object.assign(\n {},\n ...options.map((key) => {\n return {[key.name]: key.value};\n }),\n ) as Record<string, string>;\n}\n\n/**\n * Returns the JSON stringify result of mapSelectedProductOptionToObject\n */\nfunction mapSelectedProductOptionToObjectAsString(\n options: Pick<SelectedOption, 'name' | 'value'>[],\n): string {\n return JSON.stringify(mapSelectedProductOptionToObject(options));\n}\n\n/**\n * Encode the selected product option as a key for mapping to the encoded variants\n * For example, a selected product option of\n * [\n * \\{\n * name: 'Color',\n * value: 'Red',\n * \\},\n * \\{\n * name: 'Size',\n * value: 'Medium',\n * \\}\n * ]\n * Would return\n * [0,1]\n *\n * Also works with the result of mapSelectedProductOption. For example:\n * \\{\n * Color: 'Red',\n * Size: 'Medium',\n * \\}\n * Would return\n * [0,1]\n *\n * @param selectedOption - The selected product option\n * @param productOptionMappings - The result of product option mapping from mapProductOptions\n * @returns\n */\nfunction encodeSelectedProductOptionAsKey(\n selectedOption:\n | Pick<SelectedOption, 'name' | 'value'>[]\n | Record<string, string>,\n productOptionMappings: ProductOptionsMapping[],\n): string {\n if (Array.isArray(selectedOption)) {\n return JSON.stringify(\n selectedOption.map((key, index) => {\n return productOptionMappings[index][key.value];\n }),\n );\n } else {\n return JSON.stringify(\n Object.keys(selectedOption).map((key, index) => {\n return productOptionMappings[index][selectedOption[key]];\n }),\n );\n }\n}\n\n/**\n * Takes an array of product variants and maps them to an object with the encoded selected option values as the key.\n * For example, a product variant of\n * [\n * \\{\n * id: 1,\n * selectedOptions: [\n * \\{name: 'Color', value: 'Red'\\},\n * \\{name: 'Size', value: 'Small'\\},\n * ],\n * \\},\n * \\{\n * id: 2,\n * selectedOptions: [\n * \\{name: 'Color', value: 'Red'\\},\n * \\{name: 'Size', value: 'Medium'\\},\n * ],\n * \\}\n * ]\n * Would return\n * \\{\n * '[0,0]': \\{id: 1, selectedOptions: [\\{name: 'Color', value: 'Red'\\}, \\{name: 'Size', value: 'Small'\\}]\\},\n * '[0,1]': \\{id: 2, selectedOptions: [\\{name: 'Color', value: 'Red'\\}, \\{name: 'Size', value: 'Medium'\\}]\\},\n * \\}\n */\nfunction mapVariants(\n variants: ProductVariant[],\n productOptionMappings: ProductOptionsMapping[],\n): Record<string, ProductVariant> {\n return Object.assign(\n {},\n ...variants.map((variant) => {\n const variantKey = encodeSelectedProductOptionAsKey(\n variant.selectedOptions || [],\n productOptionMappings,\n );\n return {[variantKey]: variant};\n }),\n ) as Record<string, ProductVariant>;\n}\n\nexport type MappedProductOptions = Omit<ProductOption, 'optionValues'> & {\n optionValues: MappedProductOptionValue[];\n};\n\nconst PRODUCT_INPUTS = [\n 'options',\n 'selectedOrFirstAvailableVariant',\n 'adjacentVariants',\n];\n\nconst PRODUCT_INPUTS_EXTRA = [\n 'handle',\n 'encodedVariantExistence',\n 'encodedVariantAvailability',\n];\n\nfunction logErrorAndReturnFalse(key: string): boolean {\n console.error(\n `[h2:error:getProductOptions] product.${key} is missing. Make sure you query for this field from the Storefront API.`,\n );\n return false;\n}\n\nexport function checkProductParam(\n product: RecursivePartial<Product>,\n checkAll = false,\n): Product {\n let validParam = true;\n const productKeys = Object.keys(product);\n\n // Check product input\n (checkAll\n ? [...PRODUCT_INPUTS, ...PRODUCT_INPUTS_EXTRA]\n : PRODUCT_INPUTS\n ).forEach((key) => {\n if (!productKeys.includes(key)) {\n validParam = logErrorAndReturnFalse(key);\n }\n });\n\n // Check for nested options requirements\n if (product.options) {\n const firstOption = product?.options[0];\n\n if (checkAll && !firstOption?.name) {\n validParam = logErrorAndReturnFalse('options.name');\n }\n\n // Check for options.optionValues\n if (product?.options[0]?.optionValues) {\n const firstOptionValues = product.options[0].optionValues[0];\n\n // Check for options.optionValues.name\n if (checkAll && !firstOptionValues?.name) {\n validParam = logErrorAndReturnFalse('options.optionValues.name');\n }\n\n // Check for options.optionValues.firstSelectableVariant\n if (firstOptionValues?.firstSelectableVariant) {\n // check product variant\n validParam = checkProductVariantParam(\n firstOptionValues.firstSelectableVariant,\n 'options.optionValues.firstSelectableVariant',\n validParam,\n checkAll,\n );\n } else {\n validParam = logErrorAndReturnFalse(\n 'options.optionValues.firstSelectableVariant',\n );\n }\n } else {\n validParam = logErrorAndReturnFalse('options.optionValues');\n }\n }\n\n // Check for nested selectedOrFirstAvailableVariant requirements\n if (product.selectedOrFirstAvailableVariant) {\n validParam = checkProductVariantParam(\n product.selectedOrFirstAvailableVariant,\n 'selectedOrFirstAvailableVariant',\n validParam,\n checkAll,\n );\n }\n\n // Check for nested adjacentVariants requirements\n if (!!product.adjacentVariants && product.adjacentVariants[0]) {\n validParam = checkProductVariantParam(\n product.adjacentVariants[0],\n 'adjacentVariants',\n validParam,\n checkAll,\n );\n }\n\n return (validParam ? product : {}) as Product;\n}\n\nfunction checkProductVariantParam(\n variant: RecursivePartial<ProductVariant>,\n key: string,\n currentValidParamState: boolean,\n checkAll: boolean,\n): boolean {\n let validParam = currentValidParamState;\n\n if (checkAll && !variant.product?.handle) {\n validParam = logErrorAndReturnFalse(`${key}.product.handle`);\n }\n if (variant.selectedOptions) {\n const firstSelectedOption = variant.selectedOptions[0];\n if (!firstSelectedOption?.name) {\n validParam = logErrorAndReturnFalse(`${key}.selectedOptions.name`);\n }\n if (!firstSelectedOption?.value) {\n validParam = logErrorAndReturnFalse(`${key}.selectedOptions.value`);\n }\n } else {\n validParam = logErrorAndReturnFalse(`${key}.selectedOptions`);\n }\n\n return validParam;\n}\n\n/**\n * Finds all the variants provided by adjacentVariants, options.optionValues.firstAvailableVariant,\n * and selectedOrFirstAvailableVariant and return them in a single array\n */\nexport function getAdjacentAndFirstAvailableVariants(\n product: RecursivePartial<Product>,\n): ProductVariant[] {\n // Checks for valid product input\n const checkedProduct = checkProductParam(product);\n\n if (!checkedProduct.options) return [];\n\n const availableVariants: Record<string, ProductVariant> = {};\n checkedProduct.options.map((option) => {\n option.optionValues?.map((value) => {\n if (value.firstSelectableVariant) {\n const variantKey = mapSelectedProductOptionToObjectAsString(\n value.firstSelectableVariant.selectedOptions,\n );\n availableVariants[variantKey] = value.firstSelectableVariant;\n }\n });\n });\n\n checkedProduct.adjacentVariants.map((variant) => {\n const variantKey = mapSelectedProductOptionToObjectAsString(\n variant.selectedOptions,\n );\n availableVariants[variantKey] = variant;\n });\n\n const selectedVariant = checkedProduct.selectedOrFirstAvailableVariant;\n if (selectedVariant) {\n const variantKey = mapSelectedProductOptionToObjectAsString(\n selectedVariant.selectedOptions,\n );\n availableVariants[variantKey] = selectedVariant;\n }\n\n return Object.values(availableVariants);\n}\n\n/**\n * Returns a product options array with its relevant information\n * about the variant\n */\nexport function getProductOptions(\n product: RecursivePartial<Product>,\n): MappedProductOptions[] {\n // Checks for valid product input\n const checkedProduct = checkProductParam(product, true);\n\n if (!checkedProduct.options) return [];\n\n const {\n options,\n selectedOrFirstAvailableVariant: selectedVariant,\n adjacentVariants,\n encodedVariantExistence,\n encodedVariantAvailability,\n handle: productHandle,\n } = checkedProduct;\n // Get a mapping of product option names to their index for matching encoded values\n const productOptionMappings = mapProductOptions(options);\n\n // Get the adjacent variants mapped to the encoded selected option values\n const variants = mapVariants(\n selectedVariant ? [selectedVariant, ...adjacentVariants] : adjacentVariants,\n productOptionMappings,\n );\n\n // Get the key:value version of selected options for building url query params\n const selectedOptions = mapSelectedProductOptionToObject(\n selectedVariant ? selectedVariant.selectedOptions : [],\n );\n\n const productOptions = options.map((option, optionIndex) => {\n return {\n ...option,\n optionValues: option.optionValues.map((value) => {\n const targetOptionParams = {...selectedOptions}; // Clones the selected options\n\n // Modify the selected option value to the current option value\n targetOptionParams[option.name] = value.name;\n\n // Encode the new selected option values as a key for mapping to the product variants\n const targetKey = encodeSelectedProductOptionAsKey(\n targetOptionParams || [],\n productOptionMappings,\n );\n\n // Top-down option check for existence and availability\n const topDownKey = (JSON.parse(targetKey) as number[]).slice(\n 0,\n optionIndex + 1,\n );\n const exists = isOptionValueCombinationInEncodedVariant(\n topDownKey,\n encodedVariantExistence || '',\n );\n const available = isOptionValueCombinationInEncodedVariant(\n topDownKey,\n encodedVariantAvailability || '',\n );\n\n // Get the variant for the current option value if exists, else use the first selectable variant\n const variant: ProductVariant =\n variants[targetKey] || value.firstSelectableVariant;\n\n // Build the query params for this option value\n const variantOptionParam = mapSelectedProductOptionToObject(\n variant.selectedOptions || [],\n );\n const searchParams = new URLSearchParams(variantOptionParam);\n const handle = variant?.product?.handle;\n\n return {\n ...value,\n variant,\n handle,\n variantUriQuery: searchParams.toString(),\n selected: selectedOptions[option.name] === value.name,\n exists,\n available,\n isDifferentProduct: handle !== productHandle,\n };\n }),\n };\n });\n\n return productOptions;\n}\n"],"names":["isOptionValueCombinationInEncodedVariant"],"mappings":"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"}
@@ -0,0 +1,239 @@
1
+ import { isOptionValueCombinationInEncodedVariant } from "./optionValueDecoder.mjs";
2
+ function mapProductOptions(options) {
3
+ return options.map((option) => {
4
+ return Object.assign(
5
+ {},
6
+ ...(option == null ? void 0 : option.optionValues) ? option.optionValues.map((value, index) => {
7
+ return { [value.name]: index };
8
+ }) : []
9
+ );
10
+ });
11
+ }
12
+ function mapSelectedProductOptionToObject(options) {
13
+ return Object.assign(
14
+ {},
15
+ ...options.map((key) => {
16
+ return { [key.name]: key.value };
17
+ })
18
+ );
19
+ }
20
+ function mapSelectedProductOptionToObjectAsString(options) {
21
+ return JSON.stringify(mapSelectedProductOptionToObject(options));
22
+ }
23
+ function encodeSelectedProductOptionAsKey(selectedOption, productOptionMappings) {
24
+ if (Array.isArray(selectedOption)) {
25
+ return JSON.stringify(
26
+ selectedOption.map((key, index) => {
27
+ return productOptionMappings[index][key.value];
28
+ })
29
+ );
30
+ } else {
31
+ return JSON.stringify(
32
+ Object.keys(selectedOption).map((key, index) => {
33
+ return productOptionMappings[index][selectedOption[key]];
34
+ })
35
+ );
36
+ }
37
+ }
38
+ function mapVariants(variants, productOptionMappings) {
39
+ return Object.assign(
40
+ {},
41
+ ...variants.map((variant) => {
42
+ const variantKey = encodeSelectedProductOptionAsKey(
43
+ variant.selectedOptions || [],
44
+ productOptionMappings
45
+ );
46
+ return { [variantKey]: variant };
47
+ })
48
+ );
49
+ }
50
+ const PRODUCT_INPUTS = [
51
+ "options",
52
+ "selectedOrFirstAvailableVariant",
53
+ "adjacentVariants"
54
+ ];
55
+ const PRODUCT_INPUTS_EXTRA = [
56
+ "handle",
57
+ "encodedVariantExistence",
58
+ "encodedVariantAvailability"
59
+ ];
60
+ function logErrorAndReturnFalse(key) {
61
+ console.error(
62
+ `[h2:error:getProductOptions] product.${key} is missing. Make sure you query for this field from the Storefront API.`
63
+ );
64
+ return false;
65
+ }
66
+ function checkProductParam(product, checkAll = false) {
67
+ var _a;
68
+ let validParam = true;
69
+ const productKeys = Object.keys(product);
70
+ (checkAll ? [...PRODUCT_INPUTS, ...PRODUCT_INPUTS_EXTRA] : PRODUCT_INPUTS).forEach((key) => {
71
+ if (!productKeys.includes(key)) {
72
+ validParam = logErrorAndReturnFalse(key);
73
+ }
74
+ });
75
+ if (product.options) {
76
+ const firstOption = product == null ? void 0 : product.options[0];
77
+ if (checkAll && !(firstOption == null ? void 0 : firstOption.name)) {
78
+ validParam = logErrorAndReturnFalse("options.name");
79
+ }
80
+ if ((_a = product == null ? void 0 : product.options[0]) == null ? void 0 : _a.optionValues) {
81
+ const firstOptionValues = product.options[0].optionValues[0];
82
+ if (checkAll && !(firstOptionValues == null ? void 0 : firstOptionValues.name)) {
83
+ validParam = logErrorAndReturnFalse("options.optionValues.name");
84
+ }
85
+ if (firstOptionValues == null ? void 0 : firstOptionValues.firstSelectableVariant) {
86
+ validParam = checkProductVariantParam(
87
+ firstOptionValues.firstSelectableVariant,
88
+ "options.optionValues.firstSelectableVariant",
89
+ validParam,
90
+ checkAll
91
+ );
92
+ } else {
93
+ validParam = logErrorAndReturnFalse(
94
+ "options.optionValues.firstSelectableVariant"
95
+ );
96
+ }
97
+ } else {
98
+ validParam = logErrorAndReturnFalse("options.optionValues");
99
+ }
100
+ }
101
+ if (product.selectedOrFirstAvailableVariant) {
102
+ validParam = checkProductVariantParam(
103
+ product.selectedOrFirstAvailableVariant,
104
+ "selectedOrFirstAvailableVariant",
105
+ validParam,
106
+ checkAll
107
+ );
108
+ }
109
+ if (!!product.adjacentVariants && product.adjacentVariants[0]) {
110
+ validParam = checkProductVariantParam(
111
+ product.adjacentVariants[0],
112
+ "adjacentVariants",
113
+ validParam,
114
+ checkAll
115
+ );
116
+ }
117
+ return validParam ? product : {};
118
+ }
119
+ function checkProductVariantParam(variant, key, currentValidParamState, checkAll) {
120
+ var _a;
121
+ let validParam = currentValidParamState;
122
+ if (checkAll && !((_a = variant.product) == null ? void 0 : _a.handle)) {
123
+ validParam = logErrorAndReturnFalse(`${key}.product.handle`);
124
+ }
125
+ if (variant.selectedOptions) {
126
+ const firstSelectedOption = variant.selectedOptions[0];
127
+ if (!(firstSelectedOption == null ? void 0 : firstSelectedOption.name)) {
128
+ validParam = logErrorAndReturnFalse(`${key}.selectedOptions.name`);
129
+ }
130
+ if (!(firstSelectedOption == null ? void 0 : firstSelectedOption.value)) {
131
+ validParam = logErrorAndReturnFalse(`${key}.selectedOptions.value`);
132
+ }
133
+ } else {
134
+ validParam = logErrorAndReturnFalse(`${key}.selectedOptions`);
135
+ }
136
+ return validParam;
137
+ }
138
+ function getAdjacentAndFirstAvailableVariants(product) {
139
+ const checkedProduct = checkProductParam(product);
140
+ if (!checkedProduct.options)
141
+ return [];
142
+ const availableVariants = {};
143
+ checkedProduct.options.map((option) => {
144
+ var _a;
145
+ (_a = option.optionValues) == null ? void 0 : _a.map((value) => {
146
+ if (value.firstSelectableVariant) {
147
+ const variantKey = mapSelectedProductOptionToObjectAsString(
148
+ value.firstSelectableVariant.selectedOptions
149
+ );
150
+ availableVariants[variantKey] = value.firstSelectableVariant;
151
+ }
152
+ });
153
+ });
154
+ checkedProduct.adjacentVariants.map((variant) => {
155
+ const variantKey = mapSelectedProductOptionToObjectAsString(
156
+ variant.selectedOptions
157
+ );
158
+ availableVariants[variantKey] = variant;
159
+ });
160
+ const selectedVariant = checkedProduct.selectedOrFirstAvailableVariant;
161
+ if (selectedVariant) {
162
+ const variantKey = mapSelectedProductOptionToObjectAsString(
163
+ selectedVariant.selectedOptions
164
+ );
165
+ availableVariants[variantKey] = selectedVariant;
166
+ }
167
+ return Object.values(availableVariants);
168
+ }
169
+ function getProductOptions(product) {
170
+ const checkedProduct = checkProductParam(product, true);
171
+ if (!checkedProduct.options)
172
+ return [];
173
+ const {
174
+ options,
175
+ selectedOrFirstAvailableVariant: selectedVariant,
176
+ adjacentVariants,
177
+ encodedVariantExistence,
178
+ encodedVariantAvailability,
179
+ handle: productHandle
180
+ } = checkedProduct;
181
+ const productOptionMappings = mapProductOptions(options);
182
+ const variants = mapVariants(
183
+ selectedVariant ? [selectedVariant, ...adjacentVariants] : adjacentVariants,
184
+ productOptionMappings
185
+ );
186
+ const selectedOptions = mapSelectedProductOptionToObject(
187
+ selectedVariant ? selectedVariant.selectedOptions : []
188
+ );
189
+ const productOptions = options.map((option, optionIndex) => {
190
+ return {
191
+ ...option,
192
+ optionValues: option.optionValues.map((value) => {
193
+ var _a;
194
+ const targetOptionParams = { ...selectedOptions };
195
+ targetOptionParams[option.name] = value.name;
196
+ const targetKey = encodeSelectedProductOptionAsKey(
197
+ targetOptionParams || [],
198
+ productOptionMappings
199
+ );
200
+ const topDownKey = JSON.parse(targetKey).slice(
201
+ 0,
202
+ optionIndex + 1
203
+ );
204
+ const exists = isOptionValueCombinationInEncodedVariant(
205
+ topDownKey,
206
+ encodedVariantExistence || ""
207
+ );
208
+ const available = isOptionValueCombinationInEncodedVariant(
209
+ topDownKey,
210
+ encodedVariantAvailability || ""
211
+ );
212
+ const variant = variants[targetKey] || value.firstSelectableVariant;
213
+ const variantOptionParam = mapSelectedProductOptionToObject(
214
+ variant.selectedOptions || []
215
+ );
216
+ const searchParams = new URLSearchParams(variantOptionParam);
217
+ const handle = (_a = variant == null ? void 0 : variant.product) == null ? void 0 : _a.handle;
218
+ return {
219
+ ...value,
220
+ variant,
221
+ handle,
222
+ variantUriQuery: searchParams.toString(),
223
+ selected: selectedOptions[option.name] === value.name,
224
+ exists,
225
+ available,
226
+ isDifferentProduct: handle !== productHandle
227
+ };
228
+ })
229
+ };
230
+ });
231
+ return productOptions;
232
+ }
233
+ export {
234
+ checkProductParam,
235
+ getAdjacentAndFirstAvailableVariants,
236
+ getProductOptions,
237
+ mapSelectedProductOptionToObject
238
+ };
239
+ //# sourceMappingURL=getProductOptions.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getProductOptions.mjs","sources":["../../src/getProductOptions.ts"],"sourcesContent":["import {isOptionValueCombinationInEncodedVariant} from './optionValueDecoder.js';\nimport type {\n Product,\n ProductOption,\n ProductOptionValue,\n ProductVariant,\n SelectedOption,\n} from './storefront-api-types';\n\nexport type RecursivePartial<T> = {\n [P in keyof T]?: RecursivePartial<T[P]>;\n};\ntype ProductOptionsMapping = Record<string, number>;\ntype ProductOptionValueState = {\n variant: ProductVariant;\n handle: string;\n variantUriQuery: string;\n selected: boolean;\n exists: boolean;\n available: boolean;\n isDifferentProduct: boolean;\n};\ntype MappedProductOptionValue = ProductOptionValue & ProductOptionValueState;\n\n/**\n * Creates a mapping of product options to their index for matching encoded values\n * For example, a product option of\n * [\n * \\{\n * name: 'Color',\n * optionValues: [\\{name: 'Red'\\}, \\{name: 'Blue'\\}]\n * \\},\n * \\{\n * name: 'Size',\n * optionValues: [\\{name: 'Small'\\}, \\{name: 'Medium'\\}, \\{name: 'Large'\\}]\n * \\}\n * ]\n * Would return\n * [\n * \\{Red: 0, Blue: 1\\},\n * \\{Small: 0, Medium: 1, Large: 2\\}\n * ]\n */\nfunction mapProductOptions(options: ProductOption[]): ProductOptionsMapping[] {\n return options.map((option: ProductOption) => {\n return Object.assign(\n {},\n ...(option?.optionValues\n ? option.optionValues.map((value, index) => {\n return {[value.name]: index};\n })\n : []),\n ) as ProductOptionsMapping;\n });\n}\n\n/**\n * Converts the product option into an Object\\<key, value\\> for building query params\n * For example, a selected product option of\n * [\n * \\{\n * name: 'Color',\n * value: 'Red',\n * \\},\n * \\{\n * name: 'Size',\n * value: 'Medium',\n * \\}\n * ]\n * Would return\n * \\{\n * Color: 'Red',\n * Size: 'Medium',\n * \\}\n */\nexport function mapSelectedProductOptionToObject(\n options: Pick<SelectedOption, 'name' | 'value'>[],\n): Record<string, string> {\n return Object.assign(\n {},\n ...options.map((key) => {\n return {[key.name]: key.value};\n }),\n ) as Record<string, string>;\n}\n\n/**\n * Returns the JSON stringify result of mapSelectedProductOptionToObject\n */\nfunction mapSelectedProductOptionToObjectAsString(\n options: Pick<SelectedOption, 'name' | 'value'>[],\n): string {\n return JSON.stringify(mapSelectedProductOptionToObject(options));\n}\n\n/**\n * Encode the selected product option as a key for mapping to the encoded variants\n * For example, a selected product option of\n * [\n * \\{\n * name: 'Color',\n * value: 'Red',\n * \\},\n * \\{\n * name: 'Size',\n * value: 'Medium',\n * \\}\n * ]\n * Would return\n * [0,1]\n *\n * Also works with the result of mapSelectedProductOption. For example:\n * \\{\n * Color: 'Red',\n * Size: 'Medium',\n * \\}\n * Would return\n * [0,1]\n *\n * @param selectedOption - The selected product option\n * @param productOptionMappings - The result of product option mapping from mapProductOptions\n * @returns\n */\nfunction encodeSelectedProductOptionAsKey(\n selectedOption:\n | Pick<SelectedOption, 'name' | 'value'>[]\n | Record<string, string>,\n productOptionMappings: ProductOptionsMapping[],\n): string {\n if (Array.isArray(selectedOption)) {\n return JSON.stringify(\n selectedOption.map((key, index) => {\n return productOptionMappings[index][key.value];\n }),\n );\n } else {\n return JSON.stringify(\n Object.keys(selectedOption).map((key, index) => {\n return productOptionMappings[index][selectedOption[key]];\n }),\n );\n }\n}\n\n/**\n * Takes an array of product variants and maps them to an object with the encoded selected option values as the key.\n * For example, a product variant of\n * [\n * \\{\n * id: 1,\n * selectedOptions: [\n * \\{name: 'Color', value: 'Red'\\},\n * \\{name: 'Size', value: 'Small'\\},\n * ],\n * \\},\n * \\{\n * id: 2,\n * selectedOptions: [\n * \\{name: 'Color', value: 'Red'\\},\n * \\{name: 'Size', value: 'Medium'\\},\n * ],\n * \\}\n * ]\n * Would return\n * \\{\n * '[0,0]': \\{id: 1, selectedOptions: [\\{name: 'Color', value: 'Red'\\}, \\{name: 'Size', value: 'Small'\\}]\\},\n * '[0,1]': \\{id: 2, selectedOptions: [\\{name: 'Color', value: 'Red'\\}, \\{name: 'Size', value: 'Medium'\\}]\\},\n * \\}\n */\nfunction mapVariants(\n variants: ProductVariant[],\n productOptionMappings: ProductOptionsMapping[],\n): Record<string, ProductVariant> {\n return Object.assign(\n {},\n ...variants.map((variant) => {\n const variantKey = encodeSelectedProductOptionAsKey(\n variant.selectedOptions || [],\n productOptionMappings,\n );\n return {[variantKey]: variant};\n }),\n ) as Record<string, ProductVariant>;\n}\n\nexport type MappedProductOptions = Omit<ProductOption, 'optionValues'> & {\n optionValues: MappedProductOptionValue[];\n};\n\nconst PRODUCT_INPUTS = [\n 'options',\n 'selectedOrFirstAvailableVariant',\n 'adjacentVariants',\n];\n\nconst PRODUCT_INPUTS_EXTRA = [\n 'handle',\n 'encodedVariantExistence',\n 'encodedVariantAvailability',\n];\n\nfunction logErrorAndReturnFalse(key: string): boolean {\n console.error(\n `[h2:error:getProductOptions] product.${key} is missing. Make sure you query for this field from the Storefront API.`,\n );\n return false;\n}\n\nexport function checkProductParam(\n product: RecursivePartial<Product>,\n checkAll = false,\n): Product {\n let validParam = true;\n const productKeys = Object.keys(product);\n\n // Check product input\n (checkAll\n ? [...PRODUCT_INPUTS, ...PRODUCT_INPUTS_EXTRA]\n : PRODUCT_INPUTS\n ).forEach((key) => {\n if (!productKeys.includes(key)) {\n validParam = logErrorAndReturnFalse(key);\n }\n });\n\n // Check for nested options requirements\n if (product.options) {\n const firstOption = product?.options[0];\n\n if (checkAll && !firstOption?.name) {\n validParam = logErrorAndReturnFalse('options.name');\n }\n\n // Check for options.optionValues\n if (product?.options[0]?.optionValues) {\n const firstOptionValues = product.options[0].optionValues[0];\n\n // Check for options.optionValues.name\n if (checkAll && !firstOptionValues?.name) {\n validParam = logErrorAndReturnFalse('options.optionValues.name');\n }\n\n // Check for options.optionValues.firstSelectableVariant\n if (firstOptionValues?.firstSelectableVariant) {\n // check product variant\n validParam = checkProductVariantParam(\n firstOptionValues.firstSelectableVariant,\n 'options.optionValues.firstSelectableVariant',\n validParam,\n checkAll,\n );\n } else {\n validParam = logErrorAndReturnFalse(\n 'options.optionValues.firstSelectableVariant',\n );\n }\n } else {\n validParam = logErrorAndReturnFalse('options.optionValues');\n }\n }\n\n // Check for nested selectedOrFirstAvailableVariant requirements\n if (product.selectedOrFirstAvailableVariant) {\n validParam = checkProductVariantParam(\n product.selectedOrFirstAvailableVariant,\n 'selectedOrFirstAvailableVariant',\n validParam,\n checkAll,\n );\n }\n\n // Check for nested adjacentVariants requirements\n if (!!product.adjacentVariants && product.adjacentVariants[0]) {\n validParam = checkProductVariantParam(\n product.adjacentVariants[0],\n 'adjacentVariants',\n validParam,\n checkAll,\n );\n }\n\n return (validParam ? product : {}) as Product;\n}\n\nfunction checkProductVariantParam(\n variant: RecursivePartial<ProductVariant>,\n key: string,\n currentValidParamState: boolean,\n checkAll: boolean,\n): boolean {\n let validParam = currentValidParamState;\n\n if (checkAll && !variant.product?.handle) {\n validParam = logErrorAndReturnFalse(`${key}.product.handle`);\n }\n if (variant.selectedOptions) {\n const firstSelectedOption = variant.selectedOptions[0];\n if (!firstSelectedOption?.name) {\n validParam = logErrorAndReturnFalse(`${key}.selectedOptions.name`);\n }\n if (!firstSelectedOption?.value) {\n validParam = logErrorAndReturnFalse(`${key}.selectedOptions.value`);\n }\n } else {\n validParam = logErrorAndReturnFalse(`${key}.selectedOptions`);\n }\n\n return validParam;\n}\n\n/**\n * Finds all the variants provided by adjacentVariants, options.optionValues.firstAvailableVariant,\n * and selectedOrFirstAvailableVariant and return them in a single array\n */\nexport function getAdjacentAndFirstAvailableVariants(\n product: RecursivePartial<Product>,\n): ProductVariant[] {\n // Checks for valid product input\n const checkedProduct = checkProductParam(product);\n\n if (!checkedProduct.options) return [];\n\n const availableVariants: Record<string, ProductVariant> = {};\n checkedProduct.options.map((option) => {\n option.optionValues?.map((value) => {\n if (value.firstSelectableVariant) {\n const variantKey = mapSelectedProductOptionToObjectAsString(\n value.firstSelectableVariant.selectedOptions,\n );\n availableVariants[variantKey] = value.firstSelectableVariant;\n }\n });\n });\n\n checkedProduct.adjacentVariants.map((variant) => {\n const variantKey = mapSelectedProductOptionToObjectAsString(\n variant.selectedOptions,\n );\n availableVariants[variantKey] = variant;\n });\n\n const selectedVariant = checkedProduct.selectedOrFirstAvailableVariant;\n if (selectedVariant) {\n const variantKey = mapSelectedProductOptionToObjectAsString(\n selectedVariant.selectedOptions,\n );\n availableVariants[variantKey] = selectedVariant;\n }\n\n return Object.values(availableVariants);\n}\n\n/**\n * Returns a product options array with its relevant information\n * about the variant\n */\nexport function getProductOptions(\n product: RecursivePartial<Product>,\n): MappedProductOptions[] {\n // Checks for valid product input\n const checkedProduct = checkProductParam(product, true);\n\n if (!checkedProduct.options) return [];\n\n const {\n options,\n selectedOrFirstAvailableVariant: selectedVariant,\n adjacentVariants,\n encodedVariantExistence,\n encodedVariantAvailability,\n handle: productHandle,\n } = checkedProduct;\n // Get a mapping of product option names to their index for matching encoded values\n const productOptionMappings = mapProductOptions(options);\n\n // Get the adjacent variants mapped to the encoded selected option values\n const variants = mapVariants(\n selectedVariant ? [selectedVariant, ...adjacentVariants] : adjacentVariants,\n productOptionMappings,\n );\n\n // Get the key:value version of selected options for building url query params\n const selectedOptions = mapSelectedProductOptionToObject(\n selectedVariant ? selectedVariant.selectedOptions : [],\n );\n\n const productOptions = options.map((option, optionIndex) => {\n return {\n ...option,\n optionValues: option.optionValues.map((value) => {\n const targetOptionParams = {...selectedOptions}; // Clones the selected options\n\n // Modify the selected option value to the current option value\n targetOptionParams[option.name] = value.name;\n\n // Encode the new selected option values as a key for mapping to the product variants\n const targetKey = encodeSelectedProductOptionAsKey(\n targetOptionParams || [],\n productOptionMappings,\n );\n\n // Top-down option check for existence and availability\n const topDownKey = (JSON.parse(targetKey) as number[]).slice(\n 0,\n optionIndex + 1,\n );\n const exists = isOptionValueCombinationInEncodedVariant(\n topDownKey,\n encodedVariantExistence || '',\n );\n const available = isOptionValueCombinationInEncodedVariant(\n topDownKey,\n encodedVariantAvailability || '',\n );\n\n // Get the variant for the current option value if exists, else use the first selectable variant\n const variant: ProductVariant =\n variants[targetKey] || value.firstSelectableVariant;\n\n // Build the query params for this option value\n const variantOptionParam = mapSelectedProductOptionToObject(\n variant.selectedOptions || [],\n );\n const searchParams = new URLSearchParams(variantOptionParam);\n const handle = variant?.product?.handle;\n\n return {\n ...value,\n variant,\n handle,\n variantUriQuery: searchParams.toString(),\n selected: selectedOptions[option.name] === value.name,\n exists,\n available,\n isDifferentProduct: handle !== productHandle,\n };\n }),\n };\n });\n\n return productOptions;\n}\n"],"names":[],"mappings":"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"}
@@ -16,11 +16,13 @@ const codegen_helpers = require("./codegen.helpers.js");
16
16
  const cookiesUtils = require("./cookies-utils.js");
17
17
  const ExternalVideo = require("./ExternalVideo.js");
18
18
  const flattenConnection = require("./flatten-connection.js");
19
+ const getProductOptions = require("./getProductOptions.js");
19
20
  const Image = require("./Image.js");
20
21
  const loadScript = require("./load-script.js");
21
22
  const MediaFile = require("./MediaFile.js");
22
23
  const ModelViewer = require("./ModelViewer.js");
23
24
  const Money = require("./Money.js");
25
+ const optionValueDecoder = require("./optionValueDecoder.js");
24
26
  const parseMetafield = require("./parse-metafield.js");
25
27
  const ProductPrice = require("./ProductPrice.js");
26
28
  const ProductProvider = require("./ProductProvider.js");
@@ -29,6 +31,7 @@ const ShopifyProvider = require("./ShopifyProvider.js");
29
31
  const ShopPayButton = require("./ShopPayButton.js");
30
32
  const storefrontClient = require("./storefront-client.js");
31
33
  const useMoney = require("./useMoney.js");
34
+ const useSelectedOptionInUrlParam = require("./useSelectedOptionInUrlParam.js");
32
35
  const useShopifyCookies = require("./useShopifyCookies.js");
33
36
  const Video = require("./Video.js");
34
37
  exports.AddToCartButton = AddToCartButton.AddToCartButton;
@@ -57,12 +60,17 @@ exports.storefrontApiCustomScalars = codegen_helpers.storefrontApiCustomScalars;
57
60
  exports.getShopifyCookies = cookiesUtils.getShopifyCookies;
58
61
  exports.ExternalVideo = ExternalVideo.ExternalVideo;
59
62
  exports.flattenConnection = flattenConnection.flattenConnection;
63
+ exports.getAdjacentAndFirstAvailableVariants = getProductOptions.getAdjacentAndFirstAvailableVariants;
64
+ exports.getProductOptions = getProductOptions.getProductOptions;
65
+ exports.mapSelectedProductOptionToObject = getProductOptions.mapSelectedProductOptionToObject;
60
66
  exports.IMAGE_FRAGMENT = Image.IMAGE_FRAGMENT;
61
67
  exports.Image = Image.Image;
62
68
  exports.useLoadScript = loadScript.useLoadScript;
63
69
  exports.MediaFile = MediaFile.MediaFile;
64
70
  exports.ModelViewer = ModelViewer.ModelViewer;
65
71
  exports.Money = Money.Money;
72
+ exports.decodeEncodedVariant = optionValueDecoder.decodeEncodedVariant;
73
+ exports.isOptionValueCombinationInEncodedVariant = optionValueDecoder.isOptionValueCombinationInEncodedVariant;
66
74
  exports.parseMetafield = parseMetafield.parseMetafield;
67
75
  exports.ProductPrice = ProductPrice.ProductPrice;
68
76
  exports.ProductProvider = ProductProvider.ProductProvider;
@@ -73,6 +81,7 @@ exports.useShop = ShopifyProvider.useShop;
73
81
  exports.ShopPayButton = ShopPayButton.ShopPayButton;
74
82
  exports.createStorefrontClient = storefrontClient.createStorefrontClient;
75
83
  exports.useMoney = useMoney.useMoney;
84
+ exports.useSelectedOptionInUrlParam = useSelectedOptionInUrlParam.useSelectedOptionInUrlParam;
76
85
  exports.useShopifyCookies = useShopifyCookies.useShopifyCookies;
77
86
  exports.Video = Video.Video;
78
87
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -14,11 +14,13 @@ import { customerAccountApiCustomScalars, storefrontApiCustomScalars } from "./c
14
14
  import { getShopifyCookies } from "./cookies-utils.mjs";
15
15
  import { ExternalVideo } from "./ExternalVideo.mjs";
16
16
  import { flattenConnection } from "./flatten-connection.mjs";
17
+ import { getAdjacentAndFirstAvailableVariants, getProductOptions, mapSelectedProductOptionToObject } from "./getProductOptions.mjs";
17
18
  import { IMAGE_FRAGMENT, Image } from "./Image.mjs";
18
19
  import { useLoadScript } from "./load-script.mjs";
19
20
  import { MediaFile } from "./MediaFile.mjs";
20
21
  import { ModelViewer } from "./ModelViewer.mjs";
21
22
  import { Money } from "./Money.mjs";
23
+ import { decodeEncodedVariant, isOptionValueCombinationInEncodedVariant } from "./optionValueDecoder.mjs";
22
24
  import { parseMetafield } from "./parse-metafield.mjs";
23
25
  import { ProductPrice } from "./ProductPrice.mjs";
24
26
  import { ProductProvider, useProduct } from "./ProductProvider.mjs";
@@ -27,6 +29,7 @@ import { ShopifyProvider, useShop } from "./ShopifyProvider.mjs";
27
29
  import { ShopPayButton } from "./ShopPayButton.mjs";
28
30
  import { createStorefrontClient } from "./storefront-client.mjs";
29
31
  import { useMoney } from "./useMoney.mjs";
32
+ import { useSelectedOptionInUrlParam } from "./useSelectedOptionInUrlParam.mjs";
30
33
  import { useShopifyCookies } from "./useShopifyCookies.mjs";
31
34
  import { Video } from "./Video.mjs";
32
35
  export {
@@ -60,9 +63,14 @@ export {
60
63
  Video,
61
64
  createStorefrontClient,
62
65
  customerAccountApiCustomScalars,
66
+ decodeEncodedVariant,
63
67
  flattenConnection,
68
+ getAdjacentAndFirstAvailableVariants,
64
69
  getClientBrowserParameters,
70
+ getProductOptions,
65
71
  getShopifyCookies,
72
+ isOptionValueCombinationInEncodedVariant,
73
+ mapSelectedProductOptionToObject,
66
74
  parseGid,
67
75
  parseMetafield,
68
76
  sendShopifyAnalytics,
@@ -72,6 +80,7 @@ export {
72
80
  useLoadScript,
73
81
  useMoney,
74
82
  useProduct,
83
+ useSelectedOptionInUrlParam,
75
84
  useShop,
76
85
  useShopifyCookies
77
86
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}