68 lines
1.8 KiB
JavaScript
68 lines
1.8 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
var mkdirp = require('mkdirp');
|
||
|
var md5Hex = require('md5-hex');
|
||
|
var fs = require('fs');
|
||
|
var path = require('path');
|
||
|
var writeFileAtomic = require('write-file-atomic');
|
||
|
|
||
|
function defaultHash(input, additionalData, salt) {
|
||
|
return md5Hex([input, salt || '']);
|
||
|
}
|
||
|
|
||
|
function wrap(opts) {
|
||
|
if (!(opts.factory || opts.transform) || (opts.factory && opts.transform)) {
|
||
|
throw new Error('specify factory or transform but not both');
|
||
|
}
|
||
|
if (typeof opts.cacheDir !== 'string' && !opts.disableCache) {
|
||
|
throw new Error('cacheDir must be a string');
|
||
|
}
|
||
|
|
||
|
var transformFn = opts.transform;
|
||
|
var factory = opts.factory;
|
||
|
var cacheDir = opts.cacheDir;
|
||
|
var cacheDirCreated = opts.createCacheDir === false;
|
||
|
var created = transformFn && cacheDirCreated;
|
||
|
var ext = opts.ext || '';
|
||
|
var salt = opts.salt || '';
|
||
|
var shouldTransform = opts.shouldTransform;
|
||
|
var disableCache = opts.disableCache;
|
||
|
var hashFn = opts.hash || defaultHash;
|
||
|
var encoding = opts.encoding === 'buffer' ? undefined : opts.encoding || 'utf8';
|
||
|
|
||
|
function transform(input, metadata, hash) {
|
||
|
if (!created) {
|
||
|
if (!cacheDirCreated && !disableCache) {
|
||
|
mkdirp.sync(cacheDir);
|
||
|
}
|
||
|
if (!transformFn) {
|
||
|
transformFn = factory(cacheDir);
|
||
|
}
|
||
|
created = true;
|
||
|
}
|
||
|
return transformFn(input, metadata, hash);
|
||
|
}
|
||
|
|
||
|
return function (input, metadata) {
|
||
|
if (shouldTransform && !shouldTransform(input, metadata)) {
|
||
|
return input;
|
||
|
}
|
||
|
if (disableCache) {
|
||
|
return transform(input, metadata);
|
||
|
}
|
||
|
|
||
|
var hash = hashFn(input, metadata, salt);
|
||
|
var cachedPath = path.join(cacheDir, hash + ext);
|
||
|
|
||
|
try {
|
||
|
return fs.readFileSync(cachedPath, encoding);
|
||
|
} catch (e) {
|
||
|
var result = transform(input, metadata, hash);
|
||
|
writeFileAtomic.sync(cachedPath, result, encoding);
|
||
|
return result;
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
module.exports = wrap;
|