Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

set-value

Package Overview
Dependencies
Maintainers
2
Versions
25
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

set-value - npm Package Compare versions

Comparing version 3.0.2 to 4.0.0

198

index.js
/*!
* set-value <https://github.com/jonschlinkert/set-value>
*
* Copyright (c) 2014-2018, Jon Schlinkert.
* Copyright (c) Jon Schlinkert (https://github.com/jonschlinkert).
* Released under the MIT License.

@@ -10,102 +10,154 @@ */

const isPlain = require('is-plain-object');
const isPlainObject = require('is-plain-object');
function set(target, path, value, options) {
if (!isObject(target)) {
return target;
const isObject = val => {
return (typeof val === 'object' && val !== null) || typeof val === 'function';
};
const isUnsafeKey = key => {
return key === '__proto__' || key === 'constructor' || key === 'prototype';
};
const validateKey = key => {
if (isUnsafeKey(key)) {
throw new Error(`Cannot set unsafe key: "${key}"`);
}
};
let opts = options || {};
const isArray = Array.isArray(path);
if (!isArray && typeof path !== 'string') {
return target;
const toString = input => {
return Array.isArray(input) ? input.flat().map(String).join(',') : input;
};
const createMemoKey = (input, options) => {
if (typeof input !== 'string' || !options) return input;
let key = input + ';';
if (options.arrays !== undefined) key += `arrays=${options.arrays};`;
if (options.separator !== undefined) key += `separator=${options.separator};`;
if (options.split !== undefined) key += `split=${options.split};`;
if (options.merge !== undefined) key += `merge=${options.merge};`;
if (options.preservePaths !== undefined) key += `preservePaths=${options.preservePaths};`;
return key;
};
const memoize = (input, options, fn) => {
const key = toString(options ? createMemoKey(input, options) : input);
validateKey(key);
const val = setValue.cache.get(key) || fn();
setValue.cache.set(key, val);
return val;
};
const isNumber = value => {
if (value.trim() !== '') {
const number = Number(value);
return { is: Number.isInteger(number), number };
}
return { is: false };
};
let merge = opts.merge;
if (merge && typeof merge !== 'function') {
merge = Object.assign;
const splitString = (input, options) => {
const opts = options || {};
const sep = opts.separator || '.';
const preserve = sep === '/' ? false : opts.preservePaths;
if (typeof input === 'symbol') {
return [input];
}
const keys = (isArray ? path : split(path, opts)).filter(isValidKey);
const len = keys.length;
const orig = target;
if (typeof opts.split === 'function') {
return opts.split(input);
}
if (!options && keys.length === 1) {
result(target, keys[0], value, merge);
return target;
const keys = Array.isArray(input) ? input : input.split(sep);
if (typeof input === 'string' && preserve !== false && /\//.test(input)) {
return [input];
}
for (let i = 0; i < len; i++) {
let prop = keys[i];
for (let i = 0; i < keys.length; i++) {
if (typeof keys[i] !== 'string') break;
const { is, number } = isNumber(keys[i]);
if (!isObject(target[prop])) {
target[prop] = {};
if (is) {
keys[i] = number;
continue;
}
if (i === len - 1) {
result(target, prop, value, merge);
break;
while (keys[i] && i < keys.length && keys[i].endsWith('\\') && typeof keys[i + 1] === 'string') {
keys[i] = keys[i].slice(0, -1) + sep + keys.splice(i + 1, 1);
}
target = target[prop];
}
return orig;
}
return keys;
};
function result(target, path, value, merge) {
if (merge && isPlain(target[path]) && isPlain(value)) {
target[path] = merge({}, target[path], value);
} else {
target[path] = value;
}
}
const split = (input, options) => {
return memoize(input, options, () => splitString(input, options));
};
function split(path, options) {
const id = createKey(path, options);
if (set.memo[id]) return set.memo[id];
const setProp = (obj, prop, value, options) => {
validateKey(prop);
const char = (options && options.separator) ? options.separator : '.';
let keys = [];
let res = [];
// Delete property when "value" is undefined
if (value === undefined) {
delete obj[prop];
if (options && typeof options.split === 'function') {
keys = options.split(path);
} else if (options && options.merge) {
const merge = options.merge === true ? Object.assign : options.merge;
// Only merge plain objects
if (merge && isPlainObject(obj[prop]) && isPlainObject(value)) {
obj[prop] = merge(obj[prop], value);
} else {
obj[prop] = value;
}
} else {
keys = path.split(char);
obj[prop] = value;
}
for (let i = 0; i < keys.length; i++) {
let prop = keys[i];
while (prop && prop.slice(-1) === '\\' && keys[i + 1] != null) {
prop = prop.slice(0, -1) + char + keys[++i];
return obj;
};
const setValue = (obj, path, value, options) => {
if (!path) return obj;
if (!isObject(obj)) return obj;
const keys = split(path, options);
const len = keys.length;
const target = obj;
for (let i = 0; i < len; i++) {
const key = keys[i];
const next = keys[i + 1];
validateKey(key);
if (next === undefined) {
setProp(obj, key, value, options);
break;
}
res.push(prop);
}
set.memo[id] = res;
return res;
}
function createKey(pattern, options) {
let id = pattern;
if (typeof options === 'undefined') {
return id + '';
if (typeof next === 'number' && !Array.isArray(obj[key])) {
obj[key] = [];
obj = obj[key];
continue;
}
if (!isObject(obj[key])) {
obj[key] = {};
}
obj = obj[key];
}
const keys = Object.keys(options);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
id += ';' + key + '=' + String(options[key]);
}
return id;
}
function isValidKey(key) {
return key !== '__proto__' && key !== 'constructor' && key !== 'prototype';
}
return target;
};
function isObject(val) {
return val !== null && (typeof val === 'object' || typeof val === 'function');
}
setValue.cache = new Map();
setValue.clear = () => {
setValue.cache = new Map();
};
set.memo = {};
module.exports = set;
module.exports = setValue;
{
"name": "set-value",
"description": "Create nested values and any intermediaries using dot notation (`'a.b.c'`) paths.",
"version": "3.0.2",
"version": "4.0.0",
"description": "Set nested properties on an object using dot notation.",
"license": "MIT",
"repository": "jonschlinkert/set-value",
"homepage": "https://github.com/jonschlinkert/set-value",
"author": "Jon Schlinkert (https://github.com/jonschlinkert)",
"bugs": "https://github.com/jonschlinkert/set-value/issues",
"author": "Jon Schlinkert <jon.schlinkert@sellside.com> (https://github.com/jonschlinkert)",
"funding": [
"https://github.com/sponsors/jonschlinkert",
"https://paypal.me/jonathanschlinkert",
"https://jonschlinkert.dev/sponsor"
],
"contributors": [

@@ -12,7 +20,2 @@ "Jon Schlinkert (http://twitter.com/jonschlinkert)",

],
"repository": "jonschlinkert/set-value",
"bugs": {
"url": "https://github.com/jonschlinkert/set-value/issues"
},
"license": "MIT",
"files": [

@@ -23,3 +26,3 @@ "index.js"

"engines": {
"node": ">=6.0"
"node": ">=11.0"
},

@@ -33,18 +36,5 @@ "scripts": {

"devDependencies": {
"benchmarked": "^2.0.0",
"deep-object": "^1.0.0",
"deep-property": "^1.1.0",
"deep-set": "^1.0.1",
"deephas": "^1.0.5",
"dot-prop": "^4.2.0",
"dot2val": "^1.2.2",
"es5-dot-prop": "^4.1.1",
"gulp-format-md": "^2.0.0",
"lodash.set": "^4.3.2",
"minimist": "^1.2.0",
"mocha": "^3.5.3",
"object-path-set": "^1.0.0",
"object-set": "^1.0.1",
"split-string": "^5.0.4",
"write": "^1.0.3"
"mocha": "^8.3.2",
"split-string": "^6.1.0"
},

@@ -56,4 +46,4 @@ "keywords": [

"deep-property",
"deep-set-in",
"deep-set",
"deep-set-in",
"deephas",

@@ -72,6 +62,7 @@ "dot-prop",

"notation",
"object",
"object-path-set",
"object-path",
"object-path-set",
"object-set",
"object",
"patch",
"prop",

@@ -81,7 +72,9 @@ "properties",

"props",
"set",
"put",
"set-deep-prop",
"set-deep",
"set-deep-prop",
"set-nested-prop",
"set",
"setvalue",
"split-string",
"value",

@@ -138,2 +131,2 @@ "values"

}
}
}

@@ -1,4 +0,4 @@

# set-value [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=W8YFZ425KND68) [![NPM version](https://img.shields.io/npm/v/set-value.svg?style=flat)](https://www.npmjs.com/package/set-value) [![NPM monthly downloads](https://img.shields.io/npm/dm/set-value.svg?style=flat)](https://npmjs.org/package/set-value) [![NPM total downloads](https://img.shields.io/npm/dt/set-value.svg?style=flat)](https://npmjs.org/package/set-value) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/set-value.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/set-value)
# set-value [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/jonathanschlinkert?locale.x=en_US) [![NPM version](https://img.shields.io/npm/v/set-value.svg?style=flat)](https://www.npmjs.com/package/set-value) [![NPM monthly downloads](https://img.shields.io/npm/dm/set-value.svg?style=flat)](https://npmjs.org/package/set-value) [![NPM total downloads](https://img.shields.io/npm/dt/set-value.svg?style=flat)](https://npmjs.org/package/set-value)
> Create nested values and any intermediaries using dot notation (`'a.b.c'`) paths.
> Set nested properties on an object using dot notation.

@@ -9,3 +9,3 @@ Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support.

Install with [npm](https://www.npmjs.com/):
Install with [npm](https://www.npmjs.com/) (requires [Node.js](https://nodejs.org/en/) >=11.0):

@@ -24,3 +24,8 @@ ```sh

const set = require('set-value');
set(object, prop, value);
const obj = {};
set(obj, 'a.b.c', 'd');
console.log(obj);
//=> { a: { b: { c: 'd' } } }
```

@@ -30,17 +35,17 @@

* `object` **{object}**: The object to set `value` on
* `prop` **{string}**: The property to set. Dot-notation may be used.
* `value` **{any}**: The value to set on `object[prop]`
Signature:
## Examples
Updates and returns the given object:
```js
const obj = {};
set(obj, 'a.b.c', 'd');
console.log(obj);
//=> { a: { b: { c: 'd' } } }
set(object, property_path, value[, options]);
```
* `object` **{Object}**: The object to set `value` on
* `path` **{String|Symbol|Array}**: The [path](#object-paths) of the property to set.
* `value` **{any}**: The value to set on `obj[prop]`
* `options` **{Object}**: See all [available options](#options)
### Object paths
You may pass a string, symbol, or array of strings or symbols. By default, when a string is passed this library will split the string on `.` or a [custom separator](#options-separator) It's useful to pass an array
### Escaping

@@ -60,53 +65,105 @@

## Benchmarks
## Options
_(benchmarks were run on a MacBook Pro 2.5 GHz Intel Core i7, 16 GB 1600 MHz DDR3)_.
### options.preservePaths
set-value is more reliable and has more features than dot-prop, without sacrificing performance.
Do not split properties that include a `/`. By default, set-value assumes that properties with a `/` are not intended to be split. This option allows you to disable default behavior.
Note that this option cannot be used if `options.separator` is set to `/`.
**Type**: `boolean`
**Default**: `true`
**Example**
```js
console.log(set({}, 'https://github.com', true));
//=> { 'https://github.com': true }
console.log(set({}, 'https://github.com', true, { preservePaths: false }));
//=> { 'https://github': { com: true } }
```
### options.separator
Custom separator to use for splitting object paths.
**Type**: `string`
**Default**: `.`
**Example**
```js
console.log(set(obj, 'auth/userpass/users/bob', '*****', { separator: '/' }));
//=> { auth: { userpass: { users: { bob: '*****' } } } }
```
### options.split
Custom `.split()` function to use.
### options.merge
Allows you to update plain object values, instead of overwriting them.
**Type**: `boolean|function` - A custom `merge` function may be defined if you need to deep merge. Otherwise, when `merge` is `true`, a shallow merge will be performed by `Object.assign()`.
**Default**: `undefined`
**Example**
```js
const obj = { foo: { bar: { baz: 'qux' } } };
set(obj, 'foo.bar.fez', 'zzz', { merge: true });
//=> { foo: { bar: { baz: 'qux', fez: 'zzz' } } }
```
## Benchmarks
Benchmarks were run on a MacBook Pro 2.5 GHz Intel Core i7, 16 GB 1600 MHz DDR3.
```
# deep (194 bytes)
deep-object x 629,744 ops/sec ±0.85% (88 runs sampled)
deep-property x 1,470,427 ops/sec ±0.94% (89 runs sampled)
deep-set x 1,401,089 ops/sec ±1.02% (91 runs sampled)
deephas x 590,005 ops/sec ±1.73% (86 runs sampled)
dot-prop x 1,261,408 ops/sec ±0.94% (90 runs sampled)
dot2val x 1,672,729 ops/sec ±1.12% (89 runs sampled)
es5-dot-prop x 1,313,018 ops/sec ±0.79% (91 runs sampled)
lodash-set x 1,074,464 ops/sec ±0.97% (93 runs sampled)
object-path-set x 961,198 ops/sec ±2.07% (74 runs sampled)
object-set x 258,438 ops/sec ±0.69% (90 runs sampled)
set-value x 1,976,843 ops/sec ±2.07% (89 runs sampled)
deep-object x 879,975 ops/sec ±0.85% (94 runs sampled)
deep-property x 1,746,617 ops/sec ±0.59% (96 runs sampled)
deephas x 792,449 ops/sec ±0.61% (94 runs sampled)
dot-prop x 1,258,403 ops/sec ±0.81% (93 runs sampled)
dot2val x 2,096,518 ops/sec ±0.71% (94 runs sampled)
es5-dot-prop x 1,627,431 ops/sec ±0.57% (94 runs sampled)
lodash-set x 1,100,116 ops/sec ±0.80% (94 runs sampled)
object-path-set x 1,292,062 ops/sec ±0.56% (91 runs sampled)
object-set x 276,868 ops/sec ±0.60% (92 runs sampled)
set-value x 2,587,076 ops/sec ±0.47% (92 runs sampled)
fastest is set-value (by 186% avg)
fastest is set-value (by 210% avg)
# medium (98 bytes)
deep-object x 3,249,287 ops/sec ±1.04% (93 runs sampled)
deep-property x 3,409,307 ops/sec ±1.28% (88 runs sampled)
deep-set x 3,240,776 ops/sec ±1.13% (93 runs sampled)
deephas x 960,504 ops/sec ±1.39% (89 runs sampled)
dot-prop x 2,776,388 ops/sec ±0.80% (94 runs sampled)
dot2val x 3,889,791 ops/sec ±1.28% (91 runs sampled)
es5-dot-prop x 2,779,604 ops/sec ±1.32% (91 runs sampled)
lodash-set x 2,791,304 ops/sec ±0.75% (90 runs sampled)
object-path-set x 2,462,084 ops/sec ±1.51% (91 runs sampled)
object-set x 838,569 ops/sec ±0.87% (90 runs sampled)
set-value x 4,767,287 ops/sec ±1.21% (91 runs sampled)
deep-object x 5,823,296 ops/sec ±0.63% (92 runs sampled)
deep-property x 4,045,998 ops/sec ±0.69% (91 runs sampled)
deephas x 1,237,999 ops/sec ±0.56% (92 runs sampled)
dot-prop x 2,833,082 ops/sec ±0.82% (93 runs sampled)
dot2val x 4,669,511 ops/sec ±0.50% (94 runs sampled)
es5-dot-prop x 3,348,092 ops/sec ±0.71% (92 runs sampled)
lodash-set x 3,051,898 ops/sec ±0.61% (94 runs sampled)
object-path-set x 3,867,590 ops/sec ±0.48% (92 runs sampled)
object-set x 888,369 ops/sec ±0.52% (96 runs sampled)
set-value x 8,209,356 ops/sec ±0.68% (91 runs sampled)
fastest is set-value (by 181% avg)
fastest is set-value (by 248% avg)
# shallow (101 bytes)
deep-object x 4,793,168 ops/sec ±0.75% (88 runs sampled)
deep-property x 4,669,218 ops/sec ±1.17% (90 runs sampled)
deep-set x 4,648,247 ops/sec ±0.73% (91 runs sampled)
deephas x 1,246,414 ops/sec ±1.67% (92 runs sampled)
dot-prop x 3,913,694 ops/sec ±1.23% (89 runs sampled)
dot2val x 5,428,829 ops/sec ±0.76% (92 runs sampled)
es5-dot-prop x 3,897,931 ops/sec ±1.19% (92 runs sampled)
lodash-set x 6,128,638 ops/sec ±0.95% (87 runs sampled)
object-path-set x 5,429,978 ops/sec ±3.31% (87 runs sampled)
object-set x 1,529,485 ops/sec ±2.37% (89 runs sampled)
set-value x 7,150,921 ops/sec ±1.58% (89 runs sampled)
deep-object x 9,558,659 ops/sec ±0.81% (92 runs sampled)
deep-property x 5,190,792 ops/sec ±0.72% (93 runs sampled)
deephas x 1,395,091 ops/sec ±0.55% (90 runs sampled)
dot-prop x 4,203,222 ops/sec ±0.67% (94 runs sampled)
dot2val x 5,908,936 ops/sec ±0.52% (93 runs sampled)
es5-dot-prop x 4,511,259 ops/sec ±0.65% (94 runs sampled)
lodash-set x 8,624,572 ops/sec ±0.87% (90 runs sampled)
object-path-set x 5,800,121 ops/sec ±0.73% (90 runs sampled)
object-set x 1,629,494 ops/sec ±0.68% (92 runs sampled)
set-value x 13,925,948 ops/sec ±0.68% (89 runs sampled)
fastest is set-value (by 172% avg)
fastest is set-value (by 268% avg)

@@ -223,7 +280,10 @@ ```

| --- | --- |
| 73 | [jonschlinkert](https://github.com/jonschlinkert) |
| 83 | [jonschlinkert](https://github.com/jonschlinkert) |
| 4 | [doowb](https://github.com/doowb) |
| 2 | [mbelsky](https://github.com/mbelsky) |
| 1 | [doowb](https://github.com/doowb) |
| 1 | [dkebler](https://github.com/dkebler) |
| 1 | [GlennKintscher](https://github.com/GlennKintscher) |
| 1 | [vadimdemedes](https://github.com/vadimdemedes) |
| 1 | [petermorlion](https://github.com/petermorlion) |
| 1 | [abetomo](https://github.com/abetomo) |
| 1 | [zeidoo](https://github.com/zeidoo) |
| 1 | [wtgtybhertgeghgtwtg](https://github.com/wtgtybhertgeghgtwtg) |

@@ -241,3 +301,3 @@

Copyright © 2020, [Jon Schlinkert](https://github.com/jonschlinkert).
Copyright © 2021, [Jon Schlinkert](https://github.com/jonschlinkert).
Released under the [MIT License](LICENSE).

@@ -247,2 +307,2 @@

_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on April 01, 2020._
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on April 28, 2021._
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