es2015/object-store/query-engine.js
function prepareOrderingSpecificationForQuery(order, keyPath) {
  if (order === null) {
    order = CursorDirection.NEXT
  }
  
  let isCursorDirection = ((typeof order === "string") &&
      (CURSOR_DIRECTIONS.indexOf(order.toUpperCase()) > -1)) ||
      (CURSOR_DIRECTIONS.indexOf(order) > -1)
  if (isCursorDirection && (typeof order === "string")) {
    order = CursorDirection[order.toUpperCase()] || CursorDirection.PREVIOUS
  }
  
  if (order instanceof CursorDirection) {
    keyPath = normalizeKeyPath(keyPath)
    
    if (order === CursorDirection.NEXT) {
      return keyPath
    } else {
      return keyPath.map(fieldPath => `!${fieldPath}`)
    }
  }
  
  return order
}
function prepareOrderingSpecificationForQuery(order, keyPath) {
  if (order === null) {
    order = CursorDirection.NEXT
  }
  
  let isCursorDirection = ((typeof order === "string") &&
      (CURSOR_DIRECTIONS.indexOf(order.toUpperCase()) > -1)) ||
      (CURSOR_DIRECTIONS.indexOf(order) > -1)
  if (isCursorDirection && (typeof order === "string")) {
    order = CursorDirection[order.toUpperCase()] || CursorDirection.PREVIOUS
  }
  
  if (order instanceof CursorDirection) {
    keyPath = normalizeKeyPath(keyPath)
    
    if (order === CursorDirection.NEXT) {
      return keyPath
    } else {
      return keyPath.map(fieldPath => `!${fieldPath}`)
    }
  }
  
  return order
}
Preprocess the raw ordering specification into form that can be used in
query optimization.

@param {?(CursorDirection|string|string[]|function(*, *): number)} order How
the resulting records should be sorted. This can be one of the
following:
- a {@code CursorDirection} constant, either {@code NEXT} or
{@code PREVIOUS} for ascending or descending order respectively
- {@code null} as alias for {@code CursorDirection.NEXT}
- one of the {@code "NEXT"} (alias for {@code CursorDirection.NEXT}),
{@code "PREVIOUS"} or {@code "PREV"} (aliases for
{@code CursorDirection.PREVIOUS})
- a string containing a field path, meaning the records should be
sorted by the values of the denoted field (note that the field
must exist in all records and its value must be a valid IndexedDB
key value).
The order is ascending by default, use the {@code "!" prefix} for
descending order.
To sort by a field named {@code NEXT}, {@code PREVIOUS} or
{@code PREV} wrap the field path into an array containing the field
path.
- an array of field paths, as described above. The records will be
sorted by the values of the specified fields lexicographically.
- a comparator function compatible with the
{@linkcode Array.prototype.sort} method.
@param {(string|string[])} keyPath The key path of this object store.
@return {(string[]|function(*, *): number)} Prepared ordering specification
ready to be used in query optimization.