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

directory-cache

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

directory-cache - npm Package Compare versions

Comparing version 2.0.3 to 3.0.1

266

index.js

@@ -30,3 +30,9 @@ var $u = require('util')

this.directory = directory
this._pathJoin = _.partial(pathJoin, this.directory)
this._joinStatReadAdd = async.seq(this._pathJoin, stat, maybeRead, _.bind(this._addFile, this))
this._joinStatReadUpdate = async.seq(this._pathJoin, stat, maybeRead, _.bind(this._updateFile, this))
this.filter = function(file) { return false }

@@ -69,3 +75,3 @@

/*
initialize the cache
initialize the cache, this will create a new watcher if one wasn't attached first

@@ -82,24 +88,19 @@ @param {Function} initCallback callback for when the initialization completes

var initSequence = [
_.bind(fs.readdir, fs, this.directory),
_.bind(readFiles, null, this.directory),
_.bind(addFiles, this)
]
var done = _.partial(initSequenceDone, this, initCallback)
if (!this._watcher) {
initSequence.push(_.bind(DirectoryWatcher.create, null, this.directory))
initSequence.push(_.bind(this.attachWatcher, this))
}
var attachWatcher = _.bind(this.attachWatcher, this)
var self = this
async.waterfall(initSequence, _.bind(initSequenceDone, this, initCallback))
}
DirectoryWatcher.create(this.directory, function(err, watcher) {
if (err) return done(err)
function initSequenceDone(initCallback, err) {
if (err) {
debug('ERROR: %s', err.message)
initCallback(err)
attachWatcher(watcher)
mapFiles(self._joinStatReadAdd, watcher.files, done)
})
} else {
debug('cache initialized successfully')
initCallback(null, this)
mapFiles(this._joinStatReadAdd, this._watcher.files, done)
}

@@ -109,21 +110,66 @@ }

/*
stop this cache, freezing its current state
*/
DirectoryCache.prototype.stop = function() {
if (this.watcher) {
this.watcher.removeAllListeners('add')
this.watcher.removeAllListeners('change')
this.watcher.removeAllListeners('delete')
this.watcher.kill()
}
}
/*
get an array of the names of all the files in the cached directory
@returns {Array}
*/
DirectoryCache.prototype.getFilenames = function() {
return _.keys(this.cache)
}
/*
@param {String} file name of the file to delete
@returns {String|Buffer} contents of the file from the cache or undefined if its not there
*/
DirectoryCache.prototype.getFile = function(file) {
return this.cache[file]
}
/*
disable automatic json parsing
*/
DirectoryCache.prototype.disableJsonParsing = function() {
this.parseJson = false
}
/*
enable automatic json parsing
*/
DirectoryCache.prototype.enableJsonParsing = function() {
this.parseJson = true
}
/*
attach a watcher to this cache, this is an optional method. init() will
create a new watcher attachWatcher() is never called
create a new watcher if attachWatcher() is never called
@param {DirectoryWatcher} watcher a DirectoryWatcher instance (directory-watcher on npm)
@param {Function} _callback api
*/
DirectoryCache.prototype.attachWatcher = function(watcher, _callback) {
var read = _.bind(readFiles, null, this.directory)
var update = _.bind(updateFiles, this)
var add = _.bind(addFiles, this)
DirectoryCache.prototype.attachWatcher = function(watcher) {
var deleteOne = _.bind(this._deleteFile, this)
var handleError = _.bind(maybeEmitError, this)
watcher.on('add', function (files) {
async.waterfall([_.bind(read, null, files), add], handleError)
var maybeEmitError = _.bind(this._maybeEmitError, this)
var self = this
watcher.on('add', function (files) {
mapFiles(self._joinStatReadAdd, files, maybeEmitError)
})
watcher.on('change', function (files) {
async.waterfall([_.bind(read, null, files), update], handleError)
mapFiles(self._joinStatReadUpdate, files, maybeEmitError)
})

@@ -134,37 +180,22 @@

})
watcher.on('error', maybeEmitError)
this._watcher = watcher
if (_callback)
_callback(null)
}
/*
get an array of the names of all the files in the cached directory
add a file to the cache,
the file must reside in the cache directory (this is not enforced)
@returns {Array}
*/
DirectoryCache.prototype.getFilenames = function() {
return _.keys(this.cache)
}
/*
stop this cache, freezing its current state
*/
DirectoryCache.prototype.stop = function() {
if (this.watcher) {
this.watcher.kill()
}
}
/*
add a file to the cache, the file most reside in the cache directory (this is not validated)
@private
@param {String} file name of the file
@param {String|Buffer} data initial value of the file content to cache
@param {fs.Stat} stat a stat object
@param {Function} callback
*/
DirectoryCache.prototype._addFile = function(file, data) {
debug('adding %s', file)
DirectoryCache.prototype._addFile = function(file, data, stat, callback) {
debug('_addFile( %s, %s)', file, data)
data = this._cacheFile(file, data)

@@ -175,6 +206,10 @@

this.emit('add', file, data)
callback(null)
}
/*
update a file in the cache, the file most reside in the cache directory (this is not validated)
update a file in the cache,
the file must reside in the cache directory (this is not enforced)
the file must already exist in the cache (enforced)

@@ -184,5 +219,7 @@ @private

@param {String|Buffer} data updated value of the file content to cache
@param {fs.Stat} stat a stat object
@param {Function} callback
*/
DirectoryCache.prototype._updateFile = function(file, data) {
debug('updating %s', file)
DirectoryCache.prototype._updateFile = function(file, data, stat, callback) {
debug('_updateFile( %s, %s )', file, data)

@@ -194,2 +231,4 @@ if (!file in this.cache) throw new Error('cannot update a new file, use _addFile() instead')

this.emit('update', file, data)
callback(null)
}

@@ -218,25 +257,3 @@

/*
@param {String} file name of the file to delete
@returns {String|Buffer} contents of the file from the cache or undefined if its not there
*/
DirectoryCache.prototype.getFile = function(file) {
return this.cache[file]
}
/*
disable automatic json parsing
*/
DirectoryCache.prototype.disableJsonParsing = function() {
this.parseJson = false
}
/*
enable automatic json parsing
*/
DirectoryCache.prototype.enableJsonParsing = function() {
this.parseJson = true
}
/*
caching implementation, used by _addFile and _updateFile

@@ -261,3 +278,3 @@

function maybeEmitError(err) {
DirectoryCache.prototype._maybeEmitError = function(err) {
if (err)

@@ -267,41 +284,90 @@ this.emit('error', err)

function readFiles(directory, files, callback) {
debug('reading files')
/*
used as a subtask in asyncs to do stuff on files
var functors = {}
@param {Function}
@param {Array} files
@param {Function} callback
for (var i = 0; i < files.length; i++)
functors[files[i]] = _.bind(fs.readFile, fs, path.join(directory, files[i]))
@private
*/
function mapFiles(operation, files, callback) {
debug('mapFiles(...)')
async.parallel(functors, callback)
async.map(files, operation, callback)
}
function addFiles(files, callback) {
debug('adding files')
/*
path join for async flows
*/
function pathJoin(directory, file, callback) {
debug('pathJoin(%s, %s)', directory, file)
callback(null, path.join(directory, file), file)
}
/*
for (var file in files) {
var data = files[file]
@param {String} fullpath full path to a file
@param {String} file basename
@param {Function} callback
this._addFile(file, data)
}
@private
*/
function stat(fullpath, file, callback) {
debug('stat(%s, %s)', fullpath, file)
fs.stat(fullpath, function(err, stat) {
if (err) return callback(err)
if (callback)
callback(null)
callback(null, fullpath, file, stat)
})
}
function updateFiles(files, callback) {
debug('updating files')
/*
maybe read a file if indeed its a normal file
@param {String} fullpath full path to a file
@param {String} file basename
@param {fs.Stat} stat an fs.Stat object
@param {Function} callback
@private
*/
function maybeRead(fullpath, file, stat, callback) {
for (var file in files) {
var data = files[file]
if (stat.isFile()) {
fs.readFile(fullpath, function(err, content) {
if (err) return callback(err)
this._updateFile(file, data)
callback(null, file, content, stat)
})
} else {
callback(null, file, undefined, stat)
}
}
if (callback)
callback(null)
/*
init help
@private
*/
function initSequenceDone(cache, initCallback, err) {
if (err) {
debug('ERROR: %s', err.message)
initCallback(err)
} else {
debug('cache initialized successfully')
initCallback(null, cache)
}
}
/*
checks if a file has a .json extension
@param {String} filename the name of the file
@private
*/
function isJsonFile(filename) {
return filename.slice(-5).toLowerCase() === '.json'
}
{
"name": "directory-cache",
"version": "2.0.3",
"version": "3.0.1",
"description": "A directory cache + watch util",

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

@@ -8,2 +8,4 @@ var assert = require('assert')

var fs = require('fs')
var EventEmitter = require('events').EventEmitter
var TEST_DIR = path.join(__dirname, 'testdir')

@@ -16,5 +18,11 @@ var testNumber = 0

var mockWatcher
beforeEach(function (done) {
testNumber++
mockWatcher = new EventEmitter()
mockWatcher.files = ['1.json']
currentTestDir = TEST_DIR + testNumber.toString()

@@ -49,3 +57,3 @@

it('loads the content of the files in the target directory when created', function () {
it('loads the content of the files in the target directory when created', function () {
assert.deepEqual(cache.cache['1.json'], { a: 1 })

@@ -55,2 +63,38 @@ assert.strictEqual(cache.count, 1)

it('can use an external watcher, attached before initialization', function (done) {
var cache2 = DirectoryCache.create(currentTestDir)
cache2.attachWatcher(mockWatcher)
cache2.init(function(err) {
if (err) done(err)
cache2.on('update', function(file, data) {
assert.strictEqual(file, '1.json')
done()
})
mockWatcher.emit('change', ['1.json'])
})
})
it('can use an external watcher, attached after initialization', function(done) {
cache.attachWatcher(mockWatcher)
cache.on('update', function(file, data) {
assert.strictEqual(file, '1.json')
done()
})
mockWatcher.emit('change', ['1.json'])
})
it('emits error events', function (done) {
cache.attachWatcher(mockWatcher)
cache.on('error', function(err) {
assert.ok(err instanceof Error)
done()
})
mockWatcher.emit('error', new Error())
})
describe('updates the cache when', function () {

@@ -100,2 +144,16 @@ it('files are added', function (done) {

})
it('files that are not normal files raise events but without data', function(done) {
assert.strictEqual(cache.count, 1)
cache.on('add', function(file, data) {
assert.ok(data === undefined)
assert.strictEqual(file, 'moo')
done()
})
fs.mkdir(path.join(currentTestDir, 'moo'), function(err) {
if (err) return done(err)
})
})
})

@@ -102,0 +160,0 @@ })

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