{"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, 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 *    'Color': \\{Red: 0, Blue: 1\\},\n *    'Size': \\{Small: 0, Medium: 1, Large: 2\\}\n *  \\}\n */\nfunction mapProductOptions(options: ProductOption[]): ProductOptionsMapping {\n  return Object.assign(\n    {},\n    ...options.map((option: ProductOption) => {\n      return {\n        [option.name]: Object.assign(\n          {},\n          ...(option?.optionValues\n            ? option.optionValues.map((value, index) => {\n                return {[value.name]: index};\n              })\n            : []),\n        ),\n      } as Record<string, number>;\n    }),\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 *  JSON.stringify(\\{\n *    Color: 'Red',\n *    Size: 'Medium',\n *  \\})\n */\nfunction encodeSelectedProductOptionAsKey(\n  selectedOption:\n    | Pick<SelectedOption, 'name' | 'value'>[]\n    | Record<string, string>,\n): string {\n  if (Array.isArray(selectedOption)) {\n    return JSON.stringify(\n      Object.assign(\n        {},\n        ...selectedOption.map((option) => ({[option.name]: option.value})),\n      ),\n    );\n  } else {\n    return JSON.stringify(selectedOption);\n  }\n}\n\n/**\n * Build the encoding array for the given selected options. For example, if we have\n * the following productOptionMappings:\n *\n *  \\{\n *    'Color': \\{Red: 0, Blue: 1\\},\n *    'Size': \\{Small: 0, Medium: 1, Large: 2\\}\n *  \\}\n *\n * A selectedOption of\n *\n * \\{\n *    Color: 'Red',\n *    Size: 'Medium',\n * \\}\n *\n * `buildEncodingArrayFromSelectedOptions` will produce\n *\n * [0,1]\n *\n * If in the case where a selected option doesn't exists in the mapping array, for example:\n *\n * \\{\n *    Color: 'Red',\n *    Fabric: 'Cotton',\n *    Size: 'Medium',\n * \\}\n *\n * `buildEncodingArrayFromSelectedOptions` will still produce\n *\n *  [0,1]\n *\n * This can be caused by when we do not have all the product\n * option information for the loading optimistic variant\n */\nfunction buildEncodingArrayFromSelectedOptions(\n  selectedOption: Record<string, string>,\n  productOptionMappings: ProductOptionsMapping,\n): Array<number> {\n  const encoding = Object.keys(selectedOption).map((key) => {\n    return productOptionMappings[key]\n      ? productOptionMappings[key][selectedOption[key]]\n      : null;\n  });\n  return encoding.filter((code) => code !== null);\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): Record<string, ProductVariant> {\n  return Object.assign(\n    {},\n    ...variants.map((variant) => {\n      const variantKey = encodeSelectedProductOptionAsKey(\n        variant.selectedOptions || [],\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      let 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      // It is possible for firstSelectableVariant to be null\n      firstOptionValues = product.options[0].optionValues.filter(\n        (value) => !!value?.firstSelectableVariant,\n      )[0];\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      }\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\n  // The available product options is dictated by the selected options of the current variant:\n  // Filter out un-used options (Happens on parent combined listing product)\n  const selectedOptionKeys = selectedVariant?.selectedOptions.map(\n    (option) => option.name,\n  );\n  const filteredOptions = options.filter((option) => {\n    return selectedOptionKeys && selectedOptionKeys.indexOf(option.name) >= 0;\n  });\n\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  );\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 = filteredOptions.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        );\n        const encodingKey = buildEncodingArrayFromSelectedOptions(\n          targetOptionParams || [],\n          productOptionMappings,\n        );\n\n        // Top-down option check for existence and availability\n        const topDownKey = encodingKey.slice(0, optionIndex + 1);\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        let variantOptionParam = {};\n        if (variant) {\n          variantOptionParam = mapSelectedProductOptionToObject(\n            variant.selectedOptions || [],\n          );\n        }\n        const searchParams = new URLSearchParams(variantOptionParam);\n        const handle = variant?.product?.handle || productHandle;\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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"}