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    
chain-able-deps / src / util / props.ts
Size: Mime:
import NON_ENUMERABLE from '../native/NON_ENUMERABLE'
import { isSymbol } from '../is'
import uniq from '../array/uniq'
import concatMutate from '../array/concatMutate'
import keys from './keys'

const getOwnPropertyNames = Object.getOwnPropertyNames
const getOwnPropertySymbols = Object.getOwnPropertySymbols

/**
 * @todo @@perf
 */
function forProto(obj, fn, max = 11) {
  let current = obj
  let index = 0

  // would be result for `mapProto`
  // let result = []
  while ((current = Object.getPrototypeOf(current))) {
    if (index++ > max) break
    fn(current, index)
  }
  // return result
}

/**
 * @desc properties, property symbols, object keys
 *       ^ all again for prototype
 * @memberOf util
 * @since 3.0.0
 * @version 5.0.0-beta.4 only used in gc (as of 5.0.0-beta.4)
 *
 * @param  obj object to get properties & symbols from
 * @return properties
 *
 * @see deps/gc
 * @see deps/utils/nonEnumerableTypes
 * @see http://2ality.com/2011/07/js-properties.html
 * @TODO https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors
 * `const getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors`
 *
 * @example
 *    var obj = {key: true}
 *    allProperties(obj)
 *    //=> ['key']
 *
 * @example
 *    class One {
 *      method() {}
 *    }
 *    class Two extends One {
 *      eh() {}
 *    }
 *    allProperties(new Two())
 *    //=> ['eh', 'method']
 *
 */
function allProperties(obj: any): Array<string | symbol> {
  return (getOwnPropertyNames(obj) as Array<string | symbol>)
    .concat(getOwnPropertySymbols(obj))
    .concat(keys(obj))

  // .concat(keys(obj)) ?

  // const result = []
  // for (const prop in obj) result.push(prop)
  // return result

  // flatten(getOwnPropertyNames, getOwnPropertySymbols)
  // const proto = getPrototypeOf(obj)
  // return [].concat(
  //   getOwnPropertyNames(obj),
  //   getOwnPropertySymbols(obj)
  //   // ObjectKeys(obj),
  //   // proto ? allProperties(proto) : []
  // )
}

// @TODO @HACK @FIXME - needs to be in another file
const NON_ASSIGNABLE = NON_ENUMERABLE.concat(['length', 'name'])

function walkAllProperties(obj, max = 1) {
  let props = allProperties(obj)
  forProto(obj, proto => concatMutate(props, allProperties(proto)), max)
  return props.filter(key => !NON_ASSIGNABLE.includes(key as any)).filter(uniq)
}

const BUILT_IN_METHODS = NON_ASSIGNABLE.concat(['apply', 'bind', 'call'])
const BUILT_IN_FILTER = key => {
  return (
    !BUILT_IN_METHODS.includes(key) &&
    !isSymbol(key) &&
    (key && !key.startsWith('$'))
  )
}

function walkAllCustomProperties(obj, max = 1) {
  let props = allProperties(obj)
  // const iteratee = proto => {
  //   props = props.concat(allProperties(proto))
  // }
  // forProto(obj, iteratee, max)

  return props.filter(BUILT_IN_FILTER).filter(uniq)
}

export default walkAllCustomProperties