UNPKG

asset-rack

Version:

Static Web Framework for Nodejs

322 lines (294 loc) 9.66 kB
// Generated by CoffeeScript 1.6.3 (function() { var BufferStream, ConfigRack, EventEmitter, async, extend, fs, jade, pathutil, pkgcloud, _ref, __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'); pkgcloud = require('pkgcloud'); fs = require('fs'); jade = require('jade'); pathutil = require('path'); _ref = require('./util'), BufferStream = _ref.BufferStream, extend = _ref.extend; EventEmitter = require('events').EventEmitter; exports.Rack = (function(_super) { __extends(Rack, _super); function Rack(assets, options) { var asset, _i, _len, _this = this; Rack.__super__.constructor.call(this); if (options == null) { options = {}; } this.maxAge = options.maxAge; this.allowNoHashCache = options.allowNoHashCache; this.on('complete', function() { return _this.completed = true; }); this.on('newListener', function(event, listener) { if (event === 'complete' && _this.completed === true) { return listener(); } }); this.on('error', function(error) { console.log(error); _this.hasError = true; return _this.currentError = error; }); for (_i = 0, _len = assets.length; _i < _len; _i++) { asset = assets[_i]; asset.rack = this; } this.assets = []; async.forEachSeries(assets, function(asset, next) { asset.on('error', function(error) { return next(error); }); asset.on('complete', function() { if (_this.completed) { return; } if (asset.contents != null) { _this.assets.push(asset); } if (asset.assets != null) { _this.assets = _this.assets.concat(asset.assets); } return next(); }); return asset.emit('start'); }, function(error) { if (error != null) { return _this.emit('error', error); } return _this.emit('complete'); }); } Rack.prototype.handle = function(request, response, next) { var asset, check, handle, _i, _len, _ref1, _this = this; response.locals({ assets: this }); if (request.url.slice(0, 11) === '/asset-rack') { return this.handleAdmin(request, response, next); } if (this.hasError) { _ref1 = this.assets; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { asset = _ref1[_i]; check = asset.checkUrl(request.path); if (check) { return asset.respond(request, response); } } return response.redirect('/asset-rack/error'); } handle = function() { var _j, _len1, _ref2; _ref2 = _this.assets; for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { asset = _ref2[_j]; check = asset.checkUrl(request.path); if (check) { return asset.respond(request, response); } } return next(); }; if (this.completed) { return handle(); } else { return this.on('complete', handle); } }; Rack.prototype.handleError = function(request, response, next) { var errorPath, _this = this; if (process.env.NODE_ENV === 'production') { return next(); } errorPath = pathutil.join(__dirname, 'admin/templates/error.jade'); return fs.readFile(errorPath, 'utf8', function(error, contents) { var compiled; if (error != null) { return next(error); } compiled = jade.compile(contents, { filename: errorPath }); return response.send(compiled({ stack: _this.currentError.stack.split('\n') })); }); }; Rack.prototype.handleAdmin = function(request, response, next) { var adminPath, path, split, _this = this; if (process.env.NODE_ENV === 'production') { return next(); } split = request.url.split('/'); if (split.length > 2) { path = request.url.replace('/asset-rack/', ''); if (path === 'error') { return this.handleError(request, response, next); } return response.sendfile(pathutil.join(__dirname, 'admin', path)); } else { adminPath = pathutil.join(__dirname, 'admin/templates/admin.jade'); return fs.readFile(adminPath, 'utf8', function(error, contents) { var compiled; if (error != null) { return next(error); } compiled = jade.compile(contents, { filename: adminPath }); return response.send(compiled({ assets: _this.assets })); }); } }; Rack.prototype.writeConfigFile = function(filename) { var asset, config, _i, _len, _ref1; config = {}; _ref1 = this.assets; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { asset = _ref1[_i]; config[asset.url] = asset.specificUrl; } return fs.writeFileSync(filename, JSON.stringify(config)); }; Rack.prototype.deploy = function(options, next) { var deploy, _this = this; options.keyId = options.accessKey; options.key = options.secretKey; deploy = function() { var assets, client; client = pkgcloud.storage.createClient(options); assets = _this.assets; if (options.provider === 'rackspace') { assets = _this.assets.concat(_this.assets[0]); } return async.forEachSeries(assets, function(asset, next) { var clientOptions, headers, key, stream, url, value, _ref1; stream = null; headers = {}; if (asset.gzip) { stream = new BufferStream(asset.gzipContents); headers['content-encoding'] = 'gzip'; } else { stream = new BufferStream(asset.contents); } url = asset.specificUrl.slice(1, asset.specificUrl.length); _ref1 = asset.headers; for (key in _ref1) { value = _ref1[key]; headers[key] = value; } if (options.provider === 'amazon') { headers['x-amz-acl'] = 'public-read'; } clientOptions = { container: options.container, remote: url, headers: headers, stream: stream }; return client.upload(clientOptions, function(error) { if (error != null) { return next(error); } return next(); }); }, function(error) { if (error != null) { if (next != null) { return next(error); } throw error; } if (options.configFile != null) { _this.writeConfigFile(options.configFile); } if (next != null) { return next(); } }); }; if (this.completed) { return deploy(); } else { return this.on('complete', deploy); } }; Rack.prototype.tag = function(url) { var asset, _i, _len, _ref1; _ref1 = this.assets; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { asset = _ref1[_i]; if (asset.url === url) { return asset.tag(); } } throw new Error("No asset found for url: " + url); }; Rack.prototype.url = function(url) { var asset, _i, _len, _ref1; _ref1 = this.assets; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { asset = _ref1[_i]; if (url === asset.url) { return asset.specificUrl; } } }; Rack.extend = extend; return Rack; })(EventEmitter); ConfigRack = (function() { function ConfigRack(options) { if (options.configFile == null) { throw new Error('options.configFile is required'); } if (options.hostname == null) { throw new Error('options.hostname is required'); } this.assetMap = require(options.configFile); this.hostname = options.hostname; } ConfigRack.prototype.handle = function(request, response, next) { var specificUrl, url, _ref1; response.locals({ assets: this }); _ref1 = this.assetMap; for (url in _ref1) { specificUrl = _ref1[url]; if (request.path === url || request.path === specificUrl) { return response.redirect("//" + this.hostname + specificUrl); } } return next(); }; ConfigRack.prototype.tag = function(url) { var tag; switch (pathutil.extname(url)) { case '.js': tag = "\n<script type=\"text/javascript\" "; return tag += "src=\"//" + this.hostname + this.assetMap[url] + "\"></script>"; case '.css': return "\n<link rel=\"stylesheet\" href=\"//" + this.hostname + this.assetMap[url] + "\">"; } }; ConfigRack.prototype.url = function(url) { return "//" + this.hostname + this.assetMap[url]; }; return ConfigRack; })(); exports.fromConfigFile = function(options) { return new ConfigRack(options); }; }).call(this);