You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							80 lines
						
					
					
						
							1.8 KiB
						
					
					
				
			
		
		
	
	
							80 lines
						
					
					
						
							1.8 KiB
						
					
					
				'use strict'
 | 
						|
 | 
						|
function negotiate (header, supportedEncodings) {
 | 
						|
  if (!header) {
 | 
						|
    return undefined
 | 
						|
  }
 | 
						|
  const supportedEncodingMap = createMap(supportedEncodings)
 | 
						|
  const acceptedEncodings = parse(header)
 | 
						|
    .sort((a, b) => comparator(a, b, supportedEncodingMap))
 | 
						|
    .filter(isNonZeroQuality)
 | 
						|
  return determinePreffered(acceptedEncodings, supportedEncodingMap)
 | 
						|
}
 | 
						|
 | 
						|
function determinePreffered (acceptedEncodings, supportedEncodings) {
 | 
						|
  for (const encoding of acceptedEncodings) {
 | 
						|
    const selected = supportedEncodings[encoding.name]
 | 
						|
    if (selected) {
 | 
						|
      return selected.encoding
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return null
 | 
						|
}
 | 
						|
 | 
						|
function createMap (supported) {
 | 
						|
  const supportedEncodings = {}
 | 
						|
  let priority = 0
 | 
						|
  if (supported.length > 0) {
 | 
						|
    supportedEncodings['*'] = { encoding: supported[0], priority }
 | 
						|
    priority++
 | 
						|
  }
 | 
						|
  for (const encoding of supported) {
 | 
						|
    supportedEncodings[encoding] = { encoding, priority }
 | 
						|
    priority++
 | 
						|
  }
 | 
						|
  return supportedEncodings
 | 
						|
}
 | 
						|
 | 
						|
function parse (header) {
 | 
						|
  const split = header.split(',')
 | 
						|
  return split.map(parseEncoding)
 | 
						|
}
 | 
						|
 | 
						|
function isNonZeroQuality (encoding) {
 | 
						|
  return encoding.quality !== 0
 | 
						|
}
 | 
						|
 | 
						|
function parseEncoding (encoding) {
 | 
						|
  const [name, second] = encoding.trim().split(';')
 | 
						|
  const quality = getQuality(second)
 | 
						|
  return {
 | 
						|
    name,
 | 
						|
    quality
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function getQuality (second) {
 | 
						|
  if (!second) {
 | 
						|
    return 1
 | 
						|
  }
 | 
						|
  const [, quality] = second.trim().split('=')
 | 
						|
  return parseFloat(quality)
 | 
						|
}
 | 
						|
 | 
						|
function comparator (a, b, supportedEncodingMap) {
 | 
						|
  if (a.quality === b.quality) {
 | 
						|
    if (supportedEncodingMap[a.name] &&
 | 
						|
      supportedEncodingMap[b.name] &&
 | 
						|
      supportedEncodingMap[a.name].priority < supportedEncodingMap[b.name].priority) {
 | 
						|
      return -1
 | 
						|
    } else {
 | 
						|
      return 1
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return b.quality - a.quality
 | 
						|
}
 | 
						|
 | 
						|
module.exports = {
 | 
						|
  negotiate
 | 
						|
}
 |