object-manage
Advanced tools
Comparing version 0.5.1 to 0.6.0
@@ -23,3 +23,3 @@ 'use strict'; | ||
dev: { | ||
files: ['*.js','lib/*.js','test/*.js'], | ||
files: ['*.js','drivers/*.js','lib/*.js','test/*.js'], | ||
tasks: ['test'] | ||
@@ -26,0 +26,0 @@ } |
'use strict'; | ||
module.exports = require('./lib/ObjectManage') |
@@ -6,4 +6,30 @@ 'use strict'; | ||
, objectMerge = require('object-merge') | ||
, Validate = require('./Validate') | ||
, ValidateHelpers = require('./ValidateHelpers') | ||
, StorageDriver = require('./StorageDriver') | ||
, uuid = require('uuid') | ||
/** | ||
* Take a path argument and normalize to something usable | ||
* from multiple types | ||
* @param path | ||
* @returns {*} | ||
*/ | ||
var pathNormalize = function(path){ | ||
if(undefined === path){ | ||
throw new Error('path is required') | ||
} | ||
if(util.isArray(path)){ | ||
return path.join('.') | ||
} | ||
if('function' === typeof path){ | ||
return pathNormalize(path()) | ||
} | ||
if('object' === typeof path && 'string' !== typeof path && 'function' === typeof path.toString){ | ||
return path.toString() | ||
} | ||
return path | ||
} | ||
/** | ||
* Private function to traverse the target and return | ||
@@ -18,2 +44,3 @@ * the path | ||
if(undefined === path) return target | ||
path = pathNormalize(path) | ||
var o = target | ||
@@ -37,2 +64,3 @@ , p = path.split('.') | ||
if('object' !== typeof target) return false | ||
path = pathNormalize(path) | ||
var o = target | ||
@@ -55,2 +83,3 @@ , p = path.split('.') | ||
var set = function(target,path,value){ | ||
path = pathNormalize(path) | ||
if('object' === typeof target){ | ||
@@ -74,2 +103,3 @@ var o = target | ||
var remove = function(target,path){ | ||
path = pathNormalize(path) | ||
var o = target | ||
@@ -89,92 +119,2 @@ for(var a,p=path.split('.'),i=0; o&&(a=p[i++]); o=o[a]){ | ||
/** | ||
* Object Manage Validate Instance | ||
* @param verb | ||
* @param message | ||
* @param path | ||
* @param value | ||
* @constructor | ||
*/ | ||
var Validate = function(verb,message,path,value){ | ||
Error.call(this) | ||
this.message = message | ||
this.verb = verb | ||
this.path = path | ||
this.value = value | ||
} | ||
//inherit Error prototype | ||
util.inherits(Validate,Error) | ||
/** | ||
* Verb to handle the validation call | ||
* @type {null} | ||
*/ | ||
Validate.prototype.verb = null | ||
/** | ||
* Path being operated on | ||
* @type {null} | ||
*/ | ||
Validate.prototype.path = null | ||
/** | ||
* Value of the call be validated | ||
* @type {undefined} | ||
*/ | ||
Validate.prototype.value = undefined | ||
/** | ||
* Validate Helpers construction | ||
* @param path | ||
* @param value | ||
* @constructor | ||
*/ | ||
var ValidateHelpers = function(path,value){ | ||
this.path = path | ||
this.value = value | ||
} | ||
/** | ||
* Path being operated on | ||
* @type {null} | ||
*/ | ||
ValidateHelpers.prototype.path = null | ||
/** | ||
* Value being operated on | ||
* @type {null} | ||
*/ | ||
ValidateHelpers.prototype.value = null | ||
/** | ||
* Convenience method to drop a request | ||
* @param message | ||
*/ | ||
ValidateHelpers.prototype.drop = function(message){ | ||
throw new Validate('drop',message,this.path,this.value) | ||
} | ||
/** | ||
* Convenience method to reject a request | ||
* @param message | ||
*/ | ||
ValidateHelpers.prototype.reject = function(message){ | ||
throw new Validate('reject',message,this.path,this.value) | ||
} | ||
/** | ||
* Convenience method to warn about a request | ||
* @param message | ||
* @param value | ||
*/ | ||
ValidateHelpers.prototype.warn = function(message,value){ | ||
throw new Validate('warn',message,this.path,value) | ||
} | ||
/** | ||
* Convenience method to error about a request | ||
* @param message | ||
*/ | ||
ValidateHelpers.prototype.error = function(message){ | ||
throw new Validate('error',message,this.path,this.value) | ||
} | ||
/** | ||
* Convenience method to succeed a request | ||
* @param value | ||
*/ | ||
ValidateHelpers.prototype.ok = function(value){ | ||
throw new Validate('ok',null,this.path,value) | ||
} | ||
/** | ||
* Run validation of an action | ||
@@ -252,2 +192,5 @@ * | ||
this.load(data) | ||
//setup the memory driver as the default | ||
var MemoryDriver = require('../drivers/memory') | ||
this.driver = new MemoryDriver() | ||
} | ||
@@ -272,3 +215,3 @@ util.inherits(ObjectManage,events.EventEmitter) | ||
*/ | ||
ObjectManage.prototype.Validate = Validate | ||
ObjectManage.Validate = Validate | ||
@@ -492,2 +435,161 @@ /** | ||
/** | ||
* Instance of the storage backend | ||
* @type {null} | ||
*/ | ||
ObjectManage.prototype.driver = null | ||
/** | ||
* Setup the storage backend | ||
* @param driver | ||
*/ | ||
ObjectManage.prototype.storage = function(driver){ | ||
var Driver | ||
if(driver instanceof StorageDriver){ | ||
this.driver = driver | ||
} else if('string' === typeof driver){ | ||
Driver = require('../drivers/' + driver) | ||
this.driver = new Driver() | ||
} else if('object' === typeof driver){ | ||
Driver = require('../drivers/' + driver.driver) | ||
this.driver = new Driver(driver.options) | ||
} | ||
return this | ||
} | ||
/** | ||
* Reference to the storage driver class | ||
* @type {exports} | ||
*/ | ||
ObjectManage.StorageDriver = require('./StorageDriver') | ||
/** | ||
* Instance handle | ||
* @type {null} | ||
*/ | ||
ObjectManage.prototype.handle = null | ||
/** | ||
* Generate Instance Handle if not already set | ||
*/ | ||
ObjectManage.prototype.generateHandle = function(){ | ||
if(null === this.handle){ | ||
var handle = uuid.v4() | ||
this.setHandle(handle) | ||
this.emit('generateHandle',handle) | ||
} | ||
} | ||
/** | ||
* Set instance handle explicitly | ||
* @param handle | ||
*/ | ||
ObjectManage.prototype.setHandle = function(handle){ | ||
this.handle = handle | ||
} | ||
/** | ||
* Return the instance handle that is currently set | ||
* will be null if not yet generated | ||
* @returns {null} | ||
*/ | ||
ObjectManage.prototype.getHandle = function(){ | ||
return this.handle | ||
} | ||
/** | ||
* Save to the storage backend | ||
* Callback params: err, handle, data | ||
* @param [cb] | ||
*/ | ||
ObjectManage.prototype.save = function(cb){ | ||
if('function' !== typeof cb){ | ||
cb = function(err){ | ||
if(err) throw err | ||
} | ||
} | ||
var self = this | ||
self.generateHandle() | ||
if('function' === typeof self.driver.save){ | ||
self.driver.save(self.handle,self.data,function(err){ | ||
self.emit('save',self.handle,self.data) | ||
cb(err,self.handle,self.data) | ||
}) | ||
} else { | ||
var err = 'driver (' + self.driver.name + ') has not implemented a save method' | ||
self.emit('save',err) | ||
cb(err) | ||
} | ||
} | ||
/** | ||
* Restore frozen object by its handle | ||
* @param handle | ||
* @param [cb] | ||
*/ | ||
ObjectManage.prototype.restore = function(handle,cb){ | ||
var self = this | ||
if('function' !== typeof cb){ | ||
cb = function(err){ | ||
if(err) throw err | ||
} | ||
} | ||
self.setHandle(handle) | ||
if('function' === typeof self.driver.restore){ | ||
self.driver.restore(self.handle,function(err,data){ | ||
if(err){ | ||
self.emit('restore',err) | ||
cb(err) | ||
} else { | ||
self.load(data) | ||
self.emit('restore',null,data) | ||
cb(null,data) | ||
} | ||
}) | ||
} else { | ||
var err = 'driver (' + self.driver.name + ') has not implemented a restore method' | ||
self.emit('restore',err) | ||
cb(err) | ||
} | ||
} | ||
/** | ||
* Flush the object stored by the storage driver | ||
* @param [cb] | ||
*/ | ||
ObjectManage.prototype.flush = function(cb){ | ||
var self = this | ||
if('function' !== typeof cb){ | ||
cb = function(err){ | ||
if(err) throw err | ||
} | ||
} | ||
if(null === self.handle){ | ||
throw new Error('cannot flush without a handle being set') | ||
} else if('function' === typeof self.driver.flush){ | ||
self.driver.flush(self.handle,function(err){ | ||
if(err){ | ||
self.emit('flush',err) | ||
cb(err) | ||
} else { | ||
self.emit('flush') | ||
self.data = {} | ||
cb() | ||
} | ||
}) | ||
} else { | ||
var err = 'driver (' + self.driver.name + ') has not implemented a flush method' | ||
self.emit('flush',err) | ||
cb(err) | ||
} | ||
} | ||
/** | ||
* Reset data store | ||
*/ | ||
ObjectManage.prototype.reset = function(){ | ||
this.data = {} | ||
} | ||
module.exports = ObjectManage |
@@ -0,0 +0,0 @@ The MIT License (MIT) |
@@ -6,3 +6,3 @@ { | ||
"bugs": "https://github.com/snailjs/object-manage/issues", | ||
"version": "0.5.1", | ||
"version": "0.6.0", | ||
"author": "Bryan Tong <contact@nullivex.com>", | ||
@@ -30,3 +30,5 @@ "license": "MIT", | ||
"object-merge": "~2.5.1", | ||
"merge-recursive": "0.0.3" | ||
"merge-recursive": "0.0.3", | ||
"redis": "~0.10.0", | ||
"uuid": "~1.4.1" | ||
}, | ||
@@ -33,0 +35,0 @@ "devDependencies": { |
292
README.md
@@ -55,2 +55,9 @@ object-manage [![Build Status](https://travis-ci.org/snailjs/object-manage.png?branch=master)](https://travis-ci.org/snailjs/object-manage) | ||
//reset | ||
obj.reset() | ||
//path as an array | ||
obj.set(['foo','test'],'yes') | ||
obj.get('foo.test') //yes | ||
``` | ||
@@ -60,3 +67,3 @@ | ||
It is also useful to use ObjectManage as a superconstructor for libraries with options. | ||
It is also useful to use ObjectManage as a super constructor for libraries with options. | ||
@@ -79,2 +86,225 @@ Here is a quick example | ||
## Path Normalization | ||
Paths can be passed in many different formats to allow for more programatic usage | ||
of object-manage. | ||
### String | ||
The most common path format is a dot separated set of paths separated by a period. | ||
This is also the internal format that all others normalize to. | ||
**Example** | ||
```js | ||
var path = 'level1.level2.level3' | ||
obj.get(path) | ||
``` | ||
### Array | ||
An array of path parts can also be passed | ||
**Example** | ||
```js | ||
var path = ['level1','level2','level3'] | ||
obj.get(path) | ||
``` | ||
### Function | ||
A function may be passed that returns a string | ||
**Example** | ||
```js | ||
var path = function(){ | ||
return 'level1.level2.level3' | ||
} | ||
obj.get(path) | ||
``` | ||
The function can also return an array of parts | ||
**Example** | ||
```js | ||
var path = function(){ | ||
return ['level1','level2','level3'] | ||
} | ||
obj.get(path) | ||
``` | ||
### Object | ||
An object that has a `toString` method can also be used. | ||
**Example** | ||
```js | ||
var path = { | ||
toString: function(){ | ||
return 'level1.level2.level3' | ||
} | ||
} | ||
obj.get(path) | ||
``` | ||
## Storage | ||
By default **object-manage** uses an internal memory storage. However this can | ||
easily be changed to use a storage driver to persist the instance. | ||
### Bundled Drivers | ||
* Memory | ||
* Redis | ||
### Usage | ||
```js | ||
var handle = 'uuid' | ||
var obj = new ObjectManage() | ||
obj.storage({ | ||
driver: 'redis', | ||
options: { | ||
host: '127.0.0.1', | ||
port: 6379, | ||
secret: 'xyz' | ||
} | ||
}) | ||
obj.restore(handle) | ||
obj.set('foo',1) | ||
obj.save(function(err,handle){ | ||
if(err) throw err | ||
console.log(handle) | ||
}) | ||
``` | ||
### Methods | ||
#### Storage Setup | ||
To set the storage driver and options use the setStorage method. This method will | ||
automatically save the current object to the newly set options so data can still | ||
be passed to the constructor. If a string is passed it will be treated as the driver | ||
name and will not pass any options to the driver which assumes default. | ||
```js | ||
var obj = new ObjectManage() | ||
obj.storage('redis') // redis with default options | ||
obj.storage('memory') // revert back to the default | ||
obj.storage({ | ||
driver: 'redis', | ||
options: { | ||
host: '127.0.0.1', | ||
port: 6379, | ||
secret: 'xyz' | ||
}, | ||
ready: function(err){ | ||
if(err) throw err | ||
console.log('redis is ready') | ||
} | ||
}) | ||
``` | ||
Storage setup also returns the instance so it can be chained on to the constructor. | ||
```js | ||
var obj = new ObjectManage().storage('redis') | ||
obj.set('foo','yes') | ||
obj.save(function(err){ | ||
if(err) throw err | ||
process.exit() | ||
}) | ||
``` | ||
#### Save | ||
Saves the state of the object into the storage driver. | ||
If no handle is set using the `setHandle()` method then a handle | ||
will be automatically generated as a UUID. This handle is made available | ||
to the callback of the save function and will be available through the | ||
`getHandle()` method once the save has been initiated. | ||
```js | ||
var obj = new ObjectManage() | ||
obj.storage('redis') | ||
obj.data.foo = 1 | ||
obj.save(function(err,handle,data){ | ||
if(err) throw err | ||
console.log(handle) //prints the instance id | ||
console.log(data.foo) //1 | ||
}) | ||
``` | ||
#### Instance Handle | ||
To get the handle used to identify the instance use the getHandle method. | ||
The handle is automatically generated when a new instance is saved and no handle | ||
has been set. | ||
```js | ||
var obj = new ObjectManage() | ||
console.log(obj.getHandle()) //prints the instance handle | ||
``` | ||
To set a custom handle used to identify the instance use the setHandle method. | ||
```js | ||
var obj = new ObjectManage() | ||
obj.storage('redis') | ||
obj.setHandle('foo') | ||
obj.set('bar','baz') | ||
obj.save(function(err,handle,data){ | ||
if(err) throw err | ||
console.log(handle) //foo | ||
console.log(data.bar) //baz | ||
}) | ||
``` | ||
#### Restore | ||
To retrieve a saved instance of an object use the restore method. | ||
```js | ||
var handle = 'uuid' | ||
var obj = new ObjectManage().storage('redis') | ||
obj.restore(handle,function(err,data){ | ||
if(err) throw err | ||
console.log(data) | ||
}) | ||
``` | ||
### Drivers | ||
Implementing user space drivers is simple as well. | ||
Create a driver. | ||
```js | ||
var myStorageDriver = ObjectManage.StorageDriver.create('myStorageDriver') | ||
var store = {} | ||
myStorageDriver.prototype.setup = function(options){ | ||
//connect here | ||
} | ||
myStorageDriver.prototype.save = function(handle,data,next){ | ||
//save here | ||
store[handle] = data | ||
next() | ||
} | ||
myStorageDriver.prototype.restore = function(handle,next){ | ||
//restore here | ||
next(null,store[handle]) | ||
} | ||
myStorageDriver.prototype.flush = function(handle,next){ | ||
//flush here | ||
delete store[handle] | ||
next() | ||
} | ||
``` | ||
Using the driver | ||
```js | ||
var obj = new ObjectManage().storage(new myStorageDriver()) | ||
``` | ||
## Switching Merge Package | ||
@@ -332,2 +562,57 @@ | ||
### Generate Handle | ||
Fired when a handle is generated for the instance | ||
```js | ||
var obj = new require('object-manage')() | ||
obj.on('generateHandle',function(handle){ | ||
console.log('a handle was generated: ' + handle) | ||
}) | ||
obj.generateHandle() | ||
``` | ||
### Save | ||
Fired when a save to the storage driver is called | ||
```js | ||
var obj = new require('object-manage')() | ||
obj.on('save',function(err,handle,data){ | ||
if(err) throw err | ||
console.log(handle) //foo | ||
console.log(data.foo) //yes | ||
}) | ||
obj.set('foo','yes') | ||
obj.setHandle('foo') | ||
obj.save() | ||
``` | ||
### Restore | ||
Fired when a restore to the storage driver is called | ||
```js | ||
var obj = new require('object-manage')() | ||
obj.on('restore',function(err,data){ | ||
if(err) throw err | ||
console.log(data.foo) //yes | ||
}) | ||
obj.restore('foo') | ||
``` | ||
### Flush | ||
Fired when a flush to the storage driver is called | ||
```js | ||
var obj = new require('object-manage')() | ||
obj.on('flush',function(err){ | ||
if(err) throw err | ||
console.log('flushed instance') | ||
}) | ||
obj.restore('foo') | ||
obj.flush() | ||
``` | ||
### Drop | ||
@@ -409,2 +694,7 @@ | ||
### 0.6.0 | ||
* Added support for storage drivers | ||
* Added `reset` method | ||
* Added path normalization | ||
### 0.5.1 | ||
@@ -411,0 +701,0 @@ * Fixed small prototype issue with .merge being set to Object instead of ObjectManage |
@@ -50,2 +50,24 @@ 'use strict'; | ||
describe('Path Normalization',function(){ | ||
var obj | ||
beforeEach(function(){ | ||
obj = new ObjectManage(data3) | ||
}) | ||
it('should allow a period separated string',function(){ | ||
expect(obj.get('test5.test6')).to.equal('val6') | ||
}) | ||
it('should allow an array of path parts',function(){ | ||
expect(obj.get(['test5','test6'])).to.equal('val6') | ||
}) | ||
it('should allow a function that returns a path',function(){ | ||
expect(obj.get(function(){return 'test5.test6'})).to.equal('val6') | ||
}) | ||
it('should allow a function to return an array of path parts',function(){ | ||
expect(obj.get(function(){return ['test5','test6']})).to.equal('val6') | ||
}) | ||
it('should allow a toString of an object that returns a path',function(){ | ||
expect(obj.get({toString: function(){return 'test5.test6'}})).to.equal('val6') | ||
}) | ||
}) | ||
describe('Removal and Existence',function(){ | ||
@@ -65,2 +87,7 @@ it('should return true if the property exists',function(){ | ||
}) | ||
it('should reset the data object',function(){ | ||
var obj = new ObjectManage([data1,data2,data3]) | ||
obj.reset() | ||
expect(obj.get('test1')).to.equal(undefined) | ||
}) | ||
}) | ||
@@ -403,2 +430,174 @@ | ||
describe('Storage Drivers',function(){ | ||
it('should return the instance so the storage method can be chained',function(){ | ||
var obj = new ObjectManage().storage('memory') | ||
expect(obj).to.be.an.instanceof(ObjectManage) | ||
}) | ||
it('should allow setting a handle',function(){ | ||
var obj = new ObjectManage().storage('memory') | ||
obj.setHandle('foo') | ||
expect(obj.getHandle()).to.equal('foo') | ||
}) | ||
describe('Memory Driver',function(){ | ||
it('should save with the memory driver',function(done){ | ||
var obj = new ObjectManage() | ||
obj.set('foo','yes') | ||
obj.save(function(err,handle,data){ | ||
if(err) throw err | ||
expect(handle).to.not.equal(null) | ||
expect(data.foo).to.equal('yes') | ||
done() | ||
}) | ||
}) | ||
it('should restore with the memory driver',function(done){ | ||
var obj = new ObjectManage() | ||
obj.set('foo','yes') | ||
obj.save(function(err,handle){ | ||
if(err) throw err | ||
expect(handle).to.not.equal(null) | ||
//try to restore the object | ||
var obj2 = new ObjectManage() | ||
obj2.restore(handle,function(err,data){ | ||
if(err) throw err | ||
expect(data.foo).to.equal('yes') | ||
expect(obj2.get('foo')).to.equal('yes') | ||
done() | ||
}) | ||
}) | ||
}) | ||
it('should flush with the memory driver',function(done){ | ||
var obj = new ObjectManage() | ||
obj.set('foo','yes') | ||
obj.save(function(err,handle){ | ||
if(err) throw err | ||
expect(handle).to.not.equal(null) | ||
//try to restore the object | ||
var obj2 = new ObjectManage() | ||
obj2.restore(handle,function(err,data){ | ||
if(err) throw err | ||
expect(data.foo).to.equal('yes') | ||
expect(obj2.get('foo')).to.equal('yes') | ||
obj2.flush(function(err){ | ||
if(err) throw err | ||
done() | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
describe('Redis Driver',function(done){ | ||
it('should connect with full options',function(){ | ||
var options = { | ||
driver: 'redis', | ||
options: { | ||
host: '127.0.0.1', | ||
port: 6379 | ||
}, | ||
ready: function(err){ | ||
if(err) throw err | ||
console.log('redis is ready') | ||
done() | ||
} | ||
} | ||
new ObjectManage().storage(options) | ||
}) | ||
it('should save with the redis driver',function(done){ | ||
var obj = new ObjectManage().storage('redis') | ||
obj.set('foo','yes') | ||
obj.save(function(err,handle,data){ | ||
if(err) throw err | ||
expect(handle).to.not.equal(null) | ||
expect(data.foo).to.equal('yes') | ||
done() | ||
}) | ||
}) | ||
it('should restore with the redis driver',function(done){ | ||
var obj = new ObjectManage().storage('redis') | ||
obj.set('foo','yes') | ||
obj.save(function(err,handle){ | ||
if(err) throw err | ||
expect(handle).to.not.equal(null) | ||
//try to restore the object | ||
var obj2 = new ObjectManage().storage('redis') | ||
obj2.restore(handle,function(err,data){ | ||
if(err) throw err | ||
expect(data.foo).to.equal('yes') | ||
expect(obj2.get('foo')).to.equal('yes') | ||
done() | ||
}) | ||
}) | ||
}) | ||
it('should flush with the redis driver',function(done){ | ||
var obj = new ObjectManage().storage('redis') | ||
obj.set('foo','yes') | ||
obj.save(function(err,handle){ | ||
if(err) throw err | ||
expect(handle).to.not.equal(null) | ||
//try to restore the object | ||
var obj2 = new ObjectManage().storage('redis') | ||
obj2.restore(handle,function(err,data){ | ||
if(err) throw err | ||
expect(data.foo).to.equal('yes') | ||
expect(obj2.get('foo')).to.equal('yes') | ||
obj2.flush(function(err){ | ||
if(err) throw err | ||
done() | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
describe('Storage Events',function(){ | ||
it('should emit a generateHandle event',function(done){ | ||
var obj = new ObjectManage() | ||
obj.once('generateHandle',function(handle){ | ||
expect(handle).to.not.equal(null) | ||
done() | ||
}) | ||
obj.generateHandle() | ||
}) | ||
it('should emit a save event',function(done){ | ||
var obj = new ObjectManage() | ||
obj.once('save',function(handle,data){ | ||
expect(handle).to.not.equal(null) | ||
expect(data.foo).to.equal('yes') | ||
done() | ||
}) | ||
obj.set('foo','yes') | ||
obj.save() | ||
}) | ||
it('should emit a restore event',function(done){ | ||
var obj1 = new ObjectManage() | ||
obj1.set('foo','yes') | ||
obj1.save(function(err,handle){ | ||
if(err) throw err | ||
var obj = new ObjectManage() | ||
obj.once('restore',function(err,data){ | ||
if(err) throw err | ||
expect(data.foo).to.equal('yes') | ||
done() | ||
}) | ||
obj.restore(handle) | ||
}) | ||
}) | ||
it('should emit a flush event',function(done){ | ||
var obj1 = new ObjectManage() | ||
obj1.set('foo','yes') | ||
obj1.save(function(err,handle){ | ||
if(err) throw err | ||
var obj = new ObjectManage() | ||
obj.once('restore',function(err,data){ | ||
if(err) throw err | ||
expect(data.foo).to.equal('yes') | ||
obj.once('flush',function(err){ | ||
if(err) throw err | ||
done() | ||
}) | ||
obj.flush() | ||
}) | ||
obj.restore(handle) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
62621
16
1386
743
4
2
+ Addedredis@~0.10.0
+ Addeduuid@~1.4.1
+ Addedredis@0.10.3(transitive)
+ Addeduuid@1.4.2(transitive)