es2015/object-store/utils.js
function getFieldPaths(object, stopOnKeyRange = true) {
  let fieldPaths = []
  fieldPaths.containsKeyRange = false
  generateFieldPaths(object, [])

  return fieldPaths

  function generateFieldPaths(object, parts) {
    Object.keys(object).some((fieldName) => {
      let value = object[fieldName]
      if (stopOnKeyRange && (value instanceof IDBKeyRange)) {
        fieldPaths = null
        return true
      }

      let isTerminalValue =
          !(value instanceof Object) ||
          (value instanceof Date) ||
          (value instanceof Array) ||
          (value instanceof IDBKeyRange)
      let fieldPath = parts.slice()
      fieldPath.push(fieldName)

      if (isTerminalValue) {
        fieldPaths.push(fieldPath.join("."))
      } else {
        generateFieldPaths(value, fieldPath)
      }
    })
  }
}
function getFieldPaths(object, stopOnKeyRange = true) {
  let fieldPaths = []
  fieldPaths.containsKeyRange = false
  generateFieldPaths(object, [])

  return fieldPaths

  function generateFieldPaths(object, parts) {
    Object.keys(object).some((fieldName) => {
      let value = object[fieldName]
      if (stopOnKeyRange && (value instanceof IDBKeyRange)) {
        fieldPaths = null
        return true
      }

      let isTerminalValue =
          !(value instanceof Object) ||
          (value instanceof Date) ||
          (value instanceof Array) ||
          (value instanceof IDBKeyRange)
      let fieldPath = parts.slice()
      fieldPath.push(fieldName)

      if (isTerminalValue) {
        fieldPaths.push(fieldPath.join("."))
      } else {
        generateFieldPaths(value, fieldPath)
      }
    })
  }
}
Generates an array containing all field paths in the provided object.

The method also tests whether any of the leaf field values is an
{@linkcode IDBKeyRange} instance, in such case the method returns
{@code null}.

The method is used to determine whether the provided object can be turned
into and {@linkcode IDBKeyRange} instance for a compound record key, and if
so, retrieve all field paths in the object so that its structure can be
validated against the field paths of the storage.

@param {Object} object The object from which the field paths are to be
extracted.
@param {boolean=} stopOnKeyRange When {@code true}, the method returns
{@code null} if it encounters a key range.
@return {?string[]} All field paths in the provided objects, unless the
object contains a field set to an {@linkcode IDBKeyRange} instance.