file-system-cache
Advanced tools
Comparing version 1.0.5 to 1.1.0
@@ -6,3 +6,2 @@ # Change Log | ||
## [Unreleased] - YYYY-MM-DD | ||
@@ -18,2 +17,14 @@ #### Added | ||
## [2.0.0] - 2022-05-14 | ||
#### Changed | ||
- Converted project to Typescript | ||
#### Fixed | ||
- Update refs (ramda), thanks to @shernaz | ||
## [1.1.0] - 2021-04-04 | ||
#### Changed | ||
- bumped the ramda depedency version to resolve [ReDos](https://security.snyk.io/vuln/SNYK-JS-RAMDA-1582370) | ||
## [1.0.3] - 2016-01-26 | ||
@@ -20,0 +31,0 @@ #### Changed |
551
lib/cache.js
@@ -1,373 +0,224 @@ | ||
'use strict'; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
var _ramda = require('ramda'); | ||
var _ramda2 = _interopRequireDefault(_ramda); | ||
var _bluebird = require('bluebird'); | ||
var _bluebird2 = _interopRequireDefault(_bluebird); | ||
var _fsExtra = require('fs-extra'); | ||
var _fsExtra2 = _interopRequireDefault(_fsExtra); | ||
var _funcs = require('./funcs'); | ||
var f = _interopRequireWildcard(_funcs); | ||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var formatPath = _ramda2.default.pipe(f.ensureString('./.cache'), f.toAbsolutePath); | ||
var toGetValue = function toGetValue(data) { | ||
var type = data.type; | ||
var value = data.value; | ||
if (type === 'Date') { | ||
value = new Date(value); | ||
} | ||
return value; | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var getValueP = function getValueP(path, defaultValue) { | ||
return new _bluebird2.default(function (resolve, reject) { | ||
_fsExtra2.default.readJson(path, function (err, result) { | ||
if (err) { | ||
if (err.code === 'ENOENT') { | ||
resolve(defaultValue); | ||
} else { | ||
reject(err); | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const ramda_1 = __importDefault(require("ramda")); | ||
const fs_extra_1 = __importDefault(require("fs-extra")); | ||
const f = __importStar(require("./funcs")); | ||
const formatPath = ramda_1.default.pipe(f.ensureString('./.cache'), f.toAbsolutePath); | ||
const toGetValue = (data) => { | ||
const { type } = data; | ||
let { value } = data; | ||
if (type === 'Date') { | ||
value = new Date(value); | ||
} | ||
return value; | ||
}; | ||
const getValueP = (path, defaultValue) => new Promise((resolve, reject) => { | ||
fs_extra_1.default.readJson(path, (err, result) => { | ||
if (err) { | ||
if (err.code === 'ENOENT') { | ||
resolve(defaultValue); | ||
} | ||
else { | ||
reject(err); | ||
} | ||
} | ||
} else { | ||
var value = toGetValue(result); | ||
resolve(value); | ||
} | ||
else { | ||
const value = toGetValue(result); | ||
resolve(value); | ||
} | ||
}); | ||
}); | ||
}; | ||
var toJson = function toJson(value) { | ||
return JSON.stringify({ value: value, type: _ramda2.default.type(value) }); | ||
}; | ||
/** | ||
* A cache that read/writes to a specific part of the file-system. | ||
*/ | ||
var FileSystemCache = function () { | ||
/** | ||
* Constructor. | ||
* @param options | ||
* - basePath: The folder path to read/write to. | ||
* Default: './build' | ||
* - ns: A single value, or array, that represents a | ||
* a unique namespace within which values for this | ||
* store are cached. | ||
* - extension: An optional file-extension for paths. | ||
*/ | ||
function FileSystemCache() { | ||
var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
var basePath = _ref.basePath; | ||
var ns = _ref.ns; | ||
var extension = _ref.extension; | ||
_classCallCheck(this, FileSystemCache); | ||
this.basePath = formatPath(basePath); | ||
this.ns = f.hash(ns); | ||
if (f.isString(extension)) { | ||
this.extension = extension; | ||
}); | ||
const toJson = (value) => JSON.stringify({ value, type: ramda_1.default.type(value) }); | ||
class FileSystemCache { | ||
constructor(options = {}) { | ||
this.basePath = formatPath(options.basePath); | ||
this.ns = f.hash(options.ns); | ||
if (f.isString(options.extension)) { | ||
this.extension = options.extension; | ||
} | ||
if (f.isFileSync(this.basePath)) { | ||
throw new Error(`The basePath '${this.basePath}' is a file. It should be a folder.`); | ||
} | ||
} | ||
if (f.isFileSync(this.basePath)) { | ||
throw new Error('The basePath \'' + this.basePath + '\' is a file. It should be a folder.'); | ||
path(key) { | ||
if (f.isNothing(key)) { | ||
throw new Error(`Path requires a cache key.`); | ||
} | ||
let name = f.hash(key); | ||
if (this.ns) { | ||
name = `${this.ns}-${name}`; | ||
} | ||
if (this.extension) { | ||
name = `${name}.${this.extension.replace(/^\./, '')}`; | ||
} | ||
return `${this.basePath}/${name}`; | ||
} | ||
} | ||
/** | ||
* Generates the path to the cached files. | ||
* @param {string} key: The key of the cache item. | ||
* @return {string}. | ||
*/ | ||
_createClass(FileSystemCache, [{ | ||
key: 'path', | ||
value: function path(key) { | ||
if (f.isNothing(key)) { | ||
throw new Error('Path requires a cache key.'); | ||
} | ||
var name = f.hash(key); | ||
if (this.ns) { | ||
name = this.ns + '-' + name; | ||
} | ||
if (this.extension) { | ||
name = name + '.' + this.extension.replace(/^\./, ''); | ||
} | ||
return this.basePath + '/' + name; | ||
fileExists(key) { | ||
return f.existsP(this.path(key)); | ||
} | ||
/** | ||
* Determines whether the file exists. | ||
* @param {string} key: The key of the cache item. | ||
* @return {Promise} | ||
*/ | ||
}, { | ||
key: 'fileExists', | ||
value: function fileExists(key) { | ||
return f.existsP(this.path(key)); | ||
} | ||
/** | ||
* Ensure that the base path exists. | ||
* @return {Promise} | ||
*/ | ||
}, { | ||
key: 'ensureBasePath', | ||
value: function ensureBasePath() { | ||
var _this = this; | ||
return new _bluebird2.default(function (resolve, reject) { | ||
if (_this.basePathExists) { | ||
resolve(); | ||
} else { | ||
_fsExtra2.default.ensureDir(_this.basePath, function (err) { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
_this.basePathExists = true; | ||
resolve(); | ||
ensureBasePath() { | ||
return new Promise((resolve, reject) => { | ||
if (this.basePathExists) { | ||
resolve(); | ||
} | ||
}); | ||
} | ||
}); | ||
else { | ||
fs_extra_1.default.ensureDir(this.basePath, (err) => { | ||
if (err) { | ||
reject(err); | ||
} | ||
else { | ||
this.basePathExists = true; | ||
resolve(); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
/** | ||
* Gets the contents of the file with the given key. | ||
* @param {string} key: The key of the cache item. | ||
* @param defaultValue: Optional. A default value to return if the value does not exist in cache. | ||
* @return {Promise} - File contents, or | ||
* undefined if the file does not exist. | ||
*/ | ||
}, { | ||
key: 'get', | ||
value: function get(key, defaultValue) { | ||
return getValueP(this.path(key), defaultValue); | ||
get(key, defaultValue) { | ||
return getValueP(this.path(key), defaultValue); | ||
} | ||
/** | ||
* Gets the contents of the file with the given key. | ||
* @param {string} key: The key of the cache item. | ||
* @param defaultValue: Optional. A default value to return if the value does not exist in cache. | ||
* @return the cached value, or undefined. | ||
*/ | ||
}, { | ||
key: 'getSync', | ||
value: function getSync(key, defaultValue) { | ||
var path = this.path(key); | ||
return _fsExtra2.default.existsSync(path) ? toGetValue(_fsExtra2.default.readJsonSync(path)) : defaultValue; | ||
getSync(key, defaultValue) { | ||
const path = this.path(key); | ||
return fs_extra_1.default.existsSync(path) ? toGetValue(fs_extra_1.default.readJsonSync(path)) : defaultValue; | ||
} | ||
/** | ||
* Writes the given value to the file-system. | ||
* @param {string} key: The key of the cache item. | ||
* @param value: The value to write (Primitive or Object). | ||
* @return {Promise} | ||
*/ | ||
}, { | ||
key: 'set', | ||
value: function set(key, value) { | ||
var _this2 = this; | ||
var path = this.path(key); | ||
return new _bluebird2.default(function (resolve, reject) { | ||
_this2.ensureBasePath().then(function () { | ||
_fsExtra2.default.outputFile(path, toJson(value), function (err) { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve({ path: path }); | ||
} | ||
}); | ||
}).catch(function (err) { | ||
return reject(err); | ||
set(key, value) { | ||
const path = this.path(key); | ||
return new Promise((resolve, reject) => { | ||
this.ensureBasePath() | ||
.then(() => { | ||
fs_extra_1.default.outputFile(path, toJson(value), (err) => { | ||
if (err) { | ||
reject(err); | ||
} | ||
else { | ||
resolve({ path }); | ||
} | ||
}); | ||
}) | ||
.catch((err) => reject(err)); | ||
}); | ||
}); | ||
} | ||
/** | ||
* Writes the given value to the file-system and memory cache. | ||
* @param {string} key: The key of the cache item. | ||
* @param value: The value to write (Primitive or Object). | ||
* @return the cache. | ||
*/ | ||
}, { | ||
key: 'setSync', | ||
value: function setSync(key, value) { | ||
_fsExtra2.default.outputFileSync(this.path(key), toJson(value)); | ||
return this; | ||
setSync(key, value) { | ||
fs_extra_1.default.outputFileSync(this.path(key), toJson(value)); | ||
return this; | ||
} | ||
/** | ||
* Removes the item from the file-system. | ||
* @param {string} key: The key of the cache item. | ||
* @return {Promise} | ||
*/ | ||
}, { | ||
key: 'remove', | ||
value: function remove(key) { | ||
return f.removeFileP(this.path(key)); | ||
remove(key) { | ||
return f.removeFileP(this.path(key)); | ||
} | ||
/** | ||
* Removes all items from the cache. | ||
* @return {Promise} | ||
*/ | ||
}, { | ||
key: 'clear', | ||
value: function clear() { | ||
var _this3 = this; | ||
return new _bluebird2.default(function (resolve, reject) { | ||
f.filePathsP(_this3.basePath, _this3.ns).then(function (paths) { | ||
var remove = function remove(index) { | ||
var path = paths[index]; | ||
if (path) { | ||
f.removeFileP(path).then(function () { | ||
return remove(index + 1); | ||
}) // <== RECURSION. | ||
.catch(function (err) { | ||
return reject(err); | ||
}); | ||
} else { | ||
resolve(); // All files have been removed. | ||
} | ||
}; | ||
remove(0); | ||
}).catch(function (err) { | ||
return reject(err); | ||
clear() { | ||
return new Promise((resolve, reject) => { | ||
var _a; | ||
f.filePathsP(this.basePath, (_a = this.ns) !== null && _a !== void 0 ? _a : '') | ||
.then((paths) => { | ||
const remove = (index) => { | ||
const path = paths[index]; | ||
if (path) { | ||
f.removeFileP(path) | ||
.then(() => remove(index + 1)) | ||
.catch((err) => reject(err)); | ||
} | ||
else { | ||
resolve(); | ||
} | ||
}; | ||
remove(0); | ||
}) | ||
.catch((err) => reject(err)); | ||
}); | ||
}); | ||
} | ||
/** | ||
* Saves several items to the cache in one operation. | ||
* @param {array} items: An array of objects of the form { key, value }. | ||
* @return {Promise} | ||
*/ | ||
}, { | ||
key: 'save', | ||
value: function save(items) { | ||
var _this4 = this; | ||
// Setup initial conditions. | ||
if (!_ramda2.default.is(Array, items)) { | ||
items = [items]; | ||
} | ||
var isValid = function isValid(item) { | ||
if (!_ramda2.default.is(Object, item)) { | ||
return false; | ||
save(items) { | ||
if (!ramda_1.default.is(Array, items)) { | ||
items = [items]; | ||
} | ||
return item.key && item.value; | ||
}; | ||
items = _ramda2.default.pipe(_ramda2.default.reject(_ramda2.default.isNil), _ramda2.default.forEach(function (item) { | ||
if (!isValid(item)) { | ||
throw new Error('Save items not valid, must be an array of {key, value} objects.'); | ||
} | ||
}))(items); | ||
return new _bluebird2.default(function (resolve, reject) { | ||
// Don't continue if no items were passed. | ||
var response = { paths: [] }; | ||
if (items.length === 0) { | ||
resolve(response); | ||
return; | ||
} | ||
// Recursively set each item to the file-system. | ||
var setValue = function setValue(index) { | ||
var item = items[index]; | ||
if (item) { | ||
_this4.set(item.key, item.value).then(function (result) { | ||
response.paths[index] = result.path; | ||
setValue(index + 1); // <== RECURSION. | ||
}).catch(function (err) { | ||
return reject(err); | ||
}); | ||
} else { | ||
// No more items - done. | ||
resolve(response); | ||
} | ||
const isValid = (item) => { | ||
if (!ramda_1.default.is(Object, item)) { | ||
return false; | ||
} | ||
return item.key && item.value; | ||
}; | ||
setValue(0); | ||
}); | ||
} | ||
/** | ||
* Loads all files within the cache's namespace. | ||
*/ | ||
}, { | ||
key: 'load', | ||
value: function load() { | ||
var _this5 = this; | ||
return new _bluebird2.default(function (resolve, reject) { | ||
f.filePathsP(_this5.basePath, _this5.ns).then(function (paths) { | ||
// Bail out if there are no paths in the folder. | ||
var response = { files: [] }; | ||
if (paths.length === 0) { | ||
resolve(response); | ||
return; | ||
} | ||
// Get each value. | ||
var getValue = function getValue(index) { | ||
var path = paths[index]; | ||
if (path) { | ||
getValueP(path).then(function (result) { | ||
response.files[index] = { path: path, value: result }; | ||
getValue(index + 1); // <== RECURSION. | ||
}).catch(function (err) { | ||
return reject(err); | ||
}); | ||
} else { | ||
// All paths have been loaded. | ||
resolve(response); | ||
items = items.filter((item) => Boolean(item)); | ||
items.forEach((item) => { | ||
if (!isValid(item)) { | ||
throw new Error(`Save items not valid, must be an array of {key, value} objects.`); | ||
} | ||
}; | ||
getValue(0); | ||
}).catch(function (err) { | ||
return reject(err); | ||
}); | ||
}); | ||
return new Promise((resolve, reject) => { | ||
const response = { paths: [] }; | ||
if (items.length === 0) { | ||
resolve(response); | ||
return; | ||
} | ||
const setValue = (index) => { | ||
const item = items[index]; | ||
if (item) { | ||
this.set(item.key, item.value) | ||
.then((result) => { | ||
response.paths[index] = result.path; | ||
setValue(index + 1); | ||
}) | ||
.catch((err) => reject(err)); | ||
} | ||
else { | ||
resolve(response); | ||
} | ||
}; | ||
setValue(0); | ||
}); | ||
} | ||
}]); | ||
return FileSystemCache; | ||
}(); | ||
load() { | ||
return new Promise((resolve, reject) => { | ||
var _a; | ||
f.filePathsP(this.basePath, (_a = this.ns) !== null && _a !== void 0 ? _a : '') | ||
.then((paths) => { | ||
const response = { files: [] }; | ||
if (paths.length === 0) { | ||
resolve(response); | ||
return; | ||
} | ||
const getValue = (index) => { | ||
const path = paths[index]; | ||
if (path) { | ||
getValueP(path) | ||
.then((result) => { | ||
response.files[index] = { path, value: result }; | ||
getValue(index + 1); | ||
}) | ||
.catch((err) => reject(err)); | ||
} | ||
else { | ||
resolve(response); | ||
} | ||
}; | ||
getValue(0); | ||
}) | ||
.catch((err) => reject(err)); | ||
}); | ||
} | ||
} | ||
exports.default = FileSystemCache; | ||
//# sourceMappingURL=cache.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); | ||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj["default"] = obj; return newObj; } } | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var _ramda = require("ramda"); | ||
var _ramda2 = _interopRequireDefault(_ramda); | ||
var _bluebird = require("bluebird"); | ||
var _bluebird2 = _interopRequireDefault(_bluebird); | ||
var _fsExtra = require("fs-extra"); | ||
var _fsExtra2 = _interopRequireDefault(_fsExtra); | ||
var _funcs = require("./funcs"); | ||
var f = _interopRequireWildcard(_funcs); | ||
var formatPath = _ramda2["default"].pipe(f.ensureString("./.build"), f.toAbsolutePath); | ||
/** | ||
* A cache that read/writes to a specific part of the file-system. | ||
*/ | ||
var FileSystemCache = (function () { | ||
/** | ||
* Constructor. | ||
* @param options | ||
* - basePath: The folder path to read/write to. | ||
* Default: "./build" | ||
* - ns: A single value, or array, that represents a | ||
* a unique namespace within which values for this | ||
* store are cached. | ||
* - extension: An optional file-extension for paths. | ||
*/ | ||
function FileSystemCache() { | ||
var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
var basePath = _ref.basePath; | ||
var ns = _ref.ns; | ||
var extension = _ref.extension; | ||
_classCallCheck(this, FileSystemCache); | ||
this.basePath = formatPath(basePath); | ||
this.ns = f.hash(ns); | ||
if (f.isString(extension)) { | ||
this.extension = extension; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.FileSystemCache = void 0; | ||
const common_1 = require("./common"); | ||
const formatPath = common_1.R.pipe(common_1.Util.ensureString('./.cache'), common_1.Util.toAbsolutePath); | ||
class FileSystemCache { | ||
constructor(options = {}) { | ||
this.basePath = formatPath(options.basePath); | ||
this.ns = common_1.Util.hash(options.ns); | ||
if (common_1.Util.isString(options.extension)) | ||
this.extension = options.extension; | ||
if (common_1.Util.isFileSync(this.basePath)) { | ||
throw new Error(`The basePath '${this.basePath}' is a file. It should be a folder.`); | ||
} | ||
} | ||
if (f.isFileSync(this.basePath)) { | ||
throw new Error("The basePath '" + this.basePath + "' is a file. It should be a folder."); | ||
path(key) { | ||
if (common_1.Util.isNothing(key)) | ||
throw new Error(`Path requires a cache key.`); | ||
let name = common_1.Util.hash(key); | ||
if (this.ns) | ||
name = `${this.ns}-${name}`; | ||
if (this.extension) | ||
name = `${name}.${this.extension.replace(/^\./, '')}`; | ||
return `${this.basePath}/${name}`; | ||
} | ||
} | ||
/** | ||
* Generates the path to the cached files. | ||
* @param {string} key: The key of the cache item. | ||
* @return {string}. | ||
*/ | ||
_createClass(FileSystemCache, [{ | ||
key: "path", | ||
value: function path(key) { | ||
if (f.isNothing(key)) { | ||
throw new Error("Path requires a cache key."); | ||
} | ||
var name = f.hash(key); | ||
if (this.ns) { | ||
name = this.ns + "-" + name; | ||
} | ||
if (this.extension) { | ||
name = name + "." + this.extension.replace(/^\./, ""); | ||
} | ||
return this.basePath + "/" + name; | ||
fileExists(key) { | ||
return common_1.fs.pathExists(this.path(key)); | ||
} | ||
/** | ||
* Determines whether the file exists. | ||
* @param {string} key: The key of the cache item. | ||
* @return {Promise} | ||
*/ | ||
}, { | ||
key: "fileExists", | ||
value: function fileExists(key) { | ||
return f.fileExistsP(this.path(key)); | ||
ensureBasePath() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!this.basePathExists) | ||
yield common_1.fs.ensureDir(this.basePath); | ||
this.basePathExists = true; | ||
}); | ||
} | ||
/** | ||
* Ensure that the base path exists. | ||
* @return {Promise} | ||
*/ | ||
}, { | ||
key: "ensureBasePath", | ||
value: function ensureBasePath() { | ||
var _this = this; | ||
return new _bluebird2["default"](function (resolve, reject) { | ||
if (_this.basePathExists) { | ||
resolve(); | ||
} else { | ||
_fsExtra2["default"].ensureDir(_this.basePath, function (err) { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
_this.basePathExists = true; | ||
resolve(); | ||
} | ||
}); | ||
} | ||
}); | ||
get(key, defaultValue) { | ||
return common_1.Util.getValueP(this.path(key), defaultValue); | ||
} | ||
/** | ||
* Gets the contents of the file with the given key. | ||
* @param {string} key: The key of the cache item. | ||
* @return {Promise} - File contents, or | ||
* Undefined if the file does not exist. | ||
*/ | ||
}, { | ||
key: "get", | ||
value: function get(key) { | ||
var _this2 = this; | ||
return new _bluebird2["default"](function (resolve, reject) { | ||
var path = _this2.path(key); | ||
_fsExtra2["default"].readJson(path, function (err, result) { | ||
if (err) { | ||
if (err.code === "ENOENT") { | ||
resolve(undefined); | ||
} else { | ||
reject(err); | ||
} | ||
} else { | ||
var value = result.value; | ||
var type = result.type; | ||
if (type === "Date") { | ||
value = new Date(value); | ||
} | ||
resolve(value); | ||
} | ||
getSync(key, defaultValue) { | ||
const path = this.path(key); | ||
return common_1.fs.existsSync(path) ? common_1.Util.toGetValue(common_1.fs.readJsonSync(path)) : defaultValue; | ||
} | ||
set(key, value) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const path = this.path(key); | ||
yield this.ensureBasePath(); | ||
yield common_1.fs.outputFile(path, common_1.Util.toJson(value)); | ||
return { path }; | ||
}); | ||
}); | ||
} | ||
/** | ||
* Writes the given value to the file-system and memory cache. | ||
* @param {string} key: The key of the cache item. | ||
* @param value: The value to write (Primitive or Object). | ||
* @return {Promise} | ||
*/ | ||
}, { | ||
key: "set", | ||
value: function set(key, value) { | ||
var _this3 = this; | ||
var path = this.path(key); | ||
return new _bluebird2["default"](function (resolve, reject) { | ||
_this3.ensureBasePath().then(function () { | ||
var json = { | ||
value: value, | ||
type: _ramda2["default"].type(value) | ||
}; | ||
_fsExtra2["default"].outputFile(path, JSON.stringify(json), function (err) { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve({ path: path }); | ||
} | ||
}); | ||
})["catch"](function (err) { | ||
return reject(err); | ||
setSync(key, value) { | ||
common_1.fs.outputFileSync(this.path(key), common_1.Util.toJson(value)); | ||
return this; | ||
} | ||
remove(key) { | ||
return common_1.fs.remove(this.path(key)); | ||
} | ||
clear() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const paths = yield common_1.Util.filePathsP(this.basePath, this.ns); | ||
yield Promise.all(paths.map((path) => common_1.fs.remove(path))); | ||
console.groupEnd(); | ||
}); | ||
}); | ||
} | ||
/** | ||
* Removes the item from the file-system. | ||
* @param {string} key: The key of the cache item. | ||
* @return {Promise} | ||
*/ | ||
}, { | ||
key: "remove", | ||
value: function remove(key) { | ||
return f.removeFileP(this.path(key)); | ||
save(input) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let items = (Array.isArray(input) ? input : [input]); | ||
const isValid = (item) => { | ||
if (!common_1.R.is(Object, item)) | ||
return false; | ||
return item.key && item.value; | ||
}; | ||
items = items.filter((item) => Boolean(item)); | ||
items | ||
.filter((item) => !isValid(item)) | ||
.forEach(() => { | ||
const err = `Save items not valid, must be an array of {key, value} objects.`; | ||
throw new Error(err); | ||
}); | ||
if (items.length === 0) | ||
return { paths: [] }; | ||
const paths = yield Promise.all(items.map((item) => __awaiter(this, void 0, void 0, function* () { return (yield this.set(item.key, item.value)).path; }))); | ||
return { paths }; | ||
}); | ||
} | ||
/** | ||
* Removes all items from the cache. | ||
* @return {Promise} | ||
*/ | ||
}, { | ||
key: "clear", | ||
value: function clear() { | ||
var _this4 = this; | ||
return new _bluebird2["default"](function (resolve, reject) { | ||
_fsExtra2["default"].readdir(_this4.basePath, function (err, fileNames) { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
(function () { | ||
var paths = _ramda2["default"].pipe(f.compact, _ramda2["default"].filter(function (name) { | ||
return _this4.ns ? name.startsWith(_this4.ns) : true; | ||
}), _ramda2["default"].filter(function (name) { | ||
return !_this4.ns ? !_ramda2["default"].contains("-")(name) : true; | ||
}), _ramda2["default"].map(function (name) { | ||
return _this4.basePath + "/" + name; | ||
}))(fileNames); | ||
var remove = function remove(index) { | ||
var path = paths[index]; | ||
if (path) { | ||
f.removeFileP(path).then(function () { | ||
return remove(index + 1); | ||
}) // <== RECURSION | ||
["catch"](function (err) { | ||
return reject(err); | ||
}); | ||
} else { | ||
resolve(); // All files have been removed. | ||
} | ||
}; | ||
remove(0); | ||
})(); | ||
} | ||
load() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const paths = yield common_1.Util.filePathsP(this.basePath, this.ns); | ||
if (paths.length === 0) | ||
return { files: [] }; | ||
const files = yield Promise.all(paths.map((path) => __awaiter(this, void 0, void 0, function* () { return ({ path, value: yield common_1.Util.getValueP(path) }); }))); | ||
return { files }; | ||
}); | ||
}); | ||
} | ||
}]); | ||
return FileSystemCache; | ||
})(); | ||
exports["default"] = FileSystemCache; | ||
module.exports = exports["default"]; | ||
} | ||
exports.FileSystemCache = FileSystemCache; |
193
lib/funcs.js
@@ -1,127 +0,86 @@ | ||
'use strict'; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.hash = exports.filePathsP = exports.removeFileP = exports.existsP = exports.readFileSync = exports.isFileSync = exports.ensureString = exports.toAbsolutePath = exports.toStringArray = exports.compact = exports.isString = exports.isNothing = undefined; | ||
var _ramda = require('ramda'); | ||
var _ramda2 = _interopRequireDefault(_ramda); | ||
var _fsExtra = require('fs-extra'); | ||
var _fsExtra2 = _interopRequireDefault(_fsExtra); | ||
var _path = require('path'); | ||
var _path2 = _interopRequireDefault(_path); | ||
var _crypto = require('crypto'); | ||
var _crypto2 = _interopRequireDefault(_crypto); | ||
var _bluebird = require('bluebird'); | ||
var _bluebird2 = _interopRequireDefault(_bluebird); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var isNothing = exports.isNothing = function isNothing(value) { | ||
return _ramda2.default.isNil(value) || _ramda2.default.isEmpty(value); | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
var isString = exports.isString = _ramda2.default.is(String); | ||
var compact = exports.compact = _ramda2.default.pipe(_ramda2.default.flatten, _ramda2.default.reject(_ramda2.default.isNil)); | ||
var toStringArray = exports.toStringArray = _ramda2.default.pipe(compact, _ramda2.default.map(_ramda2.default.toString)); | ||
var toAbsolutePath = exports.toAbsolutePath = function toAbsolutePath(path) { | ||
return path.startsWith('.') ? _path2.default.resolve(path) : path; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.hash = exports.filePathsP = exports.removeFileP = exports.existsP = exports.readFileSync = exports.isFileSync = exports.toStringArray = exports.compact = exports.ensureString = exports.toAbsolutePath = exports.isString = exports.isNothing = void 0; | ||
const ramda_1 = __importDefault(require("ramda")); | ||
const fs_extra_1 = __importDefault(require("fs-extra")); | ||
const path_1 = __importDefault(require("path")); | ||
const crypto_1 = __importDefault(require("crypto")); | ||
const isNothing = (value) => ramda_1.default.isNil(value) || ramda_1.default.isEmpty(value); | ||
exports.isNothing = isNothing; | ||
exports.isString = ramda_1.default.is(String); | ||
const toAbsolutePath = (path) => { | ||
return path.startsWith('.') ? path_1.default.resolve(path) : path; | ||
}; | ||
var ensureString = exports.ensureString = _ramda2.default.curry(function (defaultValue, text) { | ||
return _ramda2.default.is(String, text) ? text : defaultValue; | ||
}); | ||
var isFileSync = exports.isFileSync = function isFileSync(path) { | ||
if (_fsExtra2.default.existsSync(path)) { | ||
return _fsExtra2.default.lstatSync(path).isFile(); | ||
} | ||
return false; | ||
exports.toAbsolutePath = toAbsolutePath; | ||
exports.ensureString = ramda_1.default.curry((defaultValue, text) => ramda_1.default.is(String, text) ? text : defaultValue); | ||
const compact = (input) => { | ||
return input.flat().filter((value) => !ramda_1.default.isNil(value)); | ||
}; | ||
var readFileSync = exports.readFileSync = function readFileSync(path) { | ||
if (_fsExtra2.default.existsSync(path)) { | ||
return _fsExtra2.default.readFileSync(path).toString(); | ||
} | ||
exports.compact = compact; | ||
exports.toStringArray = ramda_1.default.pipe(exports.compact, ramda_1.default.map(ramda_1.default.toString)); | ||
const isFileSync = (path) => { | ||
if (fs_extra_1.default.existsSync(path)) | ||
return fs_extra_1.default.lstatSync(path).isFile(); | ||
return false; | ||
}; | ||
var existsP = exports.existsP = function existsP(path) { | ||
return new _bluebird2.default(function (resolve) { | ||
_fsExtra2.default.exists(path, function (exists) { | ||
return resolve(exists); | ||
}); | ||
}); | ||
exports.isFileSync = isFileSync; | ||
const readFileSync = (path) => { | ||
if (fs_extra_1.default.existsSync(path)) { | ||
return fs_extra_1.default.readFileSync(path).toString(); | ||
} | ||
}; | ||
var removeFileP = exports.removeFileP = function removeFileP(path) { | ||
return new _bluebird2.default(function (resolve, reject) { | ||
existsP(path).then(function (exists) { | ||
if (exists) { | ||
_fsExtra2.default.remove(path, function (err) { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
exports.readFileSync = readFileSync; | ||
const existsP = (path) => new Promise((resolve) => { | ||
fs_extra_1.default.pathExists(path, (exists) => resolve(exists)); | ||
}); | ||
exports.existsP = existsP; | ||
const removeFileP = (path) => new Promise((resolve, reject) => { | ||
(0, exports.existsP)(path).then((exists) => { | ||
if (exists) { | ||
fs_extra_1.default.remove(path, (err) => { | ||
if (err) { | ||
reject(err); | ||
} | ||
else { | ||
resolve(); | ||
} | ||
}); | ||
} | ||
else { | ||
resolve(); | ||
} | ||
}); | ||
} else { | ||
resolve(); | ||
} | ||
} | ||
}); | ||
}); | ||
}; | ||
var filePathsP = exports.filePathsP = function filePathsP(basePath, ns) { | ||
return new _bluebird2.default(function (resolve, reject) { | ||
existsP(basePath).then(function (exists) { | ||
if (!exists) { | ||
resolve([]);return; | ||
} | ||
_fsExtra2.default.readdir(basePath, function (err, fileNames) { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
var paths = _ramda2.default.pipe(compact, _ramda2.default.filter(function (name) { | ||
return ns ? name.startsWith(ns) : true; | ||
}), _ramda2.default.filter(function (name) { | ||
return !ns ? !_ramda2.default.contains('-')(name) : true; | ||
}), _ramda2.default.map(function (name) { | ||
return basePath + '/' + name; | ||
}))(fileNames); | ||
resolve(paths); | ||
}); | ||
exports.removeFileP = removeFileP; | ||
const filePathsP = (basePath, ns) => new Promise((resolve, reject) => { | ||
(0, exports.existsP)(basePath).then((exists) => { | ||
if (!exists) { | ||
resolve([]); | ||
return; | ||
} | ||
}); | ||
fs_extra_1.default.readdir(basePath, (err, fileNames) => { | ||
if (err) { | ||
reject(err); | ||
} | ||
else { | ||
const paths = ramda_1.default.pipe(exports.compact, ramda_1.default.filter((name) => (ns ? name.startsWith(ns) : true)), ramda_1.default.filter((name) => (!ns ? !name.includes('-') : true)), ramda_1.default.map((name) => `${basePath}/${name}`))(fileNames); | ||
resolve(paths); | ||
} | ||
}); | ||
}); | ||
}); | ||
}); | ||
exports.filePathsP = filePathsP; | ||
const hash = (...values) => { | ||
if (ramda_1.default.pipe(exports.compact, ramda_1.default.isEmpty)(values)) { | ||
return undefined; | ||
} | ||
const resultHash = crypto_1.default.createHash('md5'); | ||
const addValue = (value) => resultHash.update(value); | ||
const addValues = ramda_1.default.forEach(addValue); | ||
ramda_1.default.pipe(exports.toStringArray, addValues)(values); | ||
return resultHash.digest('hex'); | ||
}; | ||
/** | ||
* Turns a set of values into a HEX hash code. | ||
* @param values: The set of values to hash. | ||
* @return {String} or undefined. | ||
*/ | ||
var hash = exports.hash = function hash() { | ||
for (var _len = arguments.length, values = Array(_len), _key = 0; _key < _len; _key++) { | ||
values[_key] = arguments[_key]; | ||
} | ||
if (_ramda2.default.pipe(compact, _ramda2.default.isEmpty)(values)) { | ||
return undefined; | ||
} | ||
var resultHash = _crypto2.default.createHash('md5'); | ||
var addValue = function addValue(value) { | ||
return resultHash.update(value); | ||
}; | ||
var addValues = _ramda2.default.forEach(addValue); | ||
_ramda2.default.pipe(toStringArray, addValues)(values); | ||
return resultHash.digest('hex'); | ||
}; | ||
//# sourceMappingURL=funcs.js.map | ||
exports.hash = hash; |
@@ -1,16 +0,6 @@ | ||
'use strict'; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var _cache = require('./cache'); | ||
var _cache2 = _interopRequireDefault(_cache); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
exports.default = function (options) { | ||
return new _cache2.default(options); | ||
}; | ||
//# sourceMappingURL=index.js.map | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.FileSystemCache = void 0; | ||
const FileSystemCache_1 = require("./FileSystemCache"); | ||
Object.defineProperty(exports, "FileSystemCache", { enumerable: true, get: function () { return FileSystemCache_1.FileSystemCache; } }); | ||
exports.default = (options) => new FileSystemCache_1.FileSystemCache(options); |
{ | ||
"name": "file-system-cache", | ||
"version": "1.0.5", | ||
"version": "1.1.0", | ||
"description": "A super-fast, promise-based cache that reads and writes to the file-system.", | ||
"main": "./lib/index.js", | ||
"scripts": { | ||
"test": "./node_modules/mocha/bin/mocha --recursive --compilers js:babel-register", | ||
"tdd": "./node_modules/mocha/bin/mocha --recursive --compilers js:babel-register --watch", | ||
"lint": "eslint ./src", | ||
"build": "babel src --out-dir lib --source-maps", | ||
"build:watch": "npm run build -- --watch", | ||
"prepublish": "npm test && npm run lint && npm run build" | ||
"test": "ts-mocha -p tsconfig.json src/**/*.TEST.ts", | ||
"build": "tsc", | ||
"prepublish": "npm test && npm run build" | ||
}, | ||
"dependencies": { | ||
"bluebird": "^3.3.5", | ||
"fs-extra": "^0.30.0", | ||
"ramda": "^0.21.0" | ||
"fs-extra": "^10.1.0", | ||
"ramda": "^0.28.0" | ||
}, | ||
"devDependencies": { | ||
"chai": "^3.4.1", | ||
"js-babel": "^6.0.4", | ||
"js-babel-dev": "^6.0.5", | ||
"mocha": "^2.4.5" | ||
"@types/chai": "^4.3.1", | ||
"@types/expect": "24.3.0", | ||
"@types/fs-extra": "^9.0.13", | ||
"@types/mocha": "9.1.1", | ||
"@types/ramda": "^0.28.12", | ||
"chai": "^4.3.6", | ||
"mocha": "^10.0.0", | ||
"ts-mocha": "10.0.0", | ||
"typescript": "4.6.4" | ||
}, | ||
@@ -25,0 +26,0 @@ "repository": { |
@@ -24,2 +24,5 @@ # file-system-cache | ||
> Reference `default` for CommonJS, e.g: `const Cache = require('file-system-cache').default | ||
` | ||
The optional `ns` ("namespace") allows for multiple groupings of files to reside within the one cache folder. When you have multiple caches with different namespaces you can re-use the same keys and they will not collide. | ||
@@ -48,3 +51,3 @@ | ||
Value types are stored and respected on subsequent calls to `get`. For examples, passing in Object will return that in it's parsed object state. | ||
Value types are stored and respected on subsequent calls to `get`. For examples, passing in Object will return that in its parsed object state. | ||
@@ -51,0 +54,0 @@ Use `setSync` for a synchronous version. |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
63306
2
35
1455
92
7
9
1
+ Addedfs-extra@10.1.0(transitive)
+ Addedjsonfile@6.1.0(transitive)
+ Addedramda@0.28.0(transitive)
+ Addeduniversalify@2.0.1(transitive)
- Removedbluebird@^3.3.5
- Removedbalanced-match@1.0.2(transitive)
- Removedbluebird@3.7.2(transitive)
- Removedbrace-expansion@1.1.11(transitive)
- Removedconcat-map@0.0.1(transitive)
- Removedfs-extra@0.30.0(transitive)
- Removedfs.realpath@1.0.0(transitive)
- Removedglob@7.2.3(transitive)
- Removedinflight@1.0.6(transitive)
- Removedinherits@2.0.4(transitive)
- Removedjsonfile@2.4.0(transitive)
- Removedklaw@1.3.1(transitive)
- Removedminimatch@3.1.2(transitive)
- Removedonce@1.4.0(transitive)
- Removedpath-is-absolute@1.0.1(transitive)
- Removedramda@0.21.0(transitive)
- Removedrimraf@2.7.1(transitive)
- Removedwrappy@1.0.2(transitive)
Updatedfs-extra@^10.1.0
Updatedramda@^0.28.0