Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

bones

Package Overview
Dependencies
Maintainers
0
Versions
51
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bones - npm Package Compare versions

Comparing version 1.2.6 to 1.3.0

servers/Asset.bones

3

bones.js
if (global.__BonesPlugin__) {
console.trace("\033[0;31mMultiple instances of bones are not supported.\033[0m");
process.exit(1);
process.exit(4);
}

@@ -19,3 +19,2 @@

exports.Collection = require('bones/server/collection');
exports.Router = require('bones/server/router');
exports.View = require('bones/server/view');

@@ -22,0 +21,0 @@ exports.Server = require('bones/server/server');

{
"name": "bones",
"version": "1.2.6",
"version": "1.3.0",

@@ -17,4 +17,5 @@ "main": "./bones.js",

"scripts": {
"test": "expresso"
"test": "expresso",
"coverage": "./test/coverage.sh"
}
}

@@ -7,4 +7,2 @@ var Backbone = require('./backbone');

function Command(plugin, callback) {
this.options = Object.create(Command.options);
this.bootstrap(plugin, function() {

@@ -21,5 +19,15 @@ this.initialize(plugin, callback);

Command.prototype.toString = function() {
return '[Command ' + this.constructor.title + ']';
};
Command.augment = Backbone.Controller.augment;
Command.extend = Backbone.Controller.extend;
Command.extend = _.wrap(Command.extend, function(parent, props, staticProps) {
var result = parent.call(this, props, staticProps);
result.options = Object.create(this.options);
return result;
});
Command.toString = function() {

@@ -29,2 +37,7 @@ return '<Command ' + this.title + '>';

Command.options = {};
Command.options = {
'host': {
'description': 'Hostnames allowed for requests. Wildcards are allowed.',
'default': [ 'localhost', require('os').hostname() ]
}
};

@@ -6,8 +6,8 @@ var Backbone = require('./backbone');

Backbone.Controller.register = function(app) {
Backbone.Controller.register = function(server) {
// Add the controller if it's not a server-only controller.
this.files.forEach(function(filename) {
if (!(/\.server\.bones$/).test(filename) && app.assets &&
app.assets.controllers.indexOf(filename) < 0) {
app.assets.controllers.push(filename);
if (!(/\.server\.bones$/).test(filename) && server.assets &&
server.assets.controllers.indexOf(filename) < 0) {
server.assets.controllers.push(filename);
}

@@ -18,3 +18,3 @@ });

return app.controllers[this.title] = new this(app);
return server.controllers[this.title] = new this({ server: server });
};

@@ -26,7 +26,7 @@

Backbone.Controller.prototype.initialize = function(app) {
if (!app.server) {
Backbone.Controller.prototype.initialize = function(options) {
if (!options.server) {
throw new Error("Can't initialize controller without server.");
}
this.server = app.server;
this.server = options.server;

@@ -33,0 +33,0 @@ // Bind routes.

var env = process.env.NODE_ENV || 'development';
var host = require('os').hostname();
exports = module.exports = require('express');
exports['sanitizeHost'] = function sanitizeHost(app) {
var hosts = app.config.host;
if (!Array.isArray(hosts)) {
hosts = app.config.host = [ hosts ];
}
if (hosts) {
hosts.forEach(function(host, i) {
if (typeof host === 'string') {
hosts[i] = new RegExp('^' + hosts[i].replace(/\./g, '\\.').replace(/\*/g, '[a-z0-9_-]+') + '(:\\d+)?$', 'i');
// Make sure we get the original host names when stringifying the host name matcher.
hosts[i].toJSON = function() { return host; };
}
});
}
return function(req, res, next) {
if (!req.headers.host) {
return next();
} else if (!hosts.length) {
req.headers.host = host;
return next();
} else {
for (var i = 0; i < hosts.length; i++) {
if (hosts[i].test(req.headers.host)) {
return next();
}
}
}
res.send(400);
};
};
exports['csrf'] = function csrf() {

@@ -15,3 +49,3 @@ return function(req, res, next) {

}
}
};
};

@@ -30,3 +64,3 @@

}
}
};
};

@@ -33,0 +67,0 @@

@@ -10,12 +10,12 @@ var Backbone = require('./backbone');

Backbone.Model.register = function(app) {
Backbone.Model.register = function(server) {
// Add the controller if it's not a server-only controller.
this.files.forEach(function(filename) {
if (!(/\.server\.bones$/).test(filename) && app.assets &&
app.assets.models.indexOf(filename) < 0) {
app.assets.models.push(filename);
if (!(/\.server\.bones$/).test(filename) && server.assets &&
server.assets.models.indexOf(filename) < 0) {
server.assets.models.push(filename);
}
});
app.models[this.title] = this;
server.models[this.title] = this;
};

@@ -22,0 +22,0 @@

@@ -73,3 +73,2 @@ var path = require('path');

this.models = {};
this.routers = {};
this.templates = {};

@@ -90,3 +89,2 @@ this.views = {};

this.require(dir, 'models');
this.require(dir, 'routers');
this.require(dir, 'templates');

@@ -98,3 +96,3 @@ this.require(dir, 'views');

return this;
}
};

@@ -137,7 +135,10 @@ Plugin.prototype.require = function(dir, kind) {

if (this.argv.help || !(command in this.commands)) {
this.help();
this.help(callback);
} else {
var command = this.commands[command];
this.loadConfig(command);
return new command(this, callback);
if (this.loadConfig(command)) {
return new command(this, callback);
} else if (callback) {
callback();
}
}

@@ -207,6 +208,10 @@ };

console.warn(JSON.stringify(config, false, 4));
return false;
} else {
return true;
}
};
Plugin.prototype.help = function() {
Plugin.prototype.help = function(callback) {
var output = [];
var command = this.argv._.length ? this.argv._[0] : false;

@@ -216,11 +221,11 @@ if (command !== false && command in this.commands) {

var command = this.commands[command];
console.log('Usage: %s', utils.colorize(this.argv['$0'] + ' ' +
output.push(['Usage: %s', utils.colorize(this.argv['$0'] + ' ' +
command.title +
(command.usage ? ' ' + command.usage : '') +
' [options...]', 'green'));
' [options...]', 'green')]);
console.log('%s%s: %s',
output.push(['%s%s: %s',
utils.colorize(command.title, 'yellow', 'bold'),
utils.colorize(command.usage ? ' ' + command.usage : '', 'yellow'),
command.description);
command.description]);

@@ -235,3 +240,3 @@ var options = [];

'--' + (option.title || key),
(option.description ? option.description + ' ' : '') + '(Default: ' + util.inspect(value) +')'
(option.description ? option.description + ' ' : '') + '(Default: ' + JSON.stringify(value) +')'
]);

@@ -241,7 +246,7 @@ }

table(options);
table(options).forEach(function(line) { output.push(line); });
} else {
// Display information about all available commands.
console.log('Usage: %s for a list of options.', utils.colorize(this.argv['$0'] + ' ' + (command || '[command]') + ' --help', 'green'));
console.log('Available commands are:');
output.push(['Usage: %s for a list of options.', utils.colorize(this.argv['$0'] + ' ' + (command || '[command]') + ' --help', 'green')]);
output.push(['Available commands are:']);
var commands = [];

@@ -251,9 +256,18 @@ for (var key in this.commands) {

}
table(commands);
table(commands).forEach(function(line) { output.push(line); });
}
process.exit(1);
if (callback) {
callback(output);
} else {
output.forEach(function(params) {
console.log.apply(console, params);
});
process.exit(1);
}
};
function table(fields) {
if (!fields[0]) return;
var output = [];
if (!fields[0]) return output;
var lengths = fields[0].map(function(val, i) {

@@ -265,3 +279,3 @@ return Math.max.apply(Math, fields.map(function(field) {

fields.forEach(function(field) {
console.log(
output.push([
' ' + field.map(function(val, i) {

@@ -271,4 +285,5 @@ if (i >= lengths.length - 1) return val;

}).join(' ')
);
]);
});
return output;
};
var Backbone = require('./backbone');
var _ = require('underscore');
var express = require('express');
var util = require('util');
var EventEmitter = require('events').EventEmitter;
var HTTPServer = require('express').HTTPServer;
var middleware = require('..').middleware;
module.exports = Server;
util.inherits(Server, EventEmitter);
function Server(plugin) {
HTTPServer.call(this, []);
this.plugin = plugin;
this.server = new express.createServer();
// Stores models, views served by this server.
this.models = {};
this.views = {};
// Stores instances of routers and controllers registered with this server.
this.routers = {};
this.controllers = {};
this.middleware(plugin);
this.initialize(plugin);

@@ -27,32 +14,23 @@ this.conclude(plugin);

Server.prototype.__proto__ = HTTPServer.prototype;
_.extend(Server.prototype, Backbone.Events, {
initialize : function(plugin) {
// Default implementation loads all components.
var components = ['routers', 'controllers', 'models', 'views', 'templates'];
components.forEach(function(kind) {
for (var name in plugin[kind]) {
plugin[kind][name].register(this);
}
}, this);
},
initialize : function(plugin) {},
middleware: function(plugin) {
this.server.use(middleware.bodyParser());
this.server.use(middleware.cookieParser());
this.server.use(middleware.csrf());
this.server.use(middleware.fragmentRedirect());
this.server.error(middleware.showError());
},
// TODO: Find a better solution for pre/post hooks
conclude: function(plugin) {
if (this.server) {
this.server.use(middleware.notFound());
// Add catchall 404 middleware and error handler for root servers.
if (this.port) {
this.use(middleware.notFound());
this.error(middleware.showError());
// Remove redundant frontmost middleware from each server that will not
// be a root server. See `express/lib/http.js`.
} else {
this.stack.shift();
}
},
port: 3000,
port: null,
start: function(callback) {
this.server.listen(this.port, callback);
this.port && this.listen(this.port, callback);
return this;

@@ -62,4 +40,4 @@ },

toString: function() {
if (this.server) {
return '[Server ' + this.constructor.title + ':' + this.server.address().port + ']';
if (this.port) {
return '[Server ' + this.constructor.title + ':' + this.address().port + ']';
} else {

@@ -66,0 +44,0 @@ return '[Server ' + this.constructor.title + ']';

@@ -15,12 +15,12 @@ var Backbone = require('./backbone');

Backbone.View.register = function(app) {
Backbone.View.register = function(server) {
// Add the views if it's not a server-only view.
this.files.forEach(function(filename) {
if (!(/\.server\.bones$/).test(filename) && app.assets &&
app.assets.views.indexOf(filename) < 0) {
app.assets.views.push(filename);
if (!(/\.server\.bones$/).test(filename) && server.assets &&
server.assets.views.indexOf(filename) < 0) {
server.assets.views.push(filename);
}
});
app.views[this.title] = this;
server.views[this.title] = this;
};

@@ -27,0 +27,0 @@

process.env.NODE_ENV = 'test';
var assert = require('assert');
var fs = require('fs');
require('./fixtures/assets');
var demo = require('bones').plugin;
var main = new demo.servers['Main'](demo);
var server = require('./fixture/start').servers.Core;
exports['assets'] = function(beforeExit) {
assert.response(main.server, {
url: '/assets/assets/does-not-exist',
assert.response(server, {
url: '/assets/fixture/does-not-exist',
method: 'GET'

@@ -17,4 +16,4 @@ }, {

assert.response(main.server, {
url: '/assets/assets/foo',
assert.response(server, {
url: '/assets/fixture/foo',
method: 'GET'

@@ -26,1 +25,89 @@ }, {

};
exports['/assets/bones/core.js'] = function() {
assert.response(server, {
url: '/assets/bones/core.js',
method: 'GET'
}, { status: 200 }, function(res) {
assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/client/backbone.js'))) >= 0);
assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/client/utils.js'))) >= 0);
assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/shared/backbone.js'))) >= 0);
assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/shared/utils.js'))) >= 0);
});
};
exports['/assets/bones/core.js'] = function() {
assert.response(server, {
url: '/assets/bones/vendor.js',
method: 'GET'
}, { status: 200 }, function(res) {
assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/assets/jquery.js'))) >= 0);
assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('backbone'))) >= 0);
assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('underscore'))) >= 0);
});
};
exports['/assets/bones/controllers.js'] = function() {
assert.response(server, {
url: '/assets/bones/controllers.js',
method: 'GET'
}, { status: 200 }, function(res) {
assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/node_modules/submodule/controllers/Foo'))) >= 0);
assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/controllers/Page'))) >= 0);
// Correct order.
assert.ok(res.body.indexOf('// ---- start test/fixture/node_modules/submodule/controllers/Foo.bones ----') >= 0);
assert.ok(res.body.indexOf('// ---- start test/fixture/node_modules/submodule/controllers/Foo.bones ----') <
res.body.indexOf('// ---- start test/fixture/controllers/Page.bones ----'));
assert.ok(res.body.indexOf('// ---- end test/fixture/node_modules/submodule/controllers/Foo.bones ----') >= 0);
assert.ok(res.body.indexOf('// ---- end test/fixture/node_modules/submodule/controllers/Foo.bones ----') <
res.body.indexOf('// ---- start test/fixture/controllers/Page.bones ----'));
});
};
exports['/assets/bones/models.js'] = function() {
assert.response(server, {
url: '/assets/bones/models.js',
method: 'GET'
}, { status: 200 }, function(res) {
assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/models/Failure'))) >= 0);
assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/models/Failures'))) >= 0);
assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/models/House'))) >= 0);
assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/models/Houses'))) >= 0);
assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/models/Page'))) >= 0);
// Doesn't include server files.
assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/models/Page.server'))) < 0);
// Correct order.
assert.ok(res.body.indexOf('// ---- start test/fixture/models/Failure.bones ----') >= 0);
assert.ok(res.body.indexOf('// ---- start test/fixture/models/Failure.bones ----') <
res.body.indexOf('// ---- start test/fixture/models/Failures.bones ----'));
assert.ok(res.body.indexOf('// ---- start test/fixture/models/Failures.bones ----') <
res.body.indexOf('// ---- start test/fixture/models/House.bones ----'));
assert.ok(res.body.indexOf('// ---- start test/fixture/models/House.bones ----') <
res.body.indexOf('// ---- start test/fixture/models/Houses.bones ----'));
assert.ok(res.body.indexOf('// ---- start test/fixture/models/Houses.bones ----') <
res.body.indexOf('// ---- start test/fixture/models/Page.bones ----'));
});
};
exports['/assets/bones/views.js'] = function() {
assert.response(server, {
url: '/assets/bones/views.js',
method: 'GET'
}, { status: 200 }, function(res) {
assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/views/Error'))) >= 0);
assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/views/App'))) >= 0);
// Doesn't include server files.
assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/views/App.server'))) < 0);
// Correct order.
assert.ok(res.body.indexOf('// ---- start test/fixture/views/Error.bones ----') >= 0);
assert.ok(res.body.indexOf('// ---- start test/fixture/views/Error.bones ----') <
res.body.indexOf('// ---- start test/fixture/views/App.bones ----'));
});
};
process.env.NODE_ENV = 'test';
var assert = require('assert');
require('./fixtures/collections');
var demo = require('bones').plugin;
var main = new demo.servers['Main'](demo);
var server = require('./fixture/start').servers.Core;
exports['api endpoints'] = function() {
assert.response(main.server, {
assert.response(server, {
url: '/api/House',

@@ -16,2 +14,36 @@ method: 'GET'

});
assert.response(server, {
url: '/api/Failure',
method: 'GET'
}, {
body: 'Internal Server Error',
status: 500
});
assert.response(server, {
url: '/api/Failure',
method: 'GET',
headers: { accept: 'application/json' }
}, {
body: '{"message":"Internal Server Error"}',
status: 500
});
assert.response(server, {
url: '/api/DoesNotExist',
method: 'GET'
}, {
body: 'Not Found',
status: 404
});
assert.response(server, {
url: '/api/DoesNotExist',
method: 'GET',
headers: { accept: 'application/json' }
}, {
body: '{"message":"Not Found"}',
status: 404
});
};
process.env.NODE_ENV = 'test';
var assert = require('assert');
var os = require('os');
require('./fixtures/demo');
var demo = require('bones').plugin;
var main = new demo.servers['Main'](demo);
var server = require('./fixture/start').servers.Core;
exports['routes'] = function(beforeExit) {
assert.response(main.server, {
assert.response(server, {
url: '/submodule-page',

@@ -17,3 +16,3 @@ method: 'GET'

assert.response(main.server, {
assert.response(server, {
url: '/page/foo',

@@ -26,3 +25,3 @@ method: 'GET'

assert.response(main.server, {
assert.response(server, {
url: '/page/bar',

@@ -35,3 +34,3 @@ method: 'GET'

assert.response(main.server, {
assert.response(server, {
url: '/page/special',

@@ -44,3 +43,14 @@ method: 'GET'

assert.response(main.server, {
assert.response(server, {
url: '/?_escaped_fragment_=/page/special',
method: 'GET',
headers: { host: os.hostname() }
}, {
body: '<p>Moved Permanently. Redirecting to <a href="http://' + os.hostname() + '/page/special">http://' + os.hostname() + '/page/special</a></p>',
status: 301
}, function(res) {
assert.equal(res.headers.location, 'http://' + os.hostname() + '/page/special');
});
assert.response(server, {
url: '/page/baz',

@@ -53,3 +63,3 @@ method: 'GET'

assert.response(main.server, {
assert.response(server, {
url: '/page/foo',

@@ -62,3 +72,3 @@ method: 'POST'

assert.response(main.server, {
assert.response(server, {
url: '/page/foo',

@@ -76,32 +86,1 @@ method: 'POST',

};
exports['api endpoints'] = function() {
assert.response(main.server, {
url: '/api/Page/foo',
method: 'GET'
}, {
body: '{"id":"foo","method":"read"}',
status: 200
});
assert.response(main.server, {
url: '/api/page/foo',
method: 'GET'
}, {
body: 'Not Found',
status: 404
});
assert.response(main.server, {
url: '/api/Page/foo',
method: 'PUT',
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
});
};
process.env.NODE_ENV = 'test';
var assert = require('assert');
require('./fixtures/demo');
var demo = require('bones').plugin;
var main = new demo.servers['Main'](demo);
var server = require('./fixture/start').servers.Core;
exports['error 404'] = function(beforeExit) {
assert.response(main.server, {
assert.response(server, {
url: '/does-not-exist',

@@ -17,3 +15,3 @@ method: 'GET'

assert.response(main.server, {
assert.response(server, {
url: '/does-not-exist',

@@ -27,3 +25,3 @@ method: 'GET',

assert.response(main.server, {
assert.response(server, {
url: '/does-not-exist',

@@ -37,3 +35,3 @@ method: 'POST',

assert.response(main.server, {
assert.response(server, {
url: '/does-not-exist',

@@ -51,3 +49,3 @@ method: 'POST',

assert.response(main.server, {
assert.response(server, {
url: '/does-not-exist',

@@ -66,3 +64,3 @@ method: 'POST',

assert.response(main.server, {
assert.response(server, {
url: '/api/DoesNotExit/asdf',

@@ -75,3 +73,3 @@ method: 'GET'

assert.response(main.server, {
assert.response(server, {
url: '/api/DoesNotExit/asdf',

@@ -85,3 +83,3 @@ method: 'GET',

assert.response(main.server, {
assert.response(server, {
url: '/api/Page/asdf',

@@ -94,3 +92,3 @@ method: 'GET'

assert.response(main.server, {
assert.response(server, {
url: '/api/Page/asdf',

@@ -104,3 +102,3 @@ method: 'GET',

assert.response(main.server, {
assert.response(server, {
url: '/api/Page/asdf',

@@ -118,3 +116,3 @@ method: 'PUT',

assert.response(main.server, {
assert.response(server, {
url: '/api/Page/asdf',

@@ -133,3 +131,3 @@ method: 'PUT',

assert.response(main.server, {
assert.response(server, {
url: '/api/Page/asdf',

@@ -147,3 +145,3 @@ method: 'DELETE',

assert.response(main.server, {
assert.response(server, {
url: '/api/Page/asdf',

@@ -150,0 +148,0 @@ method: 'DELETE',

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc