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

property-expr

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

property-expr - npm Package Compare versions

Comparing version 1.4.0 to 1.5.0

134

index.js
/**
* @license
* expr 1.0.0
* Copyright 2014 Jason Quense
* Based on Kendo UI Core expression code <https://github.com/telerik/kendo-ui-core#license-information>
* Copyright :copyright: 2014 Telerik
* Available under MIT license <https://github.com/theporchrat/expr/blob/master/LICENSE.txt>
*/
'use strict'
function Cache(maxSize) {
this._maxSize = maxSize
this.clear()
}
Cache.prototype.clear = function() {
this._size = 0
this._values = {}
}
Cache.prototype.get = function(key) {
return this._values[key]
}
Cache.prototype.set = function(key, value) {
this._size >= this._maxSize && this.clear()
if (!this._values.hasOwnProperty(key)) {
this._size++
}
return this._values[key] = value
}
var SPLIT_REGEX = /[^.^\]^[]+|(?=\[\]|\.\.)/g,
DIGIT_REGEX = /^\d+$/,
LEAD_DIGIT_REGEX = /^\d/,
SPEC_CHAR_REGEX = /[~`!#$%\^&*+=\-\[\]\\';,/{}|\\":<>\?]/g
SPEC_CHAR_REGEX = /[~`!#$%\^&*+=\-\[\]\\';,/{}|\\":<>\?]/g,
CLEAN_QUOTES_REGEX = /^\s*(['"]?)(.*?)(\1)\s*$/,
MAX_CACHE_SIZE = 512
var setCache = {},
getCache = {}
var contentSecurityPolicy = false,
pathCache = new Cache(MAX_CACHE_SIZE),
setCache = new Cache(MAX_CACHE_SIZE),
getCache = new Cache(MAX_CACHE_SIZE)
try {
new Function('')
} catch (error) {
contentSecurityPolicy = true
}
module.exports = {
Cache: Cache,
expr: expr,
setter: function(path) {
return (
setCache[path] ||
(setCache[path] = new Function(
'data, value',
expr(path, 'data') + ' = value'
))
)
},
split: split,
getter: function(path, safe) {
var k = path + '_' + safe
return (
getCache[k] ||
(getCache[k] = new Function('data', 'return ' + expr(path, safe, 'data')))
)
},
normalizePath: normalizePath,
split: function(path) {
return path.match(SPLIT_REGEX)
},
setter: contentSecurityPolicy
? function(path) {
var parts = normalizePath(path)
return function(data, value) {
return setterFallback(parts, data, value)
}
}
: function(path) {
return setCache.get(path) || setCache.set(
path,
new Function(
'data, value',
expr(path, 'data') + ' = value'
)
)
},
getter: contentSecurityPolicy
? function(path, safe) {
var parts = normalizePath(path)
return function(data) {
return getterFallback(parts, safe, data)
}
}
: function(path, safe) {
var key = path + '_' + safe
return getCache.get(key) || getCache.set(
key,
new Function('data', 'return ' + expr(path, safe, 'data'))
)
},
join: function(segments) {

@@ -55,6 +96,41 @@ return segments.reduce(function(path, part) {

forEach: function(path, cb, thisArg) {
forEach(path.match(SPLIT_REGEX), cb, thisArg)
forEach(split(path), cb, thisArg)
}
}
function setterFallback(parts, data, value) {
var index = 0,
len = parts.length
while (index < len - 1) {
data = data[parts[index++]]
}
data[parts[index]] = value
}
function getterFallback(parts, safe, data) {
var index = 0,
len = parts.length
while (index < len) {
if (data == null || !safe) {
data = data[parts[index++]]
} else {
return
}
}
return data
}
function normalizePath(path) {
return pathCache.get(path) || pathCache.set(
path,
split(path).map(function(part) {
return part.replace(CLEAN_QUOTES_REGEX, '$2')
})
)
}
function split(path) {
return path.match(SPLIT_REGEX)
}
function expr(expression, safe, param) {

@@ -106,3 +182,3 @@ expression = expression || ''

var result = param,
parts = path.match(SPLIT_REGEX),
parts = split(path),
isLast

@@ -109,0 +185,0 @@

{
"name": "property-expr",
"version": "1.4.0",
"version": "1.5.0",
"description": "tiny util for getting and setting deep object props safely",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -24,7 +24,7 @@ expr

setBaz(obj, 'set me!')
console.log(foo.bar[1].buz.baz) // => 'set me!'
console.log(obj.foo.bar[1].buz.baz) // => 'set me!'
### `getter(expression, [ safeAccess ])`
returns a function that accepts an obj and returns the value at the supplied expression. You can create a "safe" getter, which won't error out when accessing properties that don't exist, reducing existance checks befroe property access:
Returns a function that accepts an obj and returns the value at the supplied expression. You can create a "safe" getter, which won't error out when accessing properties that don't exist, reducing existance checks befroe property access:

@@ -36,3 +36,3 @@ expr.getter('foo.bar.baz', true)({ foo: {} }) // => undefined

returns a function that accepts an obj and a value and sets the property pointed to by the expression to the supplied value.
Returns a function that accepts an obj and a value and sets the property pointed to by the expression to the supplied value.

@@ -42,3 +42,3 @@

Returns a normalized expression string pointing to a property on root object
Returns a normalized expression string pointing to a property on root object
`paramName`.

@@ -53,6 +53,6 @@

```js
split("foo['bar'][0].baz") // [ "foo", "'bar'", "0", "baz"]
expr.split("foo['bar'][0].baz") // [ "foo", "'bar'", "0", "baz"]
```
### `forEach(path, iterator[, thisArg]) `
### `forEach(path, iterator[, thisArg])`

@@ -62,7 +62,29 @@ Iterate through a path but segment, with some additional helpful metadata about the segment. The iterator function is called with: `pathSegment`, `isBracket`, `isArray`, `idx`, `segments`

```js
.forEach('foo["bar"][1]', function(pathSegment, isBracket, isArray, idx, segments) {
expr.forEach('foo["bar"][1]', function(pathSegment, isBracket, isArray, idx, segments) {
// 'foo' -> isBracket = false, isArray = false, idx = 0
// '"bar"' -> isBracket = true, isArray = false, idx = 1
// '0' -> isBracket = false, isArray = true, idx = 2
}
```
})
```
### `normalizePath(path)`
Returns an array of path segments without quotes and spaces.
```js
expr.normalizePath('foo["bar"][ "1" ][2][ " sss " ]')
// ['foo', 'bar', '1', '2', ' sss ']
```
### `new Cache(maxSize)`
Just an utility class, returns an instance of cache. When the max size is exceeded, cache clears its storage.
```js
var cache = new Cache(2)
cache.set('a', 123) // returns 123
cache.get('a') // returns 123
cache.clear()
cache.set('a', 1)
cache.set('b', 2) // cache contains 2 values
cache.set('c', 3) // cache was cleaned automatically and contains 1 value
```

@@ -17,3 +17,3 @@ var a = require('assert'),

//--- Getters -----------------------------------------------
// -- Getters --
a.strictEqual(getter('foo.fux')(obj), 5);

@@ -26,3 +26,3 @@ a.deepEqual(getter('foo.bar')(obj), ['baz', 'bux']);

//safe access
// safe access
a.strictEqual(getter('foo.fux', true)(obj), 5);

@@ -45,3 +45,3 @@ a.deepEqual(getter('foo.bar', true)(obj), ['baz', 'bux']);

//--- Setters -----------------------------------------------
// -- Setters --
setter('foo.fux')(obj, 10);

@@ -56,4 +56,23 @@ a.strictEqual(obj.foo.fux, 10);

// -- Split -------
// -- Cache --
var cache = new expression.Cache(3)
a.strictEqual(cache._size, 0)
a.strictEqual(cache.set('a', a), a)
a.strictEqual(cache.get('a'), a)
a.strictEqual(cache._size, 1)
a.strictEqual(cache.set('b', 123), 123)
a.strictEqual(cache.get('b'), 123)
a.strictEqual(cache.set('b', 321), 321)
a.strictEqual(cache.get('b'), 321)
a.strictEqual(cache.set('c', null), null)
a.strictEqual(cache.get('c'), null)
a.strictEqual(cache._size, 3)
a.strictEqual(cache.set('d', 444), 444)
a.strictEqual(cache._size, 1)
cache.clear()
a.strictEqual(cache._size, 0)
a.strictEqual(cache.get('a'), undefined)
// -- split --
var parts = expression.split('foo.baz["bar"][1]');

@@ -63,3 +82,3 @@

// -- JOIN -------
// -- join --

@@ -72,3 +91,3 @@ var parts = expression.split('foo.baz["bar"][1]');

// -- ForEach ------
// -- forEach --

@@ -110,2 +129,10 @@ var count = 0;

a.strictEqual(count, 3);
// -- normalizePath --
a.deepEqual(
expression.normalizePath('foo[ " bux\'s " ].bar["baz"][ 9 ][ \' s \' ]'),
['foo', ' bux\'s ', 'bar', 'baz', '9', ' s ']
)
console.log('--- Tests Passed ---');
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