Skip to content

Commit

Permalink
Merge branch 'master' of github.com:developmentseed/bones
Browse files Browse the repository at this point in the history
  • Loading branch information
miccolis committed May 10, 2011
2 parents 9422735 + 26ec80e commit 1e7339d
Show file tree
Hide file tree
Showing 37 changed files with 110 additions and 98 deletions.
62 changes: 31 additions & 31 deletions bones.js
@@ -1,44 +1,44 @@
module.exports = {
$: require('jquery'),
_: require('underscore'),
express: require('express'),
mirror: require('mirror'),
exports.$ = require('jquery');
exports._ = require('underscore');
exports.mirror = require('mirror');

utils: require('bones/server/utils'),
exports.utils = require('bones/server/utils');
exports.middleware = require('bones/server/middleware');

server: true,
exports.server = true;

Backbone: require('bones/server/backbone'),
Controller: require('bones/server/controller'),
Model: require('bones/server/model'),
Collection: require('bones/server/collection'),
Router: require('bones/server/router'),
View: require('bones/server/view'),
Server: require('bones/server/server'),
Command: require('bones/server/command'),
exports.Backbone = require('bones/server/backbone');
exports.Controller = require('bones/server/controller');
exports.Model = require('bones/server/model');
exports.Collection = require('bones/server/collection');
exports.Router = require('bones/server/router');
exports.View = require('bones/server/view');
exports.Server = require('bones/server/server');
exports.Command = require('bones/server/command');

get plugin() {
Object.defineProperty(exports, 'plugin', {
get: function() {
if (!global.__BonesPlugin__) {
var Plugin = require('./server/plugin');
global.__BonesPlugin__ = new Plugin();
require('./core');
}
return global.__BonesPlugin__;
},
}
});

load: function(dir) {
this.plugin.directories.push(dir);
this.plugin
.require(dir, 'controllers')
.require(dir, 'models')
.require(dir, 'routers')
.require(dir, 'templates')
.require(dir, 'views')
.require(dir, 'servers')
.require(dir, 'commands');
},
exports.load = function(dir) {
this.plugin.directories.push(dir);
this.plugin
.require(dir, 'controllers')
.require(dir, 'models')
.require(dir, 'routers')
.require(dir, 'templates')
.require(dir, 'views')
.require(dir, 'servers')
.require(dir, 'commands');
};

start: function() {
return this.plugin.start();
}
exports.start = function() {
return this.plugin.start();
};
2 changes: 1 addition & 1 deletion core.js
Expand Up @@ -8,7 +8,7 @@ require('bones').load(__dirname);
// Default template engine.
require.extensions['._'] = function(module, filename) {
var content = fs.readFileSync(filename, 'utf8');
var name = Bones.utils.camelize(path.basename(filename).replace(/\..+$/, ''));
var name = path.basename(filename).replace(/\..+$/, '');

try {
module.exports = _.template(content);
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
14 changes: 7 additions & 7 deletions package.json
@@ -1,16 +1,16 @@
{
"name": "bones",
"version": "1.1.0",
"version": "1.2.0",

"main": "./bones.js",

"dependencies": {
"underscore": ">= 1.1.6 < 1.2.0",
"express": ">= 2.2.2 < 2.3.0",
"backbone": ">= 0.3.3 < 0.4.0",
"jquery": ">= 1.5.1 < 1.6.0",
"optimist": ">= 0.1.9 < 0.2.0",
"mirror": ">= 0.1.0 < 0.2.0"
"underscore": "1.1.x",
"express": "2.2.x",
"backbone": "0.3.x",
"jquery": "1.5.x",
"optimist": "0.1.x",
"mirror": "0.1.x"
},

"scripts": {
Expand Down
6 changes: 3 additions & 3 deletions routers/core.bones → routers/Core.bones
Expand Up @@ -30,7 +30,7 @@ router.prototype.initializeCollections = function(app) {
router.prototype.initializeStatic = function(app) {
app.plugin.directories.forEach(function(dir) {
var pkg = JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf8'));
app.server.use('/assets/' + pkg.name, express['static'](path.join(dir, 'assets')));
app.server.use('/assets/' + pkg.name, middleware['static'](path.join(dir, 'assets')));
});
};

Expand Down Expand Up @@ -70,7 +70,7 @@ router.prototype.initializeAssets = function(app) {
var headers = { 'Content-Type': 'application/json' };

router.prototype.loadCollection = function(req, res, next) {
var name = Bones.utils.camelize(Bones.utils.pluralize(req.params.collection));
var name = Bones.utils.pluralize(req.params.collection);
if (name in this.models) {
// Pass any querystring paramaters to the collection.
req.collection = new this.models[name]([], req.query);
Expand All @@ -88,7 +88,7 @@ router.prototype.loadCollection = function(req, res, next) {
};

router.prototype.loadModel = function(req, res, next) {
var name = Bones.utils.camelize(req.params.model);
var name = req.params.model;
if (name in this.models) {
// Pass any querystring paramaters to the model.
req.model = new this.models[name]({ id: req.params.id }, req.query);
Expand Down
28 changes: 28 additions & 0 deletions server/middleware.js
@@ -0,0 +1,28 @@
exports = module.exports = require('express');

exports['csrf'] = function csrf() {
return function(req, res, next) {
if (req.method === 'GET') {
next();
} else if (req.body && req.cookies['bones.token'] && req.body['bones.token'] === req.cookies['bones.token']) {
delete req.body['bones.token'];
next();
} else {
res.send(403);
}
}
};

exports['fragmentRedirect'] = function fragmentRedirect() {
return function(req, res, next) {
// @see https://code.google.com/web/ajaxcrawling/docs/specification.html
if (req.query._escaped_fragment_ === undefined) {
next();
} else {
// Force the first char of the path to be a slash to prevent
// foreign redirects.
var path = '/' + req.query._escaped_fragment_.substr(1);
res.redirect(path, 301);
}
}
};
3 changes: 1 addition & 2 deletions server/plugin.js
Expand Up @@ -76,8 +76,7 @@ Plugin.prototype.add = function(component, filename) {
component.files.push(filename);

if (!component.title) {
component.title = utils.camelize(
path.basename(filename).replace(/\..+$/, ''));
component.title = path.basename(filename).replace(/\..+$/, '');
}

var kind = path.basename(path.dirname(filename));
Expand Down
2 changes: 1 addition & 1 deletion server/router.prefix.js
Expand Up @@ -3,7 +3,7 @@ var Bones = require('bones');
var $ = Bones.$, jQuery = $;
var _ = Bones._;
var Backbone = Bones.Backbone;
var express = Bones.express;
var middleware = Bones.middleware;
var mirror = Bones.mirror;

var models = Bones.plugin.models;
Expand Down
42 changes: 8 additions & 34 deletions server/server.js
Expand Up @@ -3,37 +3,9 @@ var _ = require('underscore');
var express = require('express');
var util = require('util');
var EventEmitter = require('events').EventEmitter;
var middleware = require('..').middleware;

module.exports = Server;

var middleware = {
csrf: function() {
return function(req, res, next) {
if (req.method === 'GET') {
next();
} else if (req.body && req.cookies['bones.token'] && req.body['bones.token'] === req.cookies['bones.token']) {
delete req.body['bones.token'];
next();
} else {
res.send(403);
}
}
},
fragRedirect: function() {
return function(req, res, next) {
// @see https://code.google.com/web/ajaxcrawling/docs/specification.html
if (req.query._escaped_fragment_ === undefined) {
next();
} else {
// Force the first char of the path to be a slash to prevent
// foreign redirects.
var path = '/' + req.query._escaped_fragment_.substr(1);
res.redirect(path, 301);
}
}
}
};

util.inherits(Server, EventEmitter);
function Server(plugin) {
this.plugin = plugin;
Expand All @@ -47,10 +19,7 @@ function Server(plugin) {
this.routers = {};
this.controllers = {};

this.middleware.forEach(function(middleware) {
this.server.use(middleware());
}, this);

this.middleware(plugin);
this.initialize(plugin);
};

Expand All @@ -65,7 +34,12 @@ _.extend(Server.prototype, Backbone.Events, {
}, this);
},

middleware: [ express.bodyParser, express.cookieParser, middleware.csrf, middleware.fragRedirect ],
middleware: function(plugin) {
this.server.use(middleware.bodyParser());
this.server.use(middleware.cookieParser());
this.server.use(middleware.csrf());
this.server.use(middleware.fragmentRedirect());
},

port: 3000,

Expand Down
2 changes: 1 addition & 1 deletion server/server.prefix.js
Expand Up @@ -3,7 +3,7 @@ var Bones = require('bones');
var $ = Bones.$, jQuery = $;
var _ = Bones._;
var Backbone = Bones.Backbone;
var express = Bones.express;
var middleware = Bones.middleware;
var mirror = Bones.mirror;

var models = Bones.plugin.models;
Expand Down
2 changes: 1 addition & 1 deletion server/utils.js
Expand Up @@ -45,7 +45,7 @@ fs.readdirSync(wrapperDir).forEach(function(name) {

utils.wrapClientFile = function(content, filename) {
var kind = utils.singularize(path.basename(path.dirname(filename)));
var name = utils.camelize(path.basename(filename).replace(/\..+$/, ''));
var name = path.basename(filename).replace(/\..+$/, '');

wrappers[kind] = wrappers[kind] || {};
wrappers[kind].prefix = wrappers[kind].prefix || '';
Expand Down
12 changes: 0 additions & 12 deletions shared/utils.js
Expand Up @@ -5,18 +5,6 @@ if (typeof process !== 'undefined' && process.versions && process.versions.node)
module.exports = Bones.utils;
}

Bones.utils.camelize = function(text) {
return text.replace(/(?:^|_)(.)/g, function(all, chr) {
return chr.toUpperCase();
});
};

Bones.utils.underscoreify = function(text) {
return text.replace(/[A-Z]/g, function(match) {
return '_'+ match.toLowerCase();
}).replace(/^_/, '');
};

// From https://github.com/visionmedia/lingo/blob/master/lib/languages/en.js
Bones.utils.uncountable = [ 'advice', 'enegery', 'excretion', 'digestion',
'cooperation', 'health', 'justice', 'jeans', 'labour', 'machinery',
Expand Down
2 changes: 1 addition & 1 deletion test/collections.test.js
Expand Up @@ -6,7 +6,7 @@ var main = new demo.servers['Main'](demo);

exports['api endpoints'] = function() {
assert.response(main.server, {
url: '/api/house',
url: '/api/House',
method: 'GET'
}, {
body: '[{"foo":"bar"},{"foo":"baz"},{"foo":"blah"}]',
Expand Down
30 changes: 27 additions & 3 deletions test/demo.test.js
Expand Up @@ -48,6 +48,19 @@ exports['routes'] = function(beforeExit) {
assert.response(main.server, {
url: '/page/foo',
method: 'POST'
}, {
body: 'Forbidden',
status: 403
});

assert.response(main.server, {
url: '/page/foo',
method: 'POST',
headers: {
'content-type': 'application/json',
'cookie': 'bones.token=1f4a1137268b8e384e50d0fb72c627c4'
},
body: '{"bones.token":"1f4a1137268b8e384e50d0fb72c627c4"}'
}, {
body: 'Cannot POST /page/foo',
status: 404
Expand All @@ -56,7 +69,7 @@ exports['routes'] = function(beforeExit) {

exports['api endpoints'] = function() {
assert.response(main.server, {
url: '/api/page/foo',
url: '/api/Page/foo',
method: 'GET'
}, {
body: '{"id":"foo","method":"read"}',
Expand All @@ -65,9 +78,20 @@ exports['api endpoints'] = function() {

assert.response(main.server, {
url: '/api/page/foo',
method: 'GET'
}, {
body: 'Cannot GET /api/page/foo',
status: 404
});

assert.response(main.server, {
url: '/api/Page/foo',
method: 'PUT',
headers: { 'content-type': 'application/json' },
body: '{"id":"foo","key":"value"}'
headers: {
'content-type': 'application/json',
'cookie': 'bones.token=1f4a1137268b8e384e50d0fb72c627c4'
},
body: '{"bones.token":"1f4a1137268b8e384e50d0fb72c627c4","id":"foo","key":"value"}'
}, {
body: '{"id":"foo","key":"value","method":"update"}',
status: 200
Expand Down
1 change: 0 additions & 1 deletion test/fixtures/collections/node_modules/bones/index.js

This file was deleted.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 comments on commit 1e7339d

Please sign in to comment.