util/UsingWrapper.js

  1. import * as array from '../array'
  2. import * as collection from '../collection'
  3. import * as lang from '../lang'
  4. import * as math from '../math'
  5. import * as object from '../object'
  6. import at from 'lodash/at'
  7. import concat from 'lodash/concat'
  8. import map from 'lodash/map'
  9. import mapValues from 'lodash/mapValues'
  10. import omit from 'lodash/omit'
  11. import toPath from 'lodash/toPath'
  12. import { updatePassingArgs } from '../object/update'
  13. /**
  14. * Wrapper allowing to specify one or several paths to use as arguments for an immutadot function call.<br/>
  15. * Instances are created by calling {@link object.using}.
  16. * @memberof util
  17. * @see {@link object.using} for more information.
  18. * @private
  19. * @since 0.1.12
  20. */
  21. class UsingWrapper {
  22. /**
  23. * This constructor should not be called directly.<br/>
  24. * Instances are created by calling {@link object.using}.
  25. * @param {...(Array|string)} paths The paths to use as arguments.
  26. * @see {@link object.using} for more information.
  27. * @since 0.1.12
  28. */
  29. constructor(...paths) {
  30. this._paths = map(paths, toPath)
  31. }
  32. /**
  33. * Call a function with the specified arguments and possibly some more arguments.
  34. * @param {function} fn The function to call.
  35. * @param {Object} object The object to modify.
  36. * @param {Array|string} path The path of the property to be set.
  37. * @param {...*} args The arguments for the function call.
  38. * @return {Object} Returns the updated object.
  39. * @since 0.1.12
  40. */
  41. _call(fn, object, path, args) {
  42. return fn(object, path, ...concat(at(object, this._paths), args))
  43. }
  44. }
  45. // Add namespaces functions to the UsingWrapper prototype
  46. [
  47. array,
  48. collection,
  49. {
  50. ...omit(object, ['unset']), // Unset doesn't take any parameters
  51. update: updatePassingArgs, // Avoid updater only version of update
  52. },
  53. lang,
  54. math,
  55. object,
  56. ].forEach(namespace => Object.assign(
  57. UsingWrapper.prototype,
  58. mapValues(
  59. namespace,
  60. fn => function(object, path, ...args) {
  61. return this._call(fn, object, path, args) // eslint-disable-line no-invalid-this
  62. }
  63. )
  64. ))
  65. export default UsingWrapper