lib/mapping/index.js
function mapping ({
  filters,
  transformers,
  schemas = {},
  mappings: mappingsArr = []
} = {}) {
  const mappings = mappingsArr.reduce(
    (mappings, def) => ({ ...mappings, [def.id]: def }),
    {}
  )
  const createPipelineFn = createPipeline(filters, transformers, schemas, mappings)

  return (mapping, overrideType) => {
    const { id, type, schema, pipeline } = createPipelineFn(mapping, overrideType)
    if (!pipeline) {
      return null
    }

    const mapper = mapTransform([
      fwd('data'),
      ...pipeline,
      rev(set('data'))
    ])

    return {
      id,
      type,
      schema,

      /**
       * Map data from a service with attributes and relationships.
       * @param {Object} data - The service item to map from
       * @param {Object} options - onlyMappedValues
       * @returns {Object} Target item
       */
      fromService (data, { onlyMappedValues = true } = {}) {
        return data
          ? ensureArray(
            (onlyMappedValues) ? mapper.onlyMappedValues(data) : mapper(data)
          )
          : []
      },

      /**
       * Map data to a service with attributes and relationships.
       * @param {Object} data - The data item to map
       * @param {Object} target - Optional object to map to data on
       * @returns {Object} Mapped data
       */
      toService (data, target = null) {
        const mapped = mapper.rev.onlyMappedValues(data)
        return (
          (target
            ? Array.isArray(target)
              ? [...target].concat(mapped)
              : mergeDeepWith(concatOrRight, target, mapped)
            : mapped) || null
        )
      }
    }
  }
}
function mapping ({
  filters,
  transformers,
  schemas = {},
  mappings: mappingsArr = []
} = {}) {
  const mappings = mappingsArr.reduce(
    (mappings, def) => ({ ...mappings, [def.id]: def }),
    {}
  )
  const createPipelineFn = createPipeline(filters, transformers, schemas, mappings)

  return (mapping, overrideType) => {
    const { id, type, schema, pipeline } = createPipelineFn(mapping, overrideType)
    if (!pipeline) {
      return null
    }

    const mapper = mapTransform([
      fwd('data'),
      ...pipeline,
      rev(set('data'))
    ])

    return {
      id,
      type,
      schema,

      /**
       * Map data from a service with attributes and relationships.
       * @param {Object} data - The service item to map from
       * @param {Object} options - onlyMappedValues
       * @returns {Object} Target item
       */
      fromService (data, { onlyMappedValues = true } = {}) {
        return data
          ? ensureArray(
            (onlyMappedValues) ? mapper.onlyMappedValues(data) : mapper(data)
          )
          : []
      },

      /**
       * Map data to a service with attributes and relationships.
       * @param {Object} data - The data item to map
       * @param {Object} target - Optional object to map to data on
       * @returns {Object} Mapped data
       */
      toService (data, target = null) {
        const mapped = mapper.rev.onlyMappedValues(data)
        return (
          (target
            ? Array.isArray(target)
              ? [...target].concat(mapped)
              : mergeDeepWith(concatOrRight, target, mapped)
            : mapped) || null
        )
      }
    }
  }
}
Return item mapper object with fromService and toService.
@param {Object} resources - filters, transformers, and schemas
@returns {Object} Item mapping def