key-cache
Version:
Storing data in the form of key into the file
283 lines (221 loc) • 7.7 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _stringify = require('babel-runtime/core-js/json/stringify');
var _stringify2 = _interopRequireDefault(_stringify);
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _fs = require('fs');
var _fsExtra = require('fs-extra');
var _path = require('path');
var _crypto = require('crypto');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* 检查文件是否存在
*
* @inner
* @param {string} filePath 文件路径
* @param {string} [type=file] 检测类型
*
* @return {boolean} 是否存在
*/
/**
* @file key-cache
* @author xiaowu
* @email fe.xiaowu@gmail.com
*/
var exists = function exists(filePath) {
var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'file';
try {
return type === 'file' ? (0, _fs.statSync)(filePath).isFile() : (0, _fs.statSync)(filePath).isDirectory();
} catch (e) {
return false;
}
};
var KeyCache = function () {
function KeyCache() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
(0, _classCallCheck3.default)(this, KeyCache);
// 合并默认配置
this.options = (0, _extends3.default)({}, KeyCache.options, options);
// 解析路径
this.options.dir = (0, _path.resolve)(this.options.dir);
// 创建缓存目录
(0, _fsExtra.mkdirsSync)(this.options.dir);
}
/**
* 设置缓存
*
* @param {string} key key
* @param {Object|string} value 值
* @param {Object|undefined} options 可选配置
* @return {Object} this
*/
(0, _createClass3.default)(KeyCache, [{
key: 'set',
value: function set(key, value) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
if (!key || 'string' !== typeof key || value === undefined) {
return this;
}
options = (0, _extends3.default)({}, this.options, options);
var data = {
__time: null,
__result: value,
__key: key
};
// 如果有过期时间则记录,否则忽略
if (options.timeout !== null) {
data.__time = Date.now();
data.__end = options.timeout;
}
// 如果配置的缓存目录不是初始的则创建该目录,防止出错
if (options.dir !== this.options.dir) {
(0, _fsExtra.mkdirsSync)(options.dir);
}
// 写入缓存
(0, _fs.writeFileSync)(this._getFilePath(key, options), (0, _stringify2.default)(data));
return this;
}
/**
* 获取缓存文件路径
*
* @private
* @param {string} key key
* @param {Object|undefined} options 配置参数,如果为空则调用this.options
*
* @return {string} 文件绝对路径
*/
}, {
key: '_getFilePath',
value: function _getFilePath(key, options) {
var filename = void 0;
options = options || this.options;
if (options.md5key) {
var md5 = (0, _crypto.createHash)('md5');
// unescape encodeURIComponent 兼容中文 md5
md5.update(unescape(encodeURIComponent(key)));
filename = md5.digest('hex');
} else {
// 把文件名中的:替换为空
filename = String(key).replace(/[^\u4e00-\u9fa5a-zA-Z\_\-0-9]/g, '');
// 如果替换后为空则使用md5
if (!filename) {
return this._getFilePath(key, (0, _extends3.default)({}, options, { md5key: true }));
}
}
return (0, _path.resolve)(options.dir, filename + '.json');
}
/**
* 获取所有缓存数据
*
* @return {Object} {key: value, ...}
*/
}, {
key: 'getAll',
value: function getAll() {
var _this = this;
var dir = (0, _path.resolve)(this.options.dir);
// 如果目录不存在
if (!exists(dir, 'dir')) {
return {};
}
var data = {};
(0, _fs.readdirSync)(dir).map(function (filename) {
var result = (0, _fsExtra.readJsonSync)((0, _path.resolve)(dir, filename), {
throws: false
}) || {};
if (result.__key) {
data[result.__key] = _this.get(result.__key);
}
});
return data;
}
/**
* 获取缓存
*
* @param {string} key key
*
* @return {Object|string|null} 结果,如果没有找到或者过期则为null
*/
}, {
key: 'get',
value: function get(key) {
var filepath = this._getFilePath(key);
// 如果文件不存在
if (!exists(filepath)) {
return null;
}
var filedata = (0, _fsExtra.readJsonSync)(filepath, {
throws: false
}) || {};
// 如果没有时间就不是key-cache设置的,则忽略
if (filedata.__time === undefined) {
return null;
}
// 如果设置了时间并且过期了
// 则删除这个缓存文件
if (filedata.__time !== null && Date.now() - filedata.__time > filedata.__end * 1000) {
this.remove(key);
return null;
}
// 如果为undefined则返回null,因为值是fn时不会被JSON.stringify解析
return filedata.__result !== undefined ? filedata.__result : null;
}
/**
* 删除缓存
*
* @param {string|undefined} key key,如果为空则全部删除
*
* @return {Object} this
*/
}, {
key: 'remove',
value: function remove(key) {
// 如果没有key则说明全部删除
if (!key) {
(0, _fsExtra.emptyDirSync)(this.options.dir);
return this;
}
var filepath = this._getFilePath(key);
// 如果文件不存在
if (!exists(filepath)) {
return this;
}
// 删除文件
(0, _fsExtra.removeSync)(filepath);
return this;
}
}]);
return KeyCache;
}();
KeyCache.options = {
/**
* 缓存目录,路径基于当前运行目录
*
* @default 安装包里 dirname + .cache
* @type {String}
*/
dir: (0, _path.resolve)(__dirname, '..', '.cache'),
/**
* 保存的时间,单位秒,如果是null则表示一直保存
*
* @default null
* @type {Number|null}
*/
timeout: null,
/**
* 是否使用md5命名缓存文件
*
* @default true
* @type {Boolean}
*/
md5key: true
};
exports.default = KeyCache;
module.exports = exports['default'];