Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@skava/graphql / src / endpoints / catalog / stream / transform.ts
Size: Mime:
import { toBoolean, toNumber, isObj, isSafe, isEmpty } from 'exotic'
// import { autofixSafe as autofix } from 'exotic-core'
import { uuid } from '@skava/modules/___dist/identifier'
import { getTyped } from '@skava/modules/___dist/composition'
// import {reshape} from 'deps'
// import {schema, remap} from 'server/endpoints/catalog'
// const camelKeys = ['categoryIds', 'additionalInfo', 'productFilter', 'selectedFilters']
// const transform = data => {
//   return reshape
//     .setSchema(schema)
//     .setRemap(remap)
//     .remapKeys(camelKeys)
//     .transformn(data)
// }
// @curry2

const clientSideSorting = {
  isProductSorted: false,
  sortedValue: '',
}

const toAdditional = response => {
  const { array } = getTyped(response)
  // random stupid Type
  const info = array('properties.iteminfo.additionalinfo')
  // specifications
  const additionalproperties = array('properties.iteminfo.additionalproperties')
  const stateAdditionalProperties = array(
    'properties.state.additionalproperties'
  )
  return [...info, ...additionalproperties, ...stateAdditionalProperties]
}

const fromValueToAlwaysUniq = value => {
  value.identifier = value.identifier + uuid()
  return value
}
const fromLabel = name => {
  let label = name
  if (name === 'Friendly Color') {
    label = 'Color'
  }

  return label
}
const appendCurrencyCode = value => {
  value.name = '$' + value.name
  return value
}
const fromFacetToAlwaysUniq = facet => {
  let values = ''
  // should be value
  const oldvalues = facet.values.map(fromValueToAlwaysUniq)
  // const identifier = facet.identifier || name + uuid()
  if (facet.name === 'salePrice') {
    values = oldvalues.map(appendCurrencyCode)
  } else {
    values = oldvalues
  }
  if (facet.name === 'Color') {
    return undefined
  }
  const name = fromLabel(facet.name)
  // @todo careful to ensure selected identifier isn't the same as the name
  // if (name === 'Friendly Color') {
  //   name = 'Color'
  // }

  return { name, values }
}

const isValidProduct = (product = {}) => {
  const { image, name, identifier } = product
  const isValid = isSafe(image && name && identifier)
  return isValid
}

const getPriceValue = properties => {
  const { array } = getTyped(properties)
  const prices = array('properties.buyinfo.pricing.prices')
  const sortPrice = prices.find(item => {
    if (item.type.toLowerCase() === 'sale') {
      return item
    }
    return toNumber(sortPrice.value)
  })
}

const sortSkus = skus => {
  if (clientSideSorting.isProductSorted) {
    const isAscendingSort = clientSideSorting.sortedValue.includes('Price|asc')

    skus.sort(function(item1, item2) {
      const item1Price = getPriceValue(item1)
      const item2Price = getPriceValue(item2)

      if (isAscendingSort) {
        return parseFloat(item1Price) - item2Price
      } else {
        return parseFloat(item2Price) - item1Price
      }
    })
    return skus
  } else {
    return skus
  }
}

const toProductChildren = (children = {}) => {
  const { array } = getTyped(children)
  const { skus, ...remainingData } = children

  const validSkus = array('skus').filter(isValidProduct)
  const sortedSkus = sortSkus(validSkus)

  return {
    skus: sortedSkus,
    ...remainingData,
  }
}

const toProduct = product => {
  const validProduct = isValidProduct(product) ? product : {}
  const { array } = getTyped(validProduct)
  const { children, ...remainingData } = validProduct
  return {
    ...remainingData,
    children: toProductChildren(children),
    specifications: array('properties.iteminfo.specifications'),
    additional: toAdditional(product),
  }
}

const transformCatalogResponse = response => {
  const { array, string, number } = getTyped(response)
  // TODO - remove this once price  is rendered in call
  const facetValue = array('facets')
    .map(fromFacetToAlwaysUniq)
    .filter(isSafe)
  // facetValue.push({
  //   name: 'Price',
  //   values: [
  //     {
  //       identifier: '0-50',
  //       name: '0-50',
  //       count: '15',
  //     },
  //     {
  //       identifier: '50-100',
  //       name: '50-100',
  //       count: '15',
  //     },
  //     {
  //       identifier: '100-150',
  //       name: '100-150',
  //       count: '4',
  //     },
  //     {
  //       identifier: '200-350',
  //       name: '200-250',
  //       count: '15',
  //     },
  //   ],
  // })

  const catalogResponse = {
    identifier: string('identifier'),
    // navtype: string('navtype'),
    image: string('image'),
    name: string('name'),
    link: string('link'),

    additional: toAdditional(response),

    // useless
    // additionalInfo: getArray('properties.iteminfo.additionalinfo'),

    categoryIds: array('properties.iteminfo.categoryids').reverse(),

    /**
     * @todo - could take refine out of the response here
     */
    productFilter: {
      facets: facetValue,
      selectedFilters: array('properties.state.selectedFacets'),
    },
    productSort: {
      options: array('properties.state.sorting.0.options'),
      sortedBy:
        string('properties.state.sorting.0.selectedname') || 'Relevance',
    },

    // .map(remapProduct), @see /products
    products: array('children.products').map(toProduct),
    productCount: number('properties.state.productcount'),
    searchterm: string('properties.state.searchterm'),
  }
  return catalogResponse
}

// @todo hack till API fixes sort SKREACT-4968
const checkIsProductSorted = dynamicParams => {
  const { sort } = dynamicParams
  const sortValue = sort

  if (isSafe(sort) && !isEmpty(sort)) {
    clientSideSorting.isProductSorted = true
    clientSideSorting.sortedValue = sortValue
  }
}

const transformCatalog = (response, dynamicParams) => {
  checkIsProductSorted(dynamicParams)
  const data = transformCatalogResponse(response)
  const isSortedItem = false
  // return autofix(data)
  return data
}

const toTabProductItem = product => {
  const url = `/product/${product.identifier}`
  return {
    ...product,
    url,
  }
}

/**
 * basically reformatted plp
 * with {meta, values} as {title url viewall products}
 */
const transformCatalogTab = (response, tabName, attribute) => {
  // THIS IS DONE ON GRAPHQL (FACEPALM)
  // const transformed = transformCatalogResponse(response)
  // console.log('transformCatalogTab', { response, transformed })

  const {
    children: { products },
    identifier,
    name,
    link,
    image,
  } = response
  const url = '/category/' + identifier
  const meta = {
    title: tabName || name || 'unknown',
    url,
    image,
    // @todo this would be parent categories?
    viewAll: url,
    qa: attribute,
  }
  const oneThing = {
    // meh @todo @fixme on spread
    ...meta,
    meta,
    values: products.map(toTabProductItem),
  }
  return oneThing
}

export { toProduct, toProduct as transformProduct }
export { transformCatalog, transformCatalogTab }
export default transformCatalog