-
Ulf Seltmann authored48e52ce0
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
cache.js 5.00 KiB
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const debugFactory = require("debug");
const NodeCache = require("node-cache");
const crypto = require("crypto");
const fs = require("fs");
const path = require("path");
const endpoint_1 = require("./endpoint");
const debug = debugFactory('decap:cache');
class Register {
constructor(storage, name) {
this.storage = storage;
this.name = name;
this.cacheRegister = {};
this.get = (name) => {
if (!this.cacheRegister[name])
throw new Error(`no endpoint registered for "${name}"`);
return this.cacheRegister[name];
};
this.add = (name, serverUrl) => {
const endpoint = new endpoint_1.Endpoint(serverUrl);
const nodeCache = new NodeCache();
this.cacheRegister[name] = new Cache();
this.cacheRegister[name].setCache(nodeCache).setEndpoint(endpoint);
};
this.save = () => {
const data = Object.keys(this.cacheRegister).map((name) => {
return {
name: name,
data: this.cacheRegister[name].toObject()
};
});
fs.writeFileSync(path.resolve(this.storage, this.name), JSON.stringify(data), { encoding: 'utf8', flag: 'w' });
debug('register ${this.name} saved to ${this.storage}');
};
this.restore = () => __awaiter(this, void 0, void 0, function* () {
const data = JSON.parse(fs.readFileSync(path.resolve(this.storage, this.name), { encoding: 'utf8' }));
data.map((cache) => {
this.cacheRegister[cache.name] = new Cache();
this.cacheRegister[cache.name].fromObject(cache.data);
});
debug('register ${this.name} restored from ${this.storage}');
});
fs.existsSync(storage) || fs.mkdirSync(storage);
}
}
exports.Register = Register;
class Cache {
constructor(endpoint, realCache) {
this.endpoint = endpoint;
this.realCache = realCache;
}
setEndpoint(endpoint) {
this.endpoint = endpoint;
return this;
}
setCache(realCache) {
this.realCache = realCache;
return this;
}
get(hash, path) {
return __awaiter(this, void 0, void 0, function* () {
let value = this.realCache.get(hash);
if (value == undefined) {
debug(`no cache hit. fetching ${path}`);
value = {
contentType: '',
data: ''
};
try {
yield this.endpoint.request(path, value);
this.realCache.set(hash, value);
}
catch (err) {
console.error(err);
}
}
return value;
});
}
toObject() {
const data = {
endPoint: this.endpoint.toObject(),
cache: []
};
this.realCache.keys().map((hash) => {
data.cache.push({
hash: hash,
data: this.realCache.get(hash)
});
});
return data;
}
fromObject(data) {
const endpoint = new endpoint_1.Endpoint();
const realCache = new NodeCache();
endpoint.fromObject(data.endPoint);
this.setEndpoint(endpoint);
data.cache.map((item) => {
realCache.set(item.hash, item.data);
});
this.setCache(realCache);
}
}
exports.Cache = Cache;
function Middleware(register) {
return function (req, res, next) {
return __awaiter(this, void 0, void 0, function* () {
const pattern = new RegExp('^/([^/]+)(.*)$');
const match = req.url.match(pattern);
try {
const cache = register.get(match[1]);
const uniQueryString = Object.keys(req.query).sort().map(function (key) { return `${key}=${req.query[key]}`; }).join('&');
const hash = crypto.createHash('sha1').update(req.path + uniQueryString).digest('base64');
const value = yield cache.get(hash, match[2]);
res.setHeader('content-type', value.contentType);
res.send(value.data);
}
catch (err) {
next(err);
}
});
};
}
exports.Middleware = Middleware;
//# sourceMappingURL=cache.js.map