Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
Checking mergeability… Don't worry, you can still create the pull request.
  • 19 commits
  • 13 files changed
  • 3 commit comments
  • 4 contributors
View
4 .travis.yml
@@ -0,0 +1,4 @@
+language: node_js
+node_js:
+ - 0.6
+ - 0.8
View
3  README.md
@@ -1,3 +1,4 @@
+[![build status](https://secure.travis-ci.org/nrstott/bogart.png)](http://travis-ci.org/nrstott/bogart)
# Bogart
A blazing fast rapid application development web framework using JSGI for [node](http://nodejs.org/).
@@ -48,7 +49,7 @@ If you can't run on 8080, change the `app.start` call e.g. `app.start(9090, '127
## Routing
-Routing in Bogart is simple and intuitive. A route is a HTTP method paried with a
+Routing in Bogart is simple and intuitive. A route is a HTTP method paired with a
URL matching pattern and a handler function.
var router = bogart.router();
View
13 examples/haml-view/app.js
@@ -1,13 +0,0 @@
-var
- jsgi = require('jsgi'),
- bogart = require('../../lib/bogart')
-
-var app = bogart.app(function(show) {
- var viewEngine = bogart.viewEngine("haml");
-
- show('/', function(req) {
- return viewEngine.respond('index.haml', { layout: false });
- });
-});
-
-jsgi.start(app)
View
13 examples/haml-view/package.json
@@ -1,13 +0,0 @@
-{
- "name": "haml-example",
- "version": "1.0.0",
- "author": "Nathan Stott",
- "email": "nathan.stott@whiteboard-it.com",
- "main": "./app.js",
- "directories": { "lib": "./lib" },
- "dependencies": {
- "promised-io": "v0.2.1",
- "jsgi": "v0.2.2",
- "mustache": "0.3.1-dev"
- }
-}
View
2  examples/haml-view/views/index.haml
@@ -1,2 +0,0 @@
-%h1 Hello World
-%p This template is written using HAML
View
4 examples/task-list/app.js
@@ -48,10 +48,10 @@ router.post("/", function(req) {
return bogart.redirect("/");
});
-router.del("/:name", function(req, name) {
+router.del("/:name", function(req) {
console.log('deleting '+req.params.name);
console.log(tasks);
- delete tasks[name];
+ delete tasks[req.params.name];
return bogart.redirect("/");
});
View
8 lib/bogart.js
@@ -11,7 +11,7 @@ var
inherits = require('util').inherits,
EventEmitter = require('events').EventEmitter;
-exports.version = [0,3,40];
+exports.version = [0,3,44];
exports.q = Q;
@@ -157,9 +157,9 @@ App.prototype.start = function(port, host) {
if (Router.isRouter(descriptor.middleware)) {
descriptor.middleware.nextApp = app;
app = descriptor.middleware;
+ } else {
+ app = descriptor.middleware.apply(descriptor.middleware, descriptor.args.concat([ app ]));
}
-
- app = descriptor.middleware.apply(descriptor.middleware, descriptor.args.concat([ app ]));
});
}
@@ -241,7 +241,7 @@ exports.router = function(config, notFoundApp) {
return {
status: 404,
body: [body],
- headers: { 'Content-Length': body.length, 'Content-Type': 'text/html' }
+ headers: { 'Content-Length': Buffer.byteLength(body, 'utf-8'), 'Content-Type': 'text/html' }
};
},
router = new Router(config),
View
38 lib/middleware.js
@@ -6,7 +6,8 @@ var Q = require('promised-io/promise'),
util = require('./util'),
merge = util.merge,
EventEmitter = require('events').EventEmitter,
- _ = require('underscore');
+ _ = require('underscore'),
+ Router = require('./router').Router;
function join(forEachable) {
var body = '',
@@ -723,26 +724,32 @@ exports.binary = function(conditional, appTrue, appFalse) {
*/
exports.cascade = function(accept /*, apps */) {
var args = Array.prototype.slice.call(arguments)
- , apps = [];
+ , middlewareQueue = [];
accept = args.shift();
args.forEach(function(x) {
- apps.push(x);
+ middlewareQueue.push(x);
});
- return function(req) {
+ var cascadeApp = function(req) {
var deferred = Q.defer();
- function next(apps) {
- var nextAction = apps.shift();
+ function next() {
+ var nextAction = middlewareQueue.shift();
+
+ this.started = true;
+
+ if (Router.isRouter(nextAction)) {
+ nextAction.nextApp = next;
+ }
if (nextAction) {
Q.whenCall(function() { return nextAction(req); }, function(resp) {
if (accept(resp)) {
return deferred.resolve(resp);
} else {
- return next(apps);
+ return next();
}
}, deferred.reject);
} else {
@@ -750,10 +757,25 @@ exports.cascade = function(accept /*, apps */) {
}
}
- next(apps.concat());
+ next();
return deferred.promise;
};
+
+ cascadeApp.use = function(middleware /*, parameters */) {
+ if (this.started) {
+ throw {
+ message: 'Cascade has already been started. The middleware may only be configured before it is started.',
+ code: 'BOGART_CASCADE_ALREADY_STARTED'
+ };
+ }
+
+ var args = Array.prototype.slice.call(arguments);
+
+ middlewareQueue.push(middleware);
+ };
+
+ return cascadeApp;
};
/**
View
1  lib/mimetypes.js
@@ -98,6 +98,7 @@ exports.mimeTypes = {
".m3u" : "audio/x-mpegurl",
".m4v" : "video/mp4",
".man" : "text/troff",
+ ".manifest": "text/cache-manifest",
".mathml" : "application/mathml+xml",
".mbox" : "application/mbox",
".mdoc" : "text/troff",
View
31 lib/view.js
@@ -10,6 +10,8 @@ var
settings = {},
_ = require('underscore'),
events = require('events'),
+ async = require('async'),
+ q = require('promised-io/promise'),
util = require('util');
// TODO: Figure out how to make this work x-platform using the nodules 'engines' overlay
@@ -221,27 +223,32 @@ exports.viewEngine.engine = function(engineName) {
};
exports.viewEngine.addEngine('mustache', function(str, opts, cache, viewEngine) {
- var partialPromises = []
- , partials = {}
+ var partials = {}
, viewPath;
-
+
opts = _.extend({}, opts);
if (opts.partials) {
- for (var k in opts.partials) {
+ var defer = q.defer();
+
+ async.forEach(Object.keys(opts.partials), function(k, callback) {
viewPath = path.join(viewEngine.views, opts.partials[k]);
- partialPromises.push(when(viewEngine.viewCache[viewPath] || viewEngine.cacheView(viewPath), function(str) {
+ when(viewEngine.viewCache[viewPath] || viewEngine.cacheView(viewPath), function(str) {
partials[k] = str;
- return str;
- }));
- }
-
- return promise.all(partialPromises).then(function() {
- delete opts.partials;
+ callback();
+ });
+ }, function(err) {
+ delete opts.partials;
- return require('mustache').to_html(str, opts.locals, partials);
+ if (err) {
+ defer.reject(err);
+ } else {
+ defer.resolve(require('mustache').to_html(str, opts.locals, partials));
+ }
});
+
+ return defer.promise;
}
return require('mustache').to_html(str, opts.locals);
View
8 package.json
@@ -1,7 +1,7 @@
{
"name": "bogart",
"description": "Fast JSGI web framework taking inspiration from Sinatra",
- "version": "0.3.40",
+ "version": "0.3.44",
"keywords": ["bogart", "framework", "sinatra", "REST"],
"author": "Nathan Stott <nrstott@gmail.com>",
"email": "nathan.stott@whiteboard-it.com",
@@ -19,14 +19,16 @@
"dependencies": {
"promised-io": "v0.3.0",
"jsgi": ">=v0.2.2",
- "mustache": "0.3.1-dev",
+ "mustache": "0.7.2",
"underscore": ">=0.0.0",
"node-uuid": ">=1.2.0",
"parted": "=0.0.8",
"oauth": "=0.9.5",
"request": "=2.2.9",
"commander": "*",
- "mkdirp": "*"
+ "mkdirp": "*",
+ "async": "0.1.22",
+ "promised-io": "0.2.3"
},
"devDependencies": {
"haml": ">=0.4.2",
View
58 test/middleware.test.js
@@ -5,7 +5,8 @@ var bogart = require('../lib/bogart')
, security = require("../lib/security")
, util = require('util')
, test = require('tap').test
- , plan = require('tap').plan;
+ , plan = require('tap').plan
+ , mockRequest = require('./test-util').mockRequest;
test("test parses JSON", function(t) {
var forEachDeferred = Q.defer()
@@ -402,6 +403,61 @@ test("test bodyAdapter adapts Stream", function(t) {
});
});
+test("test cascade works with a router", function(t){
+ var cascade = bogart.middleware.cascade(function() { return true; })
+ , router = bogart.router()
+ , txt = 'Hello World';
+
+ router.get('/', function(req){
+ return bogart.text(txt);
+ });
+
+ cascade.use(router);
+
+ var resPromise = cascade(mockRequest('/'));
+
+ resPromise.then(function(res){
+ t.equal(txt, res.body.join());
+ }, function(err){
+ t.ok(false, err, 'found error');
+ });
+
+ t.plan(1);
+});
+
+test("test cascade passes to second router", function(t){
+ var router1 = bogart.router()
+ , router2 = bogart.router()
+ , txt = 'Hello World'
+ , cascade = bogart.middleware.cascade(function(res) {
+ return res.status != 404;
+ });
+
+ router1.get('/', function(req) {
+ return {
+ status: 404,
+ body: []
+ };
+ });
+
+ router2.get('/', function(req) {
+ return bogart.text(txt);
+ });
+
+ cascade.use(router1);
+ cascade.use(router2);
+
+ var resPromise = cascade(mockRequest('/'));
+
+ resPromise.then(function(res) {
+ t.equal(txt, res.body.join());
+ }, function(err) {
+ t.ok(false, err, 'found error');
+ });
+
+ t.plan(1);
+});
+
/**
* Create a mock request
*
View
15 test/test-util.js
@@ -0,0 +1,15 @@
+function mockRequest(path) {
+ return {
+ headers: {},
+ pathInfo: path,
+ method: 'GET',
+ jsgi: { version: [0,3] },
+ env: {}
+ };
+}
+
+function rootRequest() {
+ return mockRequest('/');
+}
+
+exports.mockRequest = mockRequest;

Showing you all comments on commits in this comparison.

@bennlich

Looks like this may have broken the readme image?

@nrstott
Owner

You're right, thanks. Checking it out.

@nrstott
Owner

It can't even find the nrstott/bogart information. Maybe something is wrong on their site? The image actually links to their site. Will investigate further.

Something went wrong with that request. Please try again.