key-file-storage
Advanced tools
Comparing version 2.2.7 to 2.2.8
@@ -35,3 +35,3 @@ "use strict"; | ||
var file = path_1.join(kfsPath, key); | ||
fs_extra_1.outputJsonSync(file, value); | ||
fs_extra_1.outputJsonSync(file, value, { spaces: 2 }); | ||
return (cache[key] = value); | ||
@@ -87,3 +87,3 @@ } | ||
return new Promise(function (resolve, reject) { | ||
fs_extra_1.outputJson(file, value, function (err) { | ||
fs_extra_1.outputJson(file, value, { spaces: 2 }, function (err) { | ||
if (err) | ||
@@ -90,0 +90,0 @@ return reject(err); |
{ | ||
"name": "key-file-storage", | ||
"version": "2.2.7", | ||
"version": "2.2.8", | ||
"description": "Simple key-value storage directly on file system, maps each key to a separate file.", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -1,186 +0,204 @@ | ||
"use strict"; | ||
'use strict'; | ||
exports.__esModule = true; | ||
function createCache(cacheConfig) { | ||
if (cacheConfig === true || typeof cacheConfig === 'undefined') { | ||
// Unlimited cache by default | ||
return createCache_Unlimited(cacheConfig); | ||
} | ||
else if (cacheConfig === false) { | ||
// No cache | ||
return createCache_NoCache(cacheConfig); | ||
} | ||
else if (typeof cacheConfig === 'number' && cacheConfig > 0) { | ||
// Limited cache by the number of keys | ||
return createCache_LimitedByKeyCount(cacheConfig); | ||
} | ||
else { | ||
throw new Error('Invalid cache config.'); | ||
} | ||
function createCache_Unlimited(cacheConfig) { | ||
var collectionCache = {}; | ||
return new Proxy({ | ||
if (cacheConfig === true || typeof cacheConfig === 'undefined') { | ||
// Unlimited cache by default | ||
return createCache_Unlimited(cacheConfig); | ||
} else if (cacheConfig === false) { | ||
// No cache | ||
return createCache_NoCache(cacheConfig); | ||
} else if (typeof cacheConfig === 'number' && cacheConfig > 0) { | ||
// Limited cache by the number of keys | ||
return createCache_LimitedByKeyCount(cacheConfig); | ||
} else { | ||
throw new Error('Invalid cache config.'); | ||
} | ||
function createCache_Unlimited(cacheConfig) { | ||
var collectionCache = {}; | ||
return new Proxy( | ||
{ | ||
/*CACHE*/ | ||
}, { | ||
set: function (target, property, value, receiver) { | ||
var propertyName = String(property); | ||
if (propertyName.endsWith('/')) { | ||
collectionCache[propertyName] = value; | ||
return true; | ||
} | ||
target[propertyName] = value; | ||
Object.keys(collectionCache) | ||
.filter(function (collection) { return keyInCollection(propertyName, collection); }) | ||
.forEach(function (collection) { | ||
return collectionCache[collection].includes(propertyName) || collectionCache[collection].push(propertyName); | ||
}); | ||
return true; | ||
}, | ||
get: function (target, property, receiver) { | ||
var propertyName = String(property); | ||
if (propertyName.endsWith('/')) | ||
return collectionCache[propertyName]; | ||
return target[propertyName]; | ||
}, | ||
deleteProperty: function (target, property) { | ||
var propertyName = String(property); | ||
if (propertyName === '*') { | ||
collectionCache = {}; | ||
Object.keys(target).forEach(function (key) { return delete target[key]; }); | ||
return true; | ||
} | ||
if (propertyName.endsWith('/')) | ||
return delete collectionCache[propertyName]; | ||
Object.keys(collectionCache) | ||
.filter(function (collection) { return keyInCollection(propertyName, collection); }) | ||
.forEach(function (collection) { | ||
return collectionCache[collection].includes(propertyName) && | ||
collectionCache[collection].splice(collectionCache[collection].indexOf(propertyName), 1); | ||
}); | ||
return delete target[propertyName]; | ||
}, | ||
has: function (target, property) { | ||
var propertyName = String(property); | ||
if (propertyName.endsWith('/')) | ||
return propertyName in collectionCache; | ||
return property in target; | ||
} | ||
}); | ||
} | ||
function createCache_NoCache(cacheConfig) { | ||
return new Proxy({ | ||
}, | ||
{ | ||
set: function(target, property, value, receiver) { | ||
var propertyName = String(property); | ||
if (propertyName.endsWith('/')) { | ||
collectionCache[propertyName] = value; | ||
return true; | ||
} | ||
target[propertyName] = value; | ||
Object.keys(collectionCache) | ||
.filter(function(collection) { | ||
return keyInCollection(propertyName, collection); | ||
}) | ||
.forEach(function(collection) { | ||
return ( | ||
collectionCache[collection].includes(propertyName) || collectionCache[collection].push(propertyName) | ||
); | ||
}); | ||
return true; | ||
}, | ||
get: function(target, property, receiver) { | ||
var propertyName = String(property); | ||
if (propertyName.endsWith('/')) return collectionCache[propertyName]; | ||
return target[propertyName]; | ||
}, | ||
deleteProperty: function(target, property) { | ||
var propertyName = String(property); | ||
if (propertyName === '*') { | ||
collectionCache = {}; | ||
Object.keys(target).forEach(function(key) { | ||
return delete target[key]; | ||
}); | ||
return true; | ||
} | ||
if (propertyName.endsWith('/')) return delete collectionCache[propertyName]; | ||
Object.keys(collectionCache) | ||
.filter(function(collection) { | ||
return keyInCollection(propertyName, collection); | ||
}) | ||
.forEach(function(collection) { | ||
return ( | ||
collectionCache[collection].includes(propertyName) && | ||
collectionCache[collection].splice(collectionCache[collection].indexOf(propertyName), 1) | ||
); | ||
}); | ||
return delete target[propertyName]; | ||
}, | ||
has: function(target, property) { | ||
var propertyName = String(property); | ||
if (propertyName.endsWith('/')) return propertyName in collectionCache; | ||
return property in target; | ||
}, | ||
}, | ||
); | ||
} | ||
function createCache_NoCache(cacheConfig) { | ||
return new Proxy( | ||
{ | ||
/*CACHE*/ | ||
}, { | ||
set: function (target, property, value, receiver) { | ||
return true; | ||
}, | ||
get: function (target, property, receiver) { | ||
return undefined; | ||
}, | ||
deleteProperty: function (target, property) { | ||
return true; | ||
}, | ||
has: function (target, property) { | ||
return false; | ||
} | ||
}); | ||
}, | ||
{ | ||
set: function(target, property, value, receiver) { | ||
return true; | ||
}, | ||
get: function(target, property, receiver) { | ||
return undefined; | ||
}, | ||
deleteProperty: function(target, property) { | ||
return true; | ||
}, | ||
has: function(target, property) { | ||
return false; | ||
}, | ||
}, | ||
); | ||
} | ||
function createCache_LimitedByKeyCount(cacheConfig) { | ||
var collectionCache = {}; | ||
var keyNumber = Math.ceil(cacheConfig), | ||
keys = Array(keyNumber), | ||
nextKeyIndex = 0, | ||
keyIndex; | ||
return new Proxy( | ||
{ | ||
/*CACHE*/ | ||
}, | ||
{ | ||
set: function(target, property, value, receiver) { | ||
var propertyName = String(property); | ||
if (propertyName.endsWith('/')) { | ||
collectionCache[propertyName] = value; | ||
return true; | ||
} | ||
updateKeys(target, propertyName, 'SET'); | ||
target[propertyName] = value; | ||
Object.keys(collectionCache) | ||
.filter(function(collection) { | ||
return keyInCollection(propertyName, collection); | ||
}) | ||
.forEach(function(collection) { | ||
return ( | ||
collectionCache[collection].includes(propertyName) || collectionCache[collection].push(propertyName) | ||
); | ||
}); | ||
return true; | ||
}, | ||
get: function(target, property, receiver) { | ||
var propertyName = String(property); | ||
if (propertyName.endsWith('/')) return collectionCache[propertyName]; | ||
updateKeys(target, propertyName, 'GET'); | ||
return target[propertyName]; | ||
}, | ||
deleteProperty: function(target, property) { | ||
var propertyName = String(property); | ||
if (propertyName === '*') { | ||
collectionCache = {}; | ||
keys = Array(keyNumber); | ||
nextKeyIndex = 0; | ||
return true; | ||
} | ||
if (propertyName.endsWith('/')) return delete collectionCache[propertyName]; | ||
Object.keys(collectionCache) | ||
.filter(function(collection) { | ||
return keyInCollection(propertyName, collection); | ||
}) | ||
.forEach(function(collection) { | ||
return ( | ||
collectionCache[collection].includes(propertyName) && | ||
collectionCache[collection].splice(collectionCache[collection].indexOf(propertyName), 1) | ||
); | ||
}); | ||
updateKeys(target, propertyName, 'DELETE'); | ||
return delete target[propertyName]; | ||
}, | ||
has: function(target, property) { | ||
var propertyName = String(property); | ||
if (propertyName.endsWith('/')) return propertyName in collectionCache; | ||
return keys.indexOf(property) >= 0; | ||
}, | ||
}, | ||
); | ||
function realIndex(i) { | ||
return (i + keyNumber) % keyNumber; | ||
} | ||
function createCache_LimitedByKeyCount(cacheConfig) { | ||
var collectionCache = {}; | ||
var keyNumber = Math.ceil(cacheConfig), keys = Array(keyNumber), nextKeyIndex = 0, keyIndex; | ||
return new Proxy({ | ||
/*CACHE*/ | ||
}, { | ||
set: function (target, property, value, receiver) { | ||
var propertyName = String(property); | ||
if (propertyName.endsWith('/')) { | ||
collectionCache[propertyName] = value; | ||
return true; | ||
} | ||
updateKeys(target, propertyName, 'SET'); | ||
target[propertyName] = value; | ||
Object.keys(collectionCache) | ||
.filter(function (collection) { return keyInCollection(propertyName, collection); }) | ||
.forEach(function (collection) { | ||
return collectionCache[collection].includes(propertyName) || collectionCache[collection].push(propertyName); | ||
}); | ||
return true; | ||
}, | ||
get: function (target, property, receiver) { | ||
var propertyName = String(property); | ||
if (propertyName.endsWith('/')) | ||
return collectionCache[propertyName]; | ||
updateKeys(target, propertyName, 'GET'); | ||
return target[propertyName]; | ||
}, | ||
deleteProperty: function (target, property) { | ||
var propertyName = String(property); | ||
if (propertyName === '*') { | ||
collectionCache = {}; | ||
keys = Array(keyNumber); | ||
nextKeyIndex = 0; | ||
return true; | ||
} | ||
if (propertyName.endsWith('/')) | ||
return delete collectionCache[propertyName]; | ||
Object.keys(collectionCache) | ||
.filter(function (collection) { return keyInCollection(propertyName, collection); }) | ||
.forEach(function (collection) { | ||
return collectionCache[collection].includes(propertyName) && | ||
collectionCache[collection].splice(collectionCache[collection].indexOf(propertyName), 1); | ||
}); | ||
updateKeys(target, propertyName, 'DELETE'); | ||
return delete target[propertyName]; | ||
}, | ||
has: function (target, property) { | ||
var propertyName = String(property); | ||
if (propertyName.endsWith('/')) | ||
return propertyName in collectionCache; | ||
return keys.indexOf(property) >= 0; | ||
} | ||
}); | ||
function realIndex(i) { | ||
return (i + keyNumber) % keyNumber; | ||
function updateKeys(target, property, mode) { | ||
keyIndex = keys.indexOf(property); | ||
if (keyIndex < 0) { | ||
// Does not exist | ||
mode === 'SET' && addKey(); | ||
} else if (keyIndex === realIndex(nextKeyIndex - 1)) { | ||
// The latest key | ||
mode === 'DELETE' && removeKey(); | ||
} else { | ||
// Otherwise | ||
removeKey(); | ||
mode === 'DELETE' || addKey(); | ||
} | ||
function removeKey() { | ||
while (keyIndex !== nextKeyIndex && keys[keyIndex]) { | ||
keys[keyIndex] = keys[realIndex(keyIndex - 1)]; | ||
keyIndex = realIndex(keyIndex - 1); | ||
} | ||
function updateKeys(target, property, mode) { | ||
keyIndex = keys.indexOf(property); | ||
if (keyIndex < 0) { | ||
// Does not exist | ||
mode === 'SET' && addKey(); | ||
} | ||
else if (keyIndex === realIndex(nextKeyIndex - 1)) { | ||
// The latest key | ||
mode === 'DELETE' && removeKey(); | ||
} | ||
else { | ||
// Otherwise | ||
removeKey(); | ||
mode === 'DELETE' || addKey(); | ||
} | ||
function removeKey() { | ||
while (keyIndex !== nextKeyIndex && keys[keyIndex]) { | ||
keys[keyIndex] = keys[realIndex(keyIndex - 1)]; | ||
keyIndex = realIndex(keyIndex - 1); | ||
} | ||
keys[nextKeyIndex] = undefined; | ||
} | ||
function addKey() { | ||
if (keys[nextKeyIndex] !== property) { | ||
if (keys[nextKeyIndex] !== undefined) | ||
delete target[keys[nextKeyIndex]]; | ||
keys[nextKeyIndex] = property; | ||
} | ||
nextKeyIndex = realIndex(nextKeyIndex + 1); | ||
} | ||
keys[nextKeyIndex] = undefined; | ||
} | ||
function addKey() { | ||
if (keys[nextKeyIndex] !== property) { | ||
if (keys[nextKeyIndex] !== undefined) delete target[keys[nextKeyIndex]]; | ||
keys[nextKeyIndex] = property; | ||
} | ||
nextKeyIndex = realIndex(nextKeyIndex + 1); | ||
} | ||
} | ||
function keyInCollection(key, collection) { | ||
collection = collection.startsWith('./') | ||
? collection.slice(1) | ||
: collection.startsWith('/') | ||
? collection | ||
: '/' + collection; | ||
key = key.startsWith('./') ? key.slice(1) : key.startsWith('/') ? key : '/' + key; | ||
return key.startsWith(collection); | ||
} | ||
} | ||
function keyInCollection(key, collection) { | ||
collection = collection.startsWith('./') | ||
? collection.slice(1) | ||
: collection.startsWith('/') | ||
? collection | ||
: '/' + collection; | ||
key = key.startsWith('./') ? key.slice(1) : key.startsWith('/') ? key : '/' + key; | ||
return key.startsWith(collection); | ||
} | ||
} | ||
exports["default"] = createCache; | ||
exports['default'] = createCache; |
@@ -1,240 +0,215 @@ | ||
"use strict"; | ||
'use strict'; | ||
exports.__esModule = true; | ||
var fs_extra_1 = require("fs-extra"); | ||
var path_1 = require("path"); | ||
var fs_extra_1 = require('fs-extra'); | ||
var path_1 = require('path'); | ||
var isValidPath = require('is-valid-path'); | ||
var recurFs = require('recur-fs'); | ||
function keyFileBasic(kfsPath, cache) { | ||
kfsPath = kfsPath || __dirname; // Current working folder by default. | ||
kfsPath = String(kfsPath); | ||
if (!isValidPath(kfsPath)) { | ||
throw new Error('Invalid stroage path.'); | ||
kfsPath = kfsPath || __dirname; // Current working folder by default. | ||
kfsPath = String(kfsPath); | ||
if (!isValidPath(kfsPath)) { | ||
throw new Error('Invalid stroage path.'); | ||
} | ||
return { | ||
// Synchronous | ||
setSync: setSync, | ||
getSync: getSync, | ||
deleteSync: deleteSync, | ||
clearSync: clearSync, | ||
hasSync: hasSync, | ||
// Asynchronous | ||
setAsync: setAsync, | ||
getAsync: getAsync, | ||
deleteAsync: deleteAsync, | ||
clearAsync: clearAsync, | ||
hasAsync: hasAsync, | ||
// Iterate | ||
querySync: querySync, | ||
queryAsync: queryAsync, | ||
}; | ||
function setSync(key, value) { | ||
if (value === undefined) return deleteSync(key); | ||
key = validizeKey(key); | ||
var file = path_1.join(kfsPath, key); | ||
fs_extra_1.outputJsonSync(file, value, { spaces: 2 }); | ||
return (cache[key] = value); | ||
} | ||
function getSync(key) { | ||
key = validizeKey(key); | ||
if (key in cache) return cache[key]; | ||
var file = path_1.join(kfsPath, key); | ||
try { | ||
var status = fs_extra_1.statSync(file); | ||
if (!status || !status.isFile()) return (cache[key] = null); | ||
} catch (err) { | ||
return (cache[key] = null); | ||
} | ||
return { | ||
// Synchronous | ||
setSync: setSync, | ||
getSync: getSync, | ||
deleteSync: deleteSync, | ||
clearSync: clearSync, | ||
hasSync: hasSync, | ||
// Asynchronous | ||
setAsync: setAsync, | ||
getAsync: getAsync, | ||
deleteAsync: deleteAsync, | ||
clearAsync: clearAsync, | ||
hasAsync: hasAsync, | ||
// Iterate | ||
querySync: querySync, | ||
queryAsync: queryAsync | ||
}; | ||
function setSync(key, value) { | ||
if (value === undefined) | ||
return deleteSync(key); | ||
key = validizeKey(key); | ||
var file = path_1.join(kfsPath, key); | ||
fs_extra_1.outputJsonSync(file, value); | ||
return (cache[key] = value); | ||
return (cache[key] = fs_extra_1.readJsonSync(file)); | ||
} | ||
function deleteSync(key) { | ||
key = validizeKey(key); | ||
if (key === '*') return clearSync(); | ||
var file = path_1.join(kfsPath, key); | ||
fs_extra_1.removeSync(file); | ||
return delete cache[key]; | ||
} | ||
function clearSync() { | ||
fs_extra_1.removeSync(kfsPath); | ||
return delete cache['*']; | ||
} | ||
function hasSync(key) { | ||
key = validizeKey(key); | ||
if (key in cache) return true; | ||
var file = path_1.join(kfsPath, key); | ||
try { | ||
var status = fs_extra_1.statSync(file); | ||
if (!status || !status.isFile()) return false; | ||
} catch (err) { | ||
return false; | ||
} | ||
function getSync(key) { | ||
key = validizeKey(key); | ||
if (key in cache) | ||
return cache[key]; | ||
var file = path_1.join(kfsPath, key); | ||
try { | ||
var status = fs_extra_1.statSync(file); | ||
if (!status || !status.isFile()) | ||
return (cache[key] = null); | ||
} | ||
catch (err) { | ||
return (cache[key] = null); | ||
} | ||
return (cache[key] = fs_extra_1.readJsonSync(file)); | ||
} | ||
function deleteSync(key) { | ||
key = validizeKey(key); | ||
if (key === '*') | ||
return clearSync(); | ||
var file = path_1.join(kfsPath, key); | ||
fs_extra_1.removeSync(file); | ||
return delete cache[key]; | ||
} | ||
function clearSync() { | ||
fs_extra_1.removeSync(kfsPath); | ||
return delete cache['*']; | ||
} | ||
function hasSync(key) { | ||
key = validizeKey(key); | ||
if (key in cache) | ||
return true; | ||
var file = path_1.join(kfsPath, key); | ||
try { | ||
var status = fs_extra_1.statSync(file); | ||
if (!status || !status.isFile()) | ||
return false; | ||
} | ||
catch (err) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
function setAsync(key, value) { | ||
if (value === undefined) | ||
return deleteAsync(key); | ||
key = validizeKey(key); | ||
var file = path_1.join(kfsPath, key); | ||
return new Promise(function (resolve, reject) { | ||
fs_extra_1.outputJson(file, value, function (err) { | ||
if (err) | ||
return reject(err); | ||
resolve((cache[key] = value)); | ||
}); | ||
return true; | ||
} | ||
function setAsync(key, value) { | ||
if (value === undefined) return deleteAsync(key); | ||
key = validizeKey(key); | ||
var file = path_1.join(kfsPath, key); | ||
return new Promise(function(resolve, reject) { | ||
fs_extra_1.outputJson(file, value, { spaces: 2 }, function(err) { | ||
if (err) return reject(err); | ||
resolve((cache[key] = value)); | ||
}); | ||
}); | ||
} | ||
function getAsync(key) { | ||
key = validizeKey(key); | ||
if (key in cache) return Promise.resolve(cache[key]); | ||
var file = path_1.join(kfsPath, key); | ||
return new Promise(function(resolve, reject) { | ||
fs_extra_1.stat(file, function(err, status) { | ||
if (err || !status || !status.isFile()) return resolve((cache[key] = null)); | ||
fs_extra_1.readJson(file, function(err, value) { | ||
if (err) return reject(err); | ||
resolve((cache[key] = value)); | ||
}); | ||
}); | ||
}); | ||
} | ||
function deleteAsync(key) { | ||
key = validizeKey(key); | ||
if (key === '*') return clearAsync(); | ||
var file = path_1.join(kfsPath, key); | ||
return new Promise(function(resolve, reject) { | ||
fs_extra_1.remove(file, function(err) { | ||
if (err) return reject(err); | ||
resolve(delete cache[key]); | ||
}); | ||
}); | ||
} | ||
function clearAsync() { | ||
return new Promise(function(resolve, reject) { | ||
fs_extra_1.remove(kfsPath, function(err) { | ||
if (err) return reject(err); | ||
resolve(delete cache['*']); | ||
}); | ||
}); | ||
} | ||
function hasAsync(key) { | ||
key = validizeKey(key); | ||
if (key in cache) return Promise.resolve(true); | ||
var file = path_1.join(kfsPath, key); | ||
return new Promise(function(resolve, reject) { | ||
fs_extra_1.stat(file, function(err, status) { | ||
resolve(!!(!err && status && status.isFile())); | ||
}); | ||
}); | ||
} | ||
function querySync(collection) { | ||
collection = validizeKey(collection); | ||
if (collection in cache) return cache[collection]; | ||
try { | ||
var collectionPath = path_1.join(kfsPath, collection); | ||
var files = recurFs.readdir.sync(collectionPath, function(resource, status) { | ||
return status.isFile(); | ||
}); | ||
files = files.map(function(file) { | ||
return validizeKey(path_1.relative(kfsPath, file)); | ||
}); | ||
return (cache[collection] = files || []); | ||
} catch (err) { | ||
return []; | ||
} | ||
function getAsync(key) { | ||
key = validizeKey(key); | ||
if (key in cache) | ||
return Promise.resolve(cache[key]); | ||
var file = path_1.join(kfsPath, key); | ||
return new Promise(function (resolve, reject) { | ||
fs_extra_1.stat(file, function (err, status) { | ||
if (err || !status || !status.isFile()) | ||
return resolve((cache[key] = null)); | ||
fs_extra_1.readJson(file, function (err, value) { | ||
if (err) | ||
return reject(err); | ||
resolve((cache[key] = value)); | ||
}); | ||
}); | ||
}); | ||
} | ||
function deleteAsync(key) { | ||
key = validizeKey(key); | ||
if (key === '*') | ||
return clearAsync(); | ||
var file = path_1.join(kfsPath, key); | ||
return new Promise(function (resolve, reject) { | ||
fs_extra_1.remove(file, function (err) { | ||
if (err) | ||
return reject(err); | ||
resolve(delete cache[key]); | ||
}); | ||
}); | ||
} | ||
function clearAsync() { | ||
return new Promise(function (resolve, reject) { | ||
fs_extra_1.remove(kfsPath, function (err) { | ||
if (err) | ||
return reject(err); | ||
resolve(delete cache['*']); | ||
}); | ||
}); | ||
} | ||
function hasAsync(key) { | ||
key = validizeKey(key); | ||
if (key in cache) | ||
return Promise.resolve(true); | ||
var file = path_1.join(kfsPath, key); | ||
return new Promise(function (resolve, reject) { | ||
fs_extra_1.stat(file, function (err, status) { | ||
resolve(!!(!err && status && status.isFile())); | ||
}); | ||
}); | ||
} | ||
function querySync(collection) { | ||
collection = validizeKey(collection); | ||
if (collection in cache) | ||
return cache[collection]; | ||
try { | ||
var collectionPath = path_1.join(kfsPath, collection); | ||
var files = recurFs.readdir.sync(collectionPath, function (resource, status) { | ||
return status.isFile(); | ||
}); | ||
files = files.map(function (file) { return validizeKey(path_1.relative(kfsPath, file)); }); | ||
return (cache[collection] = files || []); | ||
} | ||
function queryAsync(collection) { | ||
collection = validizeKey(collection); | ||
if (collection in cache) return Promise.resolve(cache[collection]); | ||
return new Promise(function(resolve, reject) { | ||
//// This implementation does not work with empty folders: | ||
// recurFs.readdir(collection, function(resource, status, next) { | ||
// next(status.isFile()); | ||
// }, function(err, resources) { | ||
// if (err) { | ||
// reject(err); | ||
// } | ||
// else { | ||
// resolve(resources.map(file => path.relative(kfsPath, file))); | ||
// } | ||
// }); | ||
var fileList = [], | ||
jobNumber = 1, | ||
terminated = false; | ||
var collectionPath = path_1.join(kfsPath, collection); | ||
fs_extra_1.stat(collectionPath, function(err, status) { | ||
if (err) { | ||
if (err.code === 'ENOENT') resolve((cache[collection] = [])); | ||
else reject(err); | ||
} else { | ||
processFolder(collection); | ||
} | ||
catch (err) { | ||
return []; | ||
} | ||
} | ||
function queryAsync(collection) { | ||
collection = validizeKey(collection); | ||
if (collection in cache) | ||
return Promise.resolve(cache[collection]); | ||
return new Promise(function (resolve, reject) { | ||
//// This implementation does not work with empty folders: | ||
// recurFs.readdir(collection, function(resource, status, next) { | ||
// next(status.isFile()); | ||
// }, function(err, resources) { | ||
// if (err) { | ||
// reject(err); | ||
// } | ||
// else { | ||
// resolve(resources.map(file => path.relative(kfsPath, file))); | ||
// } | ||
// }); | ||
var fileList = [], jobNumber = 1, terminated = false; | ||
var collectionPath = path_1.join(kfsPath, collection); | ||
fs_extra_1.stat(collectionPath, function (err, status) { | ||
if (err) { | ||
if (err.code === 'ENOENT') | ||
resolve((cache[collection] = [])); | ||
else | ||
reject(err); | ||
} | ||
else { | ||
processFolder(collection); | ||
} | ||
}); | ||
function processFolder(folder) { | ||
if (terminated) return; | ||
var folderPath = path_1.join(kfsPath, folder); | ||
fs_extra_1.readdir(folderPath, function(err, files) { | ||
if (terminated) return; | ||
jobNumber--; | ||
if (err) { | ||
terminated = true; | ||
reject(err); | ||
} | ||
jobNumber += files.length; | ||
if (!jobNumber) { | ||
resolve((cache[collection] = fileList)); | ||
} | ||
files.forEach(function(file) { | ||
if (terminated) return; | ||
var filePath = path_1.join(folderPath, file); | ||
fs_extra_1.stat(filePath, function(err, status) { | ||
if (terminated) return; | ||
jobNumber--; | ||
if (err) { | ||
terminated = true; | ||
reject(err); | ||
} | ||
if (status.isFile()) { | ||
fileList.push(validizeKey(path_1.relative(kfsPath, filePath))); | ||
} else if (status.isDirectory()) { | ||
jobNumber++; | ||
processFolder(filePath); | ||
} | ||
if (!jobNumber) { | ||
resolve((cache[collection] = fileList)); | ||
} | ||
}); | ||
function processFolder(folder) { | ||
if (terminated) | ||
return; | ||
var folderPath = path_1.join(kfsPath, folder); | ||
fs_extra_1.readdir(folderPath, function (err, files) { | ||
if (terminated) | ||
return; | ||
jobNumber--; | ||
if (err) { | ||
terminated = true; | ||
reject(err); | ||
} | ||
jobNumber += files.length; | ||
if (!jobNumber) { | ||
resolve((cache[collection] = fileList)); | ||
} | ||
files.forEach(function (file) { | ||
if (terminated) | ||
return; | ||
var filePath = path_1.join(folderPath, file); | ||
fs_extra_1.stat(filePath, function (err, status) { | ||
if (terminated) | ||
return; | ||
jobNumber--; | ||
if (err) { | ||
terminated = true; | ||
reject(err); | ||
} | ||
if (status.isFile()) { | ||
fileList.push(validizeKey(path_1.relative(kfsPath, filePath))); | ||
} | ||
else if (status.isDirectory()) { | ||
jobNumber++; | ||
processFolder(filePath); | ||
} | ||
if (!jobNumber) { | ||
resolve((cache[collection] = fileList)); | ||
} | ||
}); | ||
}); | ||
}); | ||
} | ||
}); | ||
}); | ||
} | ||
/////////////////////////////////////////////////// | ||
function validizeKey(key) { | ||
key = String(key).replace(/\\/g, '/'); | ||
if (key.includes('/..') || key.includes('../') || key === '..') | ||
throw new Error('Invalid key name.'); | ||
return key; | ||
} | ||
} | ||
}); | ||
} | ||
/////////////////////////////////////////////////// | ||
function validizeKey(key) { | ||
key = String(key).replace(/\\/g, '/'); | ||
if (key.includes('/..') || key.includes('../') || key === '..') throw new Error('Invalid key name.'); | ||
return key; | ||
} | ||
} | ||
exports["default"] = keyFileBasic; | ||
exports['default'] = keyFileBasic; |
@@ -65,3 +65,3 @@ import { | ||
var file = join(kfsPath, key); | ||
outputJsonSync(file, value); | ||
outputJsonSync(file, value, { spaces: 2 }); | ||
return (cache[key] = value); | ||
@@ -114,3 +114,3 @@ } | ||
return new Promise(function(resolve, reject) { | ||
outputJson(file, value, function(err) { | ||
outputJson(file, value, { spaces: 2 }, function(err) { | ||
if (err) return reject(err); | ||
@@ -117,0 +117,0 @@ resolve((cache[key] = value)); |
@@ -1,138 +0,135 @@ | ||
"use strict"; | ||
'use strict'; | ||
exports.__esModule = true; | ||
var key_file_basic_1 = require("./key-file-basic"); | ||
var key_file_basic_1 = require('./key-file-basic'); | ||
function createKfs(kfsPath, cache) { | ||
var kfb = key_file_basic_1["default"](kfsPath, cache); | ||
// The produced promise and callback function related to the latest async 'in' operator | ||
var hasAsyncHandler = null, hasAsyncPromise = null; | ||
/* async has */ | ||
var hasAsyncWrap = { | ||
has: function (target, property) { | ||
var promise = kfb.hasAsync(property); | ||
if (hasAsyncHandler) { | ||
callbackizePromise(promise, hasAsyncHandler); | ||
hasAsyncHandler = null; | ||
var kfb = key_file_basic_1['default'](kfsPath, cache); | ||
// The produced promise and callback function related to the latest async 'in' operator | ||
var hasAsyncHandler = null, | ||
hasAsyncPromise = null; | ||
/* async has */ | ||
var hasAsyncWrap = { | ||
has: function(target, property) { | ||
var promise = kfb.hasAsync(property); | ||
if (hasAsyncHandler) { | ||
callbackizePromise(promise, hasAsyncHandler); | ||
hasAsyncHandler = null; | ||
} else { | ||
hasAsyncPromise = promise; | ||
} | ||
return false; // No synchronous answer. | ||
}, | ||
}; | ||
var kfs = new Proxy( | ||
function() { | ||
var a1 = arguments[0], | ||
a2 = arguments[1], | ||
a3 = arguments[2]; | ||
switch (arguments.length) { | ||
case 0: | ||
if (hasAsyncPromise) { | ||
a3 = hasAsyncPromise; | ||
hasAsyncPromise = null; | ||
return a3; | ||
} else { | ||
return new Proxy({}, hasAsyncWrap); | ||
} | ||
// break; | ||
case 1: | ||
if (typeof a1 === 'function') { | ||
if (hasAsyncPromise) { | ||
a3 = hasAsyncPromise; | ||
hasAsyncPromise = null; | ||
return callbackizePromise(a3, a1); | ||
} else { | ||
hasAsyncHandler = a1; | ||
return new Proxy({}, hasAsyncWrap); | ||
} | ||
else { | ||
hasAsyncPromise = promise; | ||
} else if (String(a1).slice(-1) === '/') { | ||
/* async query pr */ | ||
return kfb.queryAsync(String(a1)); | ||
} else { | ||
/* async get pr */ | ||
return kfb.getAsync(String(a1)); | ||
} | ||
// break; | ||
case 2: | ||
if (typeof a2 === 'function') { | ||
if (String(a1).slice(-1) === '/') { | ||
/* async query cb */ | ||
return callbackizePromise(kfb.queryAsync(String(a1)), a2); | ||
} else { | ||
/* async get cb */ | ||
return callbackizePromise(kfb.getAsync(String(a1)), a2); | ||
} | ||
return false; // No synchronous answer. | ||
} else { | ||
/* async set pr */ | ||
return kfb.setAsync(String(a1), a2); | ||
} | ||
// break; | ||
case 3: | ||
if (typeof a3 === 'function') { | ||
/* async set cb */ | ||
return callbackizePromise(kfb.setAsync(String(a1), a2), a3); | ||
} | ||
// break; | ||
} | ||
throw new Error('Invalid input argument(s).'); | ||
}, | ||
{ | ||
/* sync set */ | ||
set: function(target, property, value, receiver) { | ||
kfb.setSync(String(property), value); | ||
return true; | ||
}, | ||
get: function(target, property, receiver) { | ||
if (String(property).slice(-1) === '/') { | ||
/* sync query */ | ||
return kfb.querySync(String(property)); | ||
} else { | ||
/* sync get */ | ||
return kfb.getSync(String(property)); | ||
} | ||
}; | ||
var kfs = new Proxy(function () { | ||
var a1 = arguments[0], a2 = arguments[1], a3 = arguments[2]; | ||
switch (arguments.length) { | ||
case 0: | ||
if (hasAsyncPromise) { | ||
a3 = hasAsyncPromise; | ||
hasAsyncPromise = null; | ||
return a3; | ||
} | ||
else { | ||
return new Proxy({}, hasAsyncWrap); | ||
} | ||
// break; | ||
case 1: | ||
if (typeof a1 === 'function') { | ||
if (hasAsyncPromise) { | ||
a3 = hasAsyncPromise; | ||
hasAsyncPromise = null; | ||
return callbackizePromise(a3, a1); | ||
} | ||
else { | ||
hasAsyncHandler = a1; | ||
return new Proxy({}, hasAsyncWrap); | ||
} | ||
} | ||
else if (String(a1).slice(-1) === '/') { | ||
/* async query pr */ | ||
return kfb.queryAsync(String(a1)); | ||
} | ||
else { | ||
/* async get pr */ | ||
return kfb.getAsync(String(a1)); | ||
} | ||
// break; | ||
case 2: | ||
if (typeof a2 === 'function') { | ||
if (String(a1).slice(-1) === '/') { | ||
/* async query cb */ | ||
return callbackizePromise(kfb.queryAsync(String(a1)), a2); | ||
} | ||
else { | ||
/* async get cb */ | ||
return callbackizePromise(kfb.getAsync(String(a1)), a2); | ||
} | ||
} | ||
else { | ||
/* async set pr */ | ||
return kfb.setAsync(String(a1), a2); | ||
} | ||
// break; | ||
case 3: | ||
if (typeof a3 === 'function') { | ||
/* async set cb */ | ||
return callbackizePromise(kfb.setAsync(String(a1), a2), a3); | ||
} | ||
// break; | ||
}, | ||
/* sync delete */ | ||
deleteProperty: function(target, property) { | ||
return kfb.deleteSync(String(property)); | ||
}, | ||
/* sync has */ | ||
has: function(target, property) { | ||
return kfb.hasSync(String(property)); | ||
}, | ||
/* async delete */ | ||
construct: function(target, argumentsList, newTarget) { | ||
var a1 = argumentsList[0], | ||
a2 = argumentsList[1]; | ||
switch (argumentsList.length) { | ||
case 0: | ||
return kfb.clearAsync(); | ||
// break; | ||
case 1: | ||
if (typeof a1 === 'function') { | ||
return callbackizePromise(kfb.clearAsync(), a1); | ||
} else { | ||
return kfb.deleteAsync(String(a1)); | ||
} | ||
// break; | ||
case 2: | ||
return callbackizePromise(kfb.deleteAsync(String(a1)), a2); | ||
// break; | ||
} | ||
throw new Error('Invalid input argument(s).'); | ||
}, { | ||
/* sync set */ | ||
set: function (target, property, value, receiver) { | ||
kfb.setSync(String(property), value); | ||
return true; | ||
}, | ||
get: function (target, property, receiver) { | ||
if (String(property).slice(-1) === '/') { | ||
/* sync query */ | ||
return kfb.querySync(String(property)); | ||
} | ||
else { | ||
/* sync get */ | ||
return kfb.getSync(String(property)); | ||
} | ||
}, | ||
/* sync delete */ | ||
deleteProperty: function (target, property) { | ||
return kfb.deleteSync(String(property)); | ||
}, | ||
/* sync has */ | ||
has: function (target, property) { | ||
return kfb.hasSync(String(property)); | ||
}, | ||
/* async delete */ | ||
construct: function (target, argumentsList, newTarget) { | ||
var a1 = argumentsList[0], a2 = argumentsList[1]; | ||
switch (argumentsList.length) { | ||
case 0: | ||
return kfb.clearAsync(); | ||
// break; | ||
case 1: | ||
if (typeof a1 === 'function') { | ||
return callbackizePromise(kfb.clearAsync(), a1); | ||
} | ||
else { | ||
return kfb.deleteAsync(String(a1)); | ||
} | ||
// break; | ||
case 2: | ||
return callbackizePromise(kfb.deleteAsync(String(a1)), a2); | ||
// break; | ||
} | ||
throw new Error('Invalid input argument(s).'); | ||
} | ||
}); | ||
return kfs; | ||
function callbackizePromise(promise, callback) { | ||
if (typeof callback === 'function') { | ||
return promise.then(function (data) { | ||
return callback(undefined, data); | ||
}, callback); | ||
} | ||
else { | ||
return promise; | ||
} | ||
}, | ||
}, | ||
); | ||
return kfs; | ||
function callbackizePromise(promise, callback) { | ||
if (typeof callback === 'function') { | ||
return promise.then(function(data) { | ||
return callback(undefined, data); | ||
}, callback); | ||
} else { | ||
return promise; | ||
} | ||
} | ||
} | ||
exports["default"] = createKfs; | ||
exports['default'] = createKfs; |
"use strict"; | ||
exports.__esModule = true; | ||
var index_1 = require("./index"); | ||
var kfs = index_1["default"]('../../data'); | ||
var kfs = index_1["default"]('../data'); | ||
delete kfs['*']; | ||
@@ -6,0 +6,0 @@ console.log("(kfs.a = 'a') >> ", (kfs.a = 'a')); |
import keyFileStorage from './index'; | ||
const kfs = keyFileStorage('../../data'); | ||
const kfs = keyFileStorage('../data'); | ||
delete kfs['*']; | ||
@@ -5,0 +5,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
74917
1863