New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

object-path-immutable

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

object-path-immutable - npm Package Compare versions

Comparing version 1.0.3 to 2.0.0

CHANGELOG.md

400

index.js

@@ -1,254 +0,260 @@

/* globals define */
var deepmerge = require('deepmerge')
var _hasOwnProperty = Object.prototype.hasOwnProperty
(function (root, factory) {
'use strict'
/* istanbul ignore next:cant test */
if (typeof module === 'object' && typeof module.exports === 'object') {
module.exports = factory()
} else if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], factory)
} else {
// Browser globals
root.objectPath = factory()
function isEmpty (value) {
if (isNumber(value)) {
return false
}
})(this, function () {
'use strict'
var _hasOwnProperty = Object.prototype.hasOwnProperty
function isEmpty (value) {
if (isNumber(value)) {
return false
}
if (!value) {
return true
}
if (isArray(value) && value.length === 0) {
return true
} else if (!isString(value)) {
for (var i in value) {
if (_hasOwnProperty.call(value, i)) {
return false
}
if (!value) {
return true
}
if (isArray(value) && value.length === 0) {
return true
} else if (!isString(value)) {
for (var i in value) {
if (_hasOwnProperty.call(value, i)) {
return false
}
return true
}
return false
return true
}
return false
}
function isNumber (value) {
return typeof value === 'number'
}
function isNumber (value) {
return typeof value === 'number'
}
function isString (obj) {
return typeof obj === 'string'
}
function isString (obj) {
return typeof obj === 'string'
}
function isArray (obj) {
return Array.isArray(obj)
}
function isArray (obj) {
return Array.isArray(obj)
}
function assignToObj (target, source) {
for (var key in source) {
if (_hasOwnProperty.call(source, key)) {
target[key] = source[key]
}
function assignToObj (target, source) {
for (var key in source) {
if (_hasOwnProperty.call(source, key)) {
target[key] = source[key]
}
return target
}
return target
}
function getKey (key) {
var intKey = parseInt(key)
if (intKey.toString() === key) {
return intKey
}
return key
function getKey (key) {
var intKey = parseInt(key)
if (intKey.toString() === key) {
return intKey
}
return key
}
var objectPathImmutable = function (src) {
var dest = src
var committed = false
function overwriteMerge (destinationArray, sourceArray) {
return sourceArray
}
var transaction = Object.keys(api).reduce(function (proxy, prop) {
/* istanbul ignore else */
if (typeof api[prop] === 'function') {
proxy[prop] = function () {
var args = [dest, src].concat(Array.prototype.slice.call(arguments))
var objectPathImmutable = function (src) {
var dest = src
var committed = false
if (committed) {
throw new Error('Cannot call ' + prop + ' after `value`')
}
var transaction = Object.keys(api).reduce(function (proxy, prop) {
/* istanbul ignore else */
if (typeof api[prop] === 'function') {
proxy[prop] = function () {
var args = [dest, src].concat(Array.prototype.slice.call(arguments))
dest = api[prop].apply(null, args)
return transaction
if (committed) {
throw new Error('Cannot call ' + prop + ' after `value`')
}
}
return proxy
}, {})
dest = api[prop].apply(null, args)
transaction.value = function () {
committed = true
return dest
return transaction
}
}
return transaction
return proxy
}, {})
transaction.value = function () {
committed = true
return dest
}
function clone (obj, createIfEmpty, assumeArray) {
if (obj == null) {
if (createIfEmpty) {
if (assumeArray) {
return []
}
return transaction
}
return {}
function clone (obj, createIfEmpty, assumeArray) {
if (obj == null) {
if (createIfEmpty) {
if (assumeArray) {
return []
}
return obj
} else if (isArray(obj)) {
return obj.slice()
return {}
}
return assignToObj({}, obj)
return obj
} else if (isArray(obj)) {
return obj.slice()
}
function changeImmutable (dest, src, path, changeCallback) {
if (isNumber(path)) {
path = [path]
}
if (isEmpty(path)) {
return src
}
if (isString(path)) {
return changeImmutable(dest, src, path.split('.').map(getKey), changeCallback)
}
var currentPath = path[0]
return assignToObj({}, obj)
}
if (!dest || dest === src) {
dest = clone(src, true, isNumber(currentPath))
}
function changeImmutable (dest, src, path, changeCallback) {
if (isNumber(path)) {
path = [path]
}
if (isEmpty(path)) {
return src
}
if (isString(path)) {
return changeImmutable(dest, src, path.split('.').map(getKey), changeCallback)
}
var currentPath = path[0]
if (path.length === 1) {
return changeCallback(dest, currentPath)
}
if (!dest || dest === src) {
dest = clone(src, true, isNumber(currentPath))
}
if (src != null) {
src = src[currentPath]
}
if (path.length === 1) {
return changeCallback(dest, currentPath)
}
dest[currentPath] = changeImmutable(dest[currentPath], src, path.slice(1), changeCallback)
if (src != null) {
src = src[currentPath]
}
return dest
dest[currentPath] = changeImmutable(dest[currentPath], src, path.slice(1), changeCallback)
return dest
}
var api = {}
api.set = function set (dest, src, path, value) {
if (isEmpty(path)) {
return value
}
return changeImmutable(dest, src, path, function (clonedObj, finalPath) {
clonedObj[finalPath] = value
return clonedObj
})
}
var api = {}
api.set = function set (dest, src, path, value) {
if (isEmpty(path)) {
return value
}
return changeImmutable(dest, src, path, function (clonedObj, finalPath) {
clonedObj[finalPath] = value
return clonedObj
})
api.update = function update (dest, src, path, updater) {
if (isEmpty(path)) {
return updater(clone(src))
}
return changeImmutable(dest, src, path, function (clonedObj, finalPath) {
clonedObj[finalPath] = updater(clonedObj[finalPath])
return clonedObj
})
}
api.update = function update (dest, src, path, updater) {
if (isEmpty(path)) {
return updater(clone(src))
api.push = function push (dest, src, path /*, values */) {
var values = Array.prototype.slice.call(arguments, 3)
if (isEmpty(path)) {
if (!isArray(src)) {
return values
} else {
return src.concat(values)
}
return changeImmutable(dest, src, path, function (clonedObj, finalPath) {
clonedObj[finalPath] = updater(clonedObj[finalPath])
return clonedObj
})
}
return changeImmutable(dest, src, path, function (clonedObj, finalPath) {
if (!isArray(clonedObj[finalPath])) {
clonedObj[finalPath] = values
} else {
clonedObj[finalPath] = clonedObj[finalPath].concat(values)
}
return clonedObj
})
}
api.push = function push (dest, src, path /*, values */) {
var values = Array.prototype.slice.call(arguments, 3)
if (isEmpty(path)) {
if (!isArray(src)) {
return values
} else {
return src.concat(values)
}
api.insert = function insert (dest, src, path, value, at) {
at = ~~at
if (isEmpty(path)) {
if (!isArray(src)) {
return [value]
}
return changeImmutable(dest, src, path, function (clonedObj, finalPath) {
if (!isArray(clonedObj[finalPath])) {
clonedObj[finalPath] = values
} else {
clonedObj[finalPath] = clonedObj[finalPath].concat(values)
}
return clonedObj
})
var first = src.slice(0, at)
first.push(value)
return first.concat(src.slice(at))
}
api.insert = function insert (dest, src, path, value, at) {
at = ~~at
if (isEmpty(path)) {
if (!isArray(src)) {
return [value]
return changeImmutable(dest, src, path, function (clonedObj, finalPath) {
var arr = clonedObj[finalPath]
if (!isArray(arr)) {
if (arr != null && typeof arr !== 'undefined') {
throw new Error('Expected ' + path + 'to be an array. Instead got ' + typeof path)
}
var first = src.slice(0, at)
first.push(value)
return first.concat(src.slice(at))
arr = []
}
return changeImmutable(dest, src, path, function (clonedObj, finalPath) {
var arr = clonedObj[finalPath]
if (!isArray(arr)) {
if (arr != null && typeof arr !== 'undefined') {
throw new Error('Expected ' + path + 'to be an array. Instead got ' + typeof path)
}
arr = []
}
var first = arr.slice(0, at)
first.push(value)
clonedObj[finalPath] = first.concat(arr.slice(at))
return clonedObj
})
var first = arr.slice(0, at)
first.push(value)
clonedObj[finalPath] = first.concat(arr.slice(at))
return clonedObj
})
}
api.del = function del (dest, src, path) {
if (isEmpty(path)) {
return void 0
}
return changeImmutable(dest, src, path, function (clonedObj, finalPath) {
if (Array.isArray(clonedObj)) {
if (clonedObj[finalPath] !== undefined) {
clonedObj.splice(finalPath, 1)
}
} else {
if (clonedObj.hasOwnProperty(finalPath)) {
delete clonedObj[finalPath]
}
}
return clonedObj
})
}
api.del = function del (dest, src, path) {
if (isEmpty(path)) {
return void 0
api.assign = function assign (dest, src, path, source) {
if (isEmpty(path)) {
if (isEmpty(source)) {
return src
}
return changeImmutable(dest, src, path, function (clonedObj, finalPath) {
if (Array.isArray(clonedObj)) {
if (clonedObj[finalPath] !== undefined) {
clonedObj.splice(finalPath, 1)
}
} else {
if (clonedObj.hasOwnProperty(finalPath)) {
delete clonedObj[finalPath]
}
}
return clonedObj
})
return assignToObj(clone(src), source)
}
return changeImmutable(dest, src, path, function (clonedObj, finalPath) {
source = Object(source)
var target = clone(clonedObj[finalPath], true)
assignToObj(target, source)
api.assign = function assign (dest, src, path, source) {
if (isEmpty(path)) {
if (isEmpty(source)) {
return src
}
return assignToObj(clone(src), source)
}
return changeImmutable(dest, src, path, function (clonedObj, finalPath) {
source = Object(source)
var target = clone(clonedObj[finalPath], true)
assignToObj(target, source)
clonedObj[finalPath] = target
return clonedObj
})
}
clonedObj[finalPath] = target
return clonedObj
})
api.merge = function assign (dest, src, path, source, options) {
options = options || {}
if (options.arrayMerge === void 0) {
options.arrayMerge = overwriteMerge
}
return Object.keys(api).reduce(function (objectPathImmutable, method) {
objectPathImmutable[method] = api[method].bind(null, null)
if (isEmpty(path)) {
if (isEmpty(source)) {
return src
}
return deepmerge(src, source, options)
}
return changeImmutable(dest, src, path, function (clonedObj, finalPath) {
source = Object(source)
clonedObj[finalPath] = deepmerge(clonedObj[finalPath], source, options)
return clonedObj
})
}
return objectPathImmutable
}, objectPathImmutable)
})
module.exports = Object.keys(api).reduce(function (objectPathImmutable, method) {
objectPathImmutable[method] = api[method].bind(null, null)
return objectPathImmutable
}, objectPathImmutable)
{
"name": "object-path-immutable",
"version": "1.0.3",
"version": "2.0.0",
"description": "Modify deep object properties without modifying the original object (immutability). Works great with React and Redux.",
"author": "Mario Casciaro <mariocasciaro@gmail.com>",
"author": "Mario Casciaro <m@mario.fyi>",
"homepage": "https://github.com/mariocasciaro/object-path-immutable",

@@ -15,8 +15,12 @@ "repository": {

},
"main": "index.js",
"scripts": {
"build": "rollup -c",
"pretest": "standard",
"test": "istanbul cover _mocha test.js --report html -- -R spec",
"test": "npm run build && istanbul cover _mocha test.js --report html -- -R spec",
"prepublish": "npm run test"
},
"dependencies": {},
"dependencies": {
"deepmerge": "^2.1.1"
},
"devDependencies": {

@@ -28,2 +32,5 @@ "chai": "^3.5.0",

"mocha-lcov-reporter": "^1.2.0",
"rollup": "^0.61.1",
"rollup-plugin-commonjs": "^9.1.3",
"rollup-plugin-node-resolve": "^3.3.0",
"standard": "^8.3.0"

@@ -51,3 +58,8 @@ },

"state"
]
],
"standard": {
"ignore": [
"dist"
]
}
}

@@ -17,12 +17,4 @@ [![build](https://img.shields.io/travis/mariocasciaro/object-path-immutable.svg?style=flat-square)](https://travis-ci.org/mariocasciaro/object-path-immutable)

### 1.0
[View Changelog](CHANGELOG.md)
- **Breaking change**: The way the library handles empty paths has changed. Before this change,all the methods were returning the original object. The new behavior is as follows.
- `set(src, path, value)`: `value` is returned
- `update(src, path, updater)`: `value` will be passed to `updater()` and the result returned
- `set(src, path, ...values)`: `values` will be concatenated to `src` if `src` is an array, otherwise `values` will be returned
- `insert(src, path, value, at)`: if `src` is an array then it will be cloned and `value` will be inserted at `at`, otherwise `[value]` will be returned
- `del(src, path)`: returns `undefined`
- `assign(src, path, target)`: Target is assigned to a clone of `src` and returned
## Install

@@ -118,4 +110,4 @@

a: {
b: 1,
},
b: 1
}
}

@@ -147,3 +139,3 @@

#### delete (initialObject, path)
#### del (initialObject, path)

@@ -173,3 +165,3 @@ Deletes a property.

##### assign (initialObject, path, payload)
#### assign (initialObject, path, payload)

@@ -189,3 +181,3 @@ Shallow copy properties.

##### insert (initialObject, path, payload, position)
#### insert (initialObject, path, payload, position)

@@ -204,2 +196,15 @@ Insert property at the specific array index.

#### merge (initialObject, path, value, options)
Deep merge properties. Uses the `deepmarge` package.
One thing to notice is that `object-path-immutable` overwrites arrays by default
instead of concatenating them. You can change this behavior by passing the `arrayMerge`
option to `merge`. Please refer to the [deepmerge documentation](https://github.com/KyleAMathews/deepmerge)
for the details.
```javascript
const newObj = immutable.merge(obj, 'a.c', {b: 'd'})
```
### Equivalent library with side effects

@@ -209,4 +214,1 @@

### Credits
* [Mario Casciaro](https://github.com/mariocasciaro) - Author

@@ -6,3 +6,3 @@ /* globals describe, it */

var expect = require('chai').expect
var op = require('./index.js')
var op = require('./')

@@ -405,2 +405,86 @@ describe('set', function () {

describe('merge', function () {
it('should merge an object without modifying the original object', function () {
var obj = {
a: {
b: 1
},
c: {
d: 2
}
}
var newObj = op.merge(obj, 'a', {b: 3})
expect(newObj).not.to.be.equal(obj)
expect(newObj.a).not.to.be.equal(obj.a)
expect(obj.a).to.be.eql({b: 1})
expect(newObj.c).to.be.equal(obj.c)
expect(newObj.a.b).to.be.equal(3)
})
it('should properly merge objects', function () {
var obj = {
a: {
b: 1,
c: {
d: 2,
e: 3
}
}
}
var newObj = op.merge(obj, 'a', {c: {e: 4}})
expect(newObj).not.to.be.equal(obj)
expect(newObj.a).not.to.be.equal(obj.a)
expect(obj.a.b).to.be.eql(1)
expect(newObj.a.c).to.be.eql({
d: 2,
e: 4
})
})
it('should not merge arrays by default', function () {
var obj = {
a: {
b: 1,
c: {
d: 2,
e: [1]
}
}
}
var newObj = op.merge(obj, 'a', {c: {e: [2]}})
expect(obj.a.b).to.be.eql(1)
expect(newObj.a.c).to.be.eql({
d: 2,
e: [2]
})
})
it('should not merge objects without a path', function () {
var obj = {
a: {
b: 1,
c: {
d: 2,
e: [1]
}
}
}
var newObj = op.merge(obj, null, {a: {c: {e: [2]}}})
expect(obj.a.b).to.be.eql(1)
expect(newObj.a.c).to.be.eql({
d: 2,
e: [2]
})
})
})
describe('bind', function () {

@@ -407,0 +491,0 @@ it('should execute all methods on the bound object', function () {

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc