asset-rack
Version:
Static Web Framework for Nodejs
271 lines (245 loc) • 8.22 kB
JavaScript
// Generated by CoffeeScript 1.6.3
(function() {
var EventEmitter, async, crypto, extend, fs, mime, pathutil, zlib,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
async = require('async');
crypto = require('crypto');
pathutil = require('path');
fs = require('fs');
zlib = require('zlib');
mime = require('mime');
extend = require('./util').extend;
EventEmitter = require('events').EventEmitter;
mime.types.js = 'text/javascript';
mime.extensions['text/javascript'] = 'js';
exports.Asset = (function(_super) {
__extends(Asset, _super);
Asset.prototype.defaultMaxAge = 60 * 60 * 24 * 365;
function Asset(options) {
var headers, key, value, _ref,
_this = this;
Asset.__super__.constructor.call(this);
if (options == null) {
options = {};
}
if (options.url != null) {
this.url = options.url;
}
if (options.contents != null) {
this.contents = options.contents;
}
this.headers = options.headers ? options.headers : {};
headers = {};
_ref = this.headers;
for (key in _ref) {
value = _ref[key];
headers[key.toLowerCase()] = value;
}
this.headers = headers;
this.ext = pathutil.extname(this.url);
this.watch = options.watch;
if (this.watch == null) {
this.watch = false;
}
if (options.mimetype != null) {
this.mimetype = options.mimetype;
}
if (this.mimetype == null) {
this.mimetype = mime.types[this.ext.slice(1, this.ext.length)];
}
if (this.mimetype == null) {
this.mimetype = 'text/plain';
}
this.gzip = options.gzip;
if (options.hash != null) {
this.hash = options.hash;
}
if (options.maxAge != null) {
this.maxAge = options.maxAge;
}
if (options.allowNoHashCache != null) {
this.allowNoHashCache = options.allowNoHashCache;
}
this.on('newListener', function(event, listener) {
if (event === 'complete' && _this.completed === true) {
return listener();
}
});
this.on('created', function(data) {
if ((data != null ? data.contents : void 0) != null) {
_this.contents = data.contents;
}
if ((data != null ? data.assets : void 0) != null) {
_this.assets = data.assets;
}
if (_this.contents != null) {
_this.createSpecificUrl();
_this.createHeaders();
}
if (_this.assets != null) {
async.forEach(_this.assets, function(asset, done) {
asset.on('error', done);
return asset.on('complete', done);
}, function(error) {
if (error != null) {
return _this.emit('error', error);
}
_this.completed = true;
return _this.emit('complete');
});
} else {
_this.completed = true;
if (_this.gzip) {
zlib.gzip(_this.contents, function(error, gzip) {
_this.gzipContents = gzip;
return _this.emit('complete');
});
} else {
_this.emit('complete');
}
}
if (_this.watch) {
return _this.watcher = fs.watch(_this.toWatch, function(event, filename) {
if (event === 'change') {
_this.watcher.close();
_this.completed = false;
_this.assets = false;
return process.nextTick(function() {
return _this.emit('start');
});
}
});
}
});
this.on('error', function(error) {
if (_this.listeners('error') === 1) {
throw error;
}
});
this.on('start', function() {
var _ref1, _ref2;
if (_this.maxAge == null) {
_this.maxAge = (_ref1 = _this.rack) != null ? _ref1.maxAge : void 0;
}
if (_this.hash !== false) {
if (_this.maxAge == null) {
_this.maxAge = _this.defaultMaxAge;
}
}
if (_this.allowNoHashCache == null) {
_this.allowNoHashCache = (_ref2 = _this.rack) != null ? _ref2.allowNoHashCache : void 0;
}
return _this.create(options);
});
process.nextTick(function() {
if (_this.maxAge == null) {
_this.maxAge = _this.defaultMaxAge;
}
if (_this.rack == null) {
return _this.create(options);
}
});
}
Asset.prototype.addAsset = function(asset) {
if (this.assets == null) {
this.assets = [];
}
return this.assets.push(asset);
};
Asset.prototype.respond = function(request, response) {
var headers, key, value, _ref;
headers = {};
if (request.path === this.url && this.allowNoHashCache !== true) {
_ref = this.headers;
for (key in _ref) {
value = _ref[key];
headers[key] = value;
}
delete headers['cache-control'];
} else {
headers = this.headers;
}
for (key in headers) {
value = headers[key];
response.header(key, value);
}
if (this.gzip) {
return response.send(this.gzipContents);
} else {
return response.send(this.contents);
}
};
Asset.prototype.checkUrl = function(url) {
return url === this.specificUrl || ((this.hash == null) && url === this.url);
};
Asset.prototype.handle = function(request, response, next) {
var handle,
_this = this;
handle = function() {
var asset, _i, _len, _ref;
if (_this.assets != null) {
_ref = _this.assets;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
asset = _ref[_i];
if (asset.checkUrl(request.path)) {
return asset.respond(request, response);
}
}
}
if (_this.checkUrl(request.path)) {
return _this.respond(request, response);
} else {
return next();
}
};
if (this.completed === true) {
return handle();
} else {
return this.on('complete', function() {
return handle();
});
}
};
Asset.prototype.create = function(options) {
return this.emit('created');
};
Asset.prototype.createHeaders = function() {
var _base, _base1, _base2;
if ((_base = this.headers)['content-type'] == null) {
_base['content-type'] = "" + this.mimetype;
}
if (this.gzip) {
if ((_base1 = this.headers)['content-encoding'] == null) {
_base1['content-encoding'] = 'gzip';
}
}
if (this.maxAge != null) {
return (_base2 = this.headers)['cache-control'] != null ? (_base2 = this.headers)['cache-control'] : _base2['cache-control'] = "public, max-age=" + this.maxAge;
}
};
Asset.prototype.tag = function() {
var tag;
switch (this.mimetype) {
case 'text/javascript':
tag = "\n<script type=\"" + this.mimetype + "\" ";
return tag += "src=\"" + this.specificUrl + "\"></script>";
case 'text/css':
return "\n<link rel=\"stylesheet\" href=\"" + this.specificUrl + "\">";
}
};
Asset.prototype.createSpecificUrl = function() {
this.md5 = crypto.createHash('md5').update(this.contents).digest('hex');
if (this.hash === false) {
this.useDefaultMaxAge = false;
return this.specificUrl = this.url;
}
this.specificUrl = "" + (this.url.slice(0, this.url.length - this.ext.length)) + "-" + this.md5 + this.ext;
if (this.hostname != null) {
return this.specificUrl = "//" + this.hostname + this.specificUrl;
}
};
Asset.extend = extend;
return Asset;
})(EventEmitter);
}).call(this);