UNPKG

grind-assets

Version:
157 lines (123 loc) 18.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CompileController = void 0; var _grindSupport = require("grind-support"); function _isnil(val) { return val === null || typeof val === 'undefined'; } const path = require('path'); const crypto = require('crypto'); const dateFormat = require('dateformat'); const stripAnsi = require('strip-ansi'); const HTTP_DATE_FORMAT = 'ddd, dd mmm yyyy HH:MM:ss Z'; class CompileController { constructor(app, factory) { this.app = null; this.factory = null; this.local = null; this.sourcePath = null; this.app = app; this.factory = factory; this.local = app.env() === 'local'; this.sourcePath = app.paths.base(app.config.get('assets.paths.source')); if (_isnil(app.cache)) { Log.error('WARNING: grind-cache not detected, assets will be recompiled every time they’re loaded.'); } } async compile(req, res) { if (req.path.indexOf('..') >= 0) { throw new NotFoundError(); } const pathname = path.join(this.sourcePath, path.relative('/assets', req.path)); const exists = await _grindSupport.FS.exists(pathname); if (!exists) { throw new NotFoundError(); } return this._serve(req, res, this.factory.make(pathname)); } async _serve(req, res, asset) { const lastModified = await asset.lastModified(); const sha1 = crypto.createHash('sha1'); sha1.update(`${asset.path}_${lastModified}`); const etag = `"${sha1.digest('hex')}"`; if (!_isnil(req.headers.http_if_none_match) && req.headers.http_if_none_match === etag) { res.send(304); return; } const expires = new Date((lastModified + 31536000) * 1000.0); const lastModifiedDate = new Date(lastModified * 1000.0); const compile = async () => { res.header('X-Cached', 'false'); let result = await asset.compile(null, req).then(result => { if (!(result instanceof Buffer)) { return Buffer.from(result); } return result; }); const postProcessors = this.factory.getPostProcessorsFromPath(`out.${asset.extension}`); if (postProcessors.length > 0) { for (const postProcessor of postProcessors) { result = await postProcessor.process(asset.path, null, result); if (!(result instanceof Buffer)) { result = Buffer.from(result); } } } return Buffer.from(result); }; let promise = null; if (_isnil(this.app.cache) || req.query['ignore-cache'] === 'true') { promise = compile(); } else { const key = `${req.path.replace(/[^a-z0-9]+/, '-')}-${lastModifiedDate.getTime()}`; const memoryCache = this.app.debug ? global.__grindAssetsCache = global.__grindAssetsCache || {} : {}; if (this.app.debug && memoryCache[key] instanceof Buffer) { promise = Promise.resolve(memoryCache[key]); } else { promise = this.app.cache.wrap(key, compile, { ttl: 86400 }).then(data => { if (!(data instanceof Buffer) && !_isnil(data.data)) { return Buffer.from(data); } return data; }); if (this.app.debug) { promise = promise.then(data => { if (this.app.debug) { memoryCache[key] = data; } return data; }); } } } return promise.then(content => { if (this.app.debug) { res.header('Cache-Control', 'no-cache'); } else { res.header('Cache-Control', 'public, max-age=31536000'); res.header('Expires', dateFormat(expires, HTTP_DATE_FORMAT)); } res.header('Last-Modified', dateFormat(lastModifiedDate, HTTP_DATE_FORMAT)); res.header('ETag', etag); res.header('Content-Type', `${asset.mime}; charset=utf-8`); res.send(content); }).catch(err => { res.status(500); res.header('Content-Type', 'text/plain'); Log.error('Asset compilation error', err.message, err); if (!_isnil(this.app.assets.websocket)) { this.app.assets.websocket.sendAll({ type: 'error', asset: path.relative(this.app.paths.base(), asset.path), assetType: asset.kind, error: err.message }, true); } res.send(`/*\n${stripAnsi(err.message)}\n*/`); }); } } exports.CompileController = CompileController; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9Db21waWxlQ29udHJvbGxlci5qcyJdLCJuYW1lcyI6WyJwYXRoIiwicmVxdWlyZSIsImNyeXB0byIsImRhdGVGb3JtYXQiLCJzdHJpcEFuc2kiLCJIVFRQX0RBVEVfRk9STUFUIiwiQ29tcGlsZUNvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImFwcCIsImZhY3RvcnkiLCJsb2NhbCIsInNvdXJjZVBhdGgiLCJlbnYiLCJwYXRocyIsImJhc2UiLCJjb25maWciLCJnZXQiLCJjYWNoZSIsIkxvZyIsImVycm9yIiwiY29tcGlsZSIsInJlcSIsInJlcyIsImluZGV4T2YiLCJOb3RGb3VuZEVycm9yIiwicGF0aG5hbWUiLCJqb2luIiwicmVsYXRpdmUiLCJleGlzdHMiLCJGUyIsIl9zZXJ2ZSIsIm1ha2UiLCJhc3NldCIsImxhc3RNb2RpZmllZCIsInNoYTEiLCJjcmVhdGVIYXNoIiwidXBkYXRlIiwiZXRhZyIsImRpZ2VzdCIsImhlYWRlcnMiLCJodHRwX2lmX25vbmVfbWF0Y2giLCJzZW5kIiwiZXhwaXJlcyIsIkRhdGUiLCJsYXN0TW9kaWZpZWREYXRlIiwiaGVhZGVyIiwicmVzdWx0IiwidGhlbiIsIkJ1ZmZlciIsImZyb20iLCJwb3N0UHJvY2Vzc29ycyIsImdldFBvc3RQcm9jZXNzb3JzRnJvbVBhdGgiLCJleHRlbnNpb24iLCJsZW5ndGgiLCJwb3N0UHJvY2Vzc29yIiwicHJvY2VzcyIsInByb21pc2UiLCJxdWVyeSIsImtleSIsInJlcGxhY2UiLCJnZXRUaW1lIiwibWVtb3J5Q2FjaGUiLCJkZWJ1ZyIsImdsb2JhbCIsIl9fZ3JpbmRBc3NldHNDYWNoZSIsIlByb21pc2UiLCJyZXNvbHZlIiwid3JhcCIsInR0bCIsImRhdGEiLCJjb250ZW50IiwibWltZSIsImNhdGNoIiwiZXJyIiwic3RhdHVzIiwibWVzc2FnZSIsImFzc2V0cyIsIndlYnNvY2tldCIsInNlbmRBbGwiLCJ0eXBlIiwiYXNzZXRUeXBlIiwia2lu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QyxTQUFqQixDQUFKLEVBQXNDO0FBQ3JDLGFBQUtyRSxHQUFMLENBQVNvRSxNQUFULENBQWdCQyxTQUFoQixDQUEwQkMsT0FBMUIsQ0FDQztBQUNDQyxVQUFBQSxJQUFJLEVBQUUsT0FEUDtBQUVDL0MsVUFBQUEsS0FBSyxFQUFFaEMsSUFBSSxDQUFDMkIsUUFBTCxDQUFjLEtBQUtuQixHQUFMLENBQVNLLEtBQVQsQ0FBZUMsSUFBZixFQUFkLEVBQXFDa0IsS0FBSyxDQUFDaEMsSUFBM0MsQ0FGUjtBQUdDZ0YsVUFBQUEsU0FBUyxFQUFFaEQsS0FBSyxDQUFDaUQsSUFIbEI7QUFJQzlELFVBQUFBLEtBQUssRUFBRXNELEdBQUcsQ0FBQ0U7QUFKWixTQURELEVBT0MsSUFQRDtBQVNBOztBQUVEckQsTUFBQUEsR0FBRyxDQUFDbUIsSUFBSixDQUFVLE9BQU1yQyxTQUFTLENBQUNxRSxHQUFHLENBQUNFLE9BQUwsQ0FBYyxNQUF2QztBQUNBLEtBbENLLENBQVA7QUFtQ0E7O0FBL0k2QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEZTIH0gZnJvbSAnZ3JpbmQtc3VwcG9ydCdcblxuY29uc3QgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKVxuY29uc3QgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJylcbmNvbnN0IGRhdGVGb3JtYXQgPSByZXF1aXJlKCdkYXRlZm9ybWF0JylcbmNvbnN0IHN0cmlwQW5zaSA9IHJlcXVpcmUoJ3N0cmlwLWFuc2knKVxuXG5jb25zdCBIVFRQX0RBVEVfRk9STUFUID0gJ2RkZCwgZGQgbW1tIHl5eXkgSEg6TU06c3MgWidcblxuZXhwb3J0IGNsYXNzIENvbXBpbGVDb250cm9sbGVyIHtcblx0YXBwID0gbnVsbFxuXHRmYWN0b3J5ID0gbnVsbFxuXHRsb2NhbCA9IG51bGxcblx0c291cmNlUGF0aCA9IG51bGxcblxuXHRjb25zdHJ1Y3RvcihhcHAsIGZhY3RvcnkpIHtcblx0XHR0aGlzLmFwcCA9IGFwcFxuXHRcdHRoaXMuZmFjdG9yeSA9IGZhY3Rvcnlcblx0XHR0aGlzLmxvY2FsID0gYXBwLmVudigpID09PSAnbG9jYWwnXG5cdFx0dGhpcy5zb3VyY2VQYXRoID0gYXBwLnBhdGhzLmJhc2UoYXBwLmNvbmZpZy5nZXQoJ2Fzc2V0cy5wYXRocy5zb3VyY2UnKSlcblxuXHRcdGlmIChhcHAuY2FjaGUuaXNOaWwpIHtcblx0XHRcdExvZy5lcnJvcihcblx0XHRcdFx0J1dBUk5JTkc6IGdyaW5kLWNhY2hlIG5vdCBkZXRlY3RlZCwgYXNzZXRzIHdpbGwgYmUgcmVjb21waWxlZCBldmVyeSB0aW1lIHRoZXnigJlyZSBsb2FkZWQuJyxcblx0XHRcdClcblx0XHR9XG5cdH1cblxuXHRhc3luYyBjb21waWxlKHJlcSwgcmVzKSB7XG5cdFx0aWYgKHJlcS5wYXRoLmluZGV4T2YoJy4uJykgPj0gMCkge1xuXHRcdFx0dGhyb3cgbmV3IE5vdEZvdW5kRXJyb3IoKVxuXHRcdH1cblxuXHRcdGNvbnN0IHBhdGhuYW1lID0gcGF0aC5qb2luKHRoaXMuc291cmNlUGF0aCwgcGF0aC5yZWxhdGl2ZSgnL2Fzc2V0cycsIHJlcS5wYXRoKSlcblx0XHRjb25zdCBleGlzdHMgPSBhd2FpdCBGUy5leGlzdHMocGF0aG5hbWUpXG5cblx0XHRpZiAoIWV4aXN0cykge1xuXHRcdFx0dGhyb3cgbmV3IE5vdEZvdW5kRXJyb3IoKVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLl9zZXJ2ZShyZXEsIHJlcywgdGhpcy5mYWN0b3J5Lm1ha2UocGF0aG5hbWUpKVxuXHR9XG5cblx0YXN5bmMgX3NlcnZlKHJlcSwgcmVzLCBhc3NldCkge1xuXHRcdGNvbnN0IGxhc3RNb2RpZmllZCA9IGF3YWl0IGFzc2V0Lmxhc3RNb2RpZmllZCgpXG5cblx0XHRjb25zdCBzaGExID0gY3J5cHRvLmNyZWF0ZUhhc2goJ3NoYTEnKVxuXHRcdHNoYTEudXBkYXRlKGAke2Fzc2V0LnBhdGh9XyR7bGFzdE1vZGlmaWVkfWApXG5cdFx0Y29uc3QgZXRhZyA9IGBcIiR7c2hhMS5kaWdlc3QoJ2hleCcpfVwiYFxuXG5cdFx0aWYgKCFyZXEuaGVhZGVycy5odHRwX2lmX25vbmVfbWF0Y2guaXNOaWwgJiYgcmVxLmhlYWRlcnMuaHR0cF9pZl9ub25lX21hdGNoID09PSBldGFnKSB7XG5cdFx0XHRyZXMuc2VuZCgzMDQpXG5cdFx0XHRyZXR1cm5cblx0XHR9XG5cblx0XHRjb25zdCBleHBpcmVzID0gbmV3IERhdGUoKGxhc3RNb2RpZmllZCArIDMxNTM2MDAwKSAqIDEwMDAuMClcblx0XHRjb25zdCBsYXN0TW9kaWZpZWREYXRlID0gbmV3IERhdGUobGFzdE1vZGlmaWVkICogMTAwMC4wKVxuXG5cdFx0Y29uc3QgY29tcGlsZSA9IGFzeW5jICgpID0+IHtcblx0XHRcdHJlcy5oZWFkZXIoJ1gtQ2FjaGVkJywgJ2ZhbHNlJylcblxuXHRcdFx0bGV0IHJlc3VsdCA9IGF3YWl0IGFzc2V0LmNvbXBpbGUobnVsbCwgcmVxKS50aGVuKHJlc3VsdCA9PiB7XG5cdFx0XHRcdGlmICghKHJlc3VsdCBpbnN0YW5jZW9mIEJ1ZmZlcikpIHtcblx0XHRcdFx0XHRyZXR1cm4gQnVmZmVyLmZyb20ocmVzdWx0KVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHJlc3VsdFxuXHRcdFx0fSlcblxuXHRcdFx0Y29uc3QgcG9zdFByb2Nlc3NvcnMgPSB0aGlzLmZhY3RvcnkuZ2V0UG9zdFByb2Nlc3NvcnNGcm9tUGF0aChgb3V0LiR7YXNzZXQuZXh0ZW5zaW9ufWApXG5cblx0XHRcdGlmIChwb3N0UHJvY2Vzc29ycy5sZW5ndGggPiAwKSB7XG5cdFx0XHRcdGZvciAoY29uc3QgcG9zdFByb2Nlc3NvciBvZiBwb3N0UHJvY2Vzc29ycykge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGF3YWl0IHBvc3RQcm9jZXNzb3IucHJvY2Vzcyhhc3NldC5wYXRoLCBudWxsLCByZXN1bHQpXG5cblx0XHRcdFx0XHRpZiAoIShyZXN1bHQgaW5zdGFuY2VvZiBCdWZmZXIpKSB7XG5cdFx0XHRcdFx0XHRyZXN1bHQgPSBCdWZmZXIuZnJvbShyZXN1bHQpXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBCdWZmZXIuZnJvbShyZXN1bHQpXG5cdFx0fVxuXG5cdFx0bGV0IHByb21pc2UgPSBudWxsXG5cblx0XHRpZiAodGhpcy5hcHAuY2FjaGUuaXNOaWwgfHwgcmVxLnF1ZXJ5WydpZ25vcmUtY2FjaGUnXSA9PT0gJ3RydWUnKSB7XG5cdFx0XHRwcm9taXNlID0gY29tcGlsZSgpXG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnN0IGtleSA9IGAke3JlcS5wYXRoLnJlcGxhY2UoL1teYS16MC05XSsvLCAnLScpfS0ke2xhc3RNb2RpZmllZERhdGUuZ2V0VGltZSgpfWBcblx0XHRcdGNvbnN0IG1lbW9yeUNhY2hlID0gdGhpcy5hcHAuZGVidWdcblx0XHRcdFx0PyAoZ2xvYmFsLl9fZ3JpbmRBc3NldHNDYWNoZSA9IGdsb2JhbC5fX2dyaW5kQXNzZXRzQ2FjaGUgfHwge30pXG5cdFx0XHRcdDoge31cblxuXHRcdFx0aWYgKHRoaXMuYXBwLmRlYnVnICYmIG1lbW9yeUNhY2hlW2tleV0gaW5zdGFuY2VvZiBCdWZmZXIpIHtcblx0XHRcdFx0cHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZShtZW1vcnlDYWNoZVtrZXldKVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cHJvbWlzZSA9IHRoaXMuYXBwLmNhY2hlLndyYXAoa2V5LCBjb21waWxlLCB7IHR0bDogODY0MDAgfSkudGhlbihkYXRhID0+IHtcblx0XHRcdFx0XHRpZiAoIShkYXRhIGluc3RhbmNlb2YgQnVmZmVyKSAmJiAhZGF0YS5kYXRhLmlzTmlsKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gQnVmZmVyLmZyb20oZGF0YSlcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm4gZGF0YVxuXHRcdFx0XHR9KVxuXG5cdFx0XHRcdGlmICh0aGlzLmFwcC5kZWJ1Zykge1xuXHRcdFx0XHRcdHByb21pc2UgPSBwcm9taXNlLnRoZW4oZGF0YSA9PiB7XG5cdFx0XHRcdFx0XHRpZiAodGhpcy5hcHAuZGVidWcpIHtcblx0XHRcdFx0XHRcdFx0bWVtb3J5Q2FjaGVba2V5XSA9IGRhdGFcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0cmV0dXJuIGRhdGFcblx0XHRcdFx0XHR9KVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHByb21pc2Vcblx0XHRcdC50aGVuKGNvbnRlbnQgPT4ge1xuXHRcdFx0XHRpZiAodGhpcy5hcHAuZGVidWcpIHtcblx0XHRcdFx0XHRyZXMuaGVhZGVyKCdDYWNoZS1Db250cm9sJywgJ25vLWNhY2hlJylcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXMuaGVhZGVyKCdDYWNoZS1Db250cm9sJywgJ3B1YmxpYywgbWF4LWFnZT0zMTUzNjAwMCcpXG5cdFx0XHRcdFx0cmVzLmhlYWRlcignRXhwaXJlcycsIGRhdGVGb3JtYXQoZXhwaXJlcywgSFRUUF9EQVRFX0ZPUk1BVCkpXG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXMuaGVhZGVyKCdMYXN0LU1vZGlmaWVkJywgZGF0ZUZvcm1hdChsYXN0TW9kaWZpZWREYXRlLCBIVFRQX0RBVEVfRk9STUFUKSlcblx0XHRcdFx0cmVzLmhlYWRlcignRVRhZycsIGV0YWcpXG5cdFx0XHRcdHJlcy5oZWFkZXIoJ0NvbnRlbnQtVHlwZScsIGAke2Fzc2V0Lm1pbWV9OyBjaGFyc2V0PXV0Zi04YClcblxuXHRcdFx0XHRyZXMuc2VuZChjb250ZW50KVxuXHRcdFx0fSlcblx0XHRcdC5jYXRjaChlcnIgPT4ge1xuXHRcdFx0XHRyZXMuc3RhdHVzKDUwMClcblx0XHRcdFx0cmVzLmhlYWRlcignQ29udGVudC1UeXBlJywgJ3RleHQvcGxhaW4nKVxuXG5cdFx0XHRcdExvZy5lcnJvcignQXNzZXQgY29tcGlsYXRpb24gZXJyb3InLCBlcnIubWVzc2FnZSwgZXJyKVxuXG5cdFx0XHRcdGlmICghdGhpcy5hcHAuYXNzZXRzLndlYnNvY2tldC5pc05pbCkge1xuXHRcdFx0XHRcdHRoaXMuYXBwLmFzc2V0cy53ZWJzb2NrZXQuc2VuZEFsbChcblx0XHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdFx0dHlwZTogJ2Vycm9yJyxcblx0XHRcdFx0XHRcdFx0YXNzZXQ6IHBhdGgucmVsYXRpdmUodGhpcy5hcHAucGF0aHMuYmFzZSgpLCBhc3NldC5wYXRoKSxcblx0XHRcdFx0XHRcdFx0YXNzZXRUeXBlOiBhc3NldC5raW5kLFxuXHRcdFx0XHRcdFx0XHRlcnJvcjogZXJyLm1lc3NhZ2UsXG5cdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0dHJ1ZSxcblx0XHRcdFx0XHQpXG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXMuc2VuZChgLypcXG4ke3N0cmlwQW5zaShlcnIubWVzc2FnZSl9XFxuKi9gKVxuXHRcdFx0fSlcblx0fVxufVxuIl19