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

nodecaf

Package Overview
Dependencies
Maintainers
1
Versions
80
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nodecaf - npm Package Compare versions

Comparing version 0.10.0-rc1 to 0.10.0-rc2

4

lib/handle.js

@@ -45,3 +45,3 @@

let input = {
...app._global, conf: app.conf, req, res,
...app.global, conf: app.conf, req, res,
flash: req.flash, log: app.log, headers: req.headers,

@@ -85,3 +85,3 @@ query: req.query, params: req.params, body: req.body

if(app.shouldParseBody && req.hasBody)
if(app._shouldParseBody && req.hasBody)
req.body = await parseBody(req);

@@ -88,0 +88,0 @@

@@ -99,3 +99,3 @@ const util = require('util');

return { level, type, ...data, pid, msg, time };
return { level, type, msg, ...data, pid, time };
}

@@ -108,3 +108,3 @@

let entry = getEntry(level, ...args);
entry.app = this.name;
entry.app = this._name;

@@ -111,0 +111,0 @@ let conf = this.conf.log;

@@ -5,2 +5,3 @@ const

http = require('http'),
assert = require('assert'),
https = require('https'),

@@ -31,12 +32,31 @@ compression = require('compression'),

constructor(conf){
constructor(opts = {}){
assert(typeof opts == 'object',
new TypeError('Options argument must be an object'));
this._api = opts.api || noop;
this._startup = opts.startup || noop;
this._shutdown = opts.shutdown || noop;
assert(typeof this._api == 'function',
new TypeError('API builder must be a function'));
assert(typeof this._startup == 'function',
new TypeError('Startup handler must be a function'));
assert(typeof this._shutdown == 'function',
new TypeError('Shutdown handler must be a function'));
// TODO sha1 of host+time+name to identify app
let { name, version } = findPkgInfo();
this._global = {};
this._startup = this._shutdown = this._api = noop;
this._confort = new Confort();
this._router = new Router(this);
this._wsRouter = new WSRouter(this);
this._name = name;
this._version = version;
this._shouldParseBody = opts.shouldParseBody || typeof opts.shouldParseBody == 'undefined';
this._alwaysRebuildAPI = opts.alwaysRebuildAPI || false;
// TODO sha1 of host+time+name to identify app
// Generate HTTP verb shortcut route methods

@@ -51,11 +71,11 @@ this._routeProxy = METHODS.reduce( (o, m) =>

this.global = {};
this.conf = this._confort.object;
this.shouldParseBody = true;
this.cookieSecret = '';
this.name = name;
this.version = version;
this.running = false;
this.stopped = Promise.resolve(true);
this.setup(conf);
this.setup(opts.conf);
if(!this._alwaysRebuildAPI)
this._api(this._routeProxy);
}

@@ -79,33 +99,4 @@

this.conf.port = this.conf.port || (this._ssl ? 443 : 80);
if(this.alwaysRebuildAPI)
this._api(this._routeProxy);
}
startup(handler){
if(typeof handler != 'function')
throw new TypeError('Startup handler must be a function');
this._startup = handler;
}
shutdown(handler){
if(typeof handler != 'function')
throw new TypeError('Shutdown handler must be a function');
this._shutdown = handler;
}
api(builder){
if(typeof builder != 'function')
throw new TypeError('API Builder must be a function');
this._api = builder;
if(!this.alwaysRebuildAPI)
this._api(this._routeProxy);
}
global(object){
this._global = object;
}
// TODO maybe move api build to constructor
async start(){

@@ -123,7 +114,9 @@ if(this.running)

if(this.alwaysRebuildAPI)
if(this._alwaysRebuildAPI){
this._router.clear();
this._api(this._routeProxy);
}
if(!this._startup.noop)
this.log.debug({ type: 'server' }, 'Starting up %s...', this.name);
this.log.debug({ type: 'server' }, 'Starting up %s...', this._name);

@@ -142,3 +135,3 @@ await this._startup(this);

this.log.info({ type: 'server' },
'%s v%s is ready on port %s', this.name, this.version, this.conf.port);
'%s v%s is ready on port %s', this._name, this._version, this.conf.port);

@@ -194,3 +187,3 @@ started(true);

- 4xx errors won't spit default body anymore
- expose() to global()
- expose() to app.global
- PID 1 omitted from log entries

@@ -205,2 +198,7 @@ - Added res.type()

- removed user error handler (TMP)
- app.api() to new App(api, ...)
- startup and shutdown
- moved cookieSecret to conf
- constructor argument to OPTS spec
- remove programmatic name and version
*/
const querystring = require('querystring');
const contentType = require('content-type');

@@ -4,0 +3,0 @@ const getRawBody = require('raw-body');

@@ -20,12 +20,2 @@

function error(status, message, ...args){
if(typeof status !== 'number')
return handleError(status, this.input);
message = format(message, ...args);
this.status(status).end(message);
this.stackAborted = true;
return getHTTPError(status, message);
}
function assert(status, cond, message, ...args){

@@ -40,3 +30,3 @@ if(!cond)

set(k, v){
this.setHeader(k.toLowerCase(), v);
this.setHeader(k, v);
return this;

@@ -51,3 +41,3 @@ },

type(ct){
this.set('content-type', SHORT_CONTENT_TYPES[ct] || ct);
this.set('Content-Type', SHORT_CONTENT_TYPES[ct] || ct);
return this;

@@ -68,4 +58,18 @@ },

error
error(status, message, ...args){
if(typeof status !== 'number')
return handleError(status, this.input);
if(typeof message == 'string')
message = format(message, ...args);
else if(typeof message != 'undefined' && message !== null){
message = JSON.stringify(message);
this.type('json');
}
this.status(status).end(message);
this.stackAborted = true;
return getHTTPError(status, message);
}
};

@@ -72,0 +76,0 @@

@@ -14,6 +14,10 @@ const querystring = require('querystring');

constructor(app){
this.app = app;
this.clear();
}
clear(){
this.routes = {};
this.static = {};
this.dynamic = {};
this.app = app;
}

@@ -27,3 +31,3 @@

if(route in this.routes)
if(!this.app._alwaysRebuildAPI && route in this.routes)
throw new Error('Route for \'' + route + '\' is already defined');

@@ -30,0 +34,0 @@

{
"name": "nodecaf",
"version": "0.10.0-rc1",
"version": "0.10.0-rc2",
"description": "Nodecaf is a framework on top of Express for building RESTful services in a quick and convenient manner.",

@@ -5,0 +5,0 @@ "main": "lib/main.js",

@@ -17,7 +17,75 @@ const assert = require('assert');

it('Should fail when Options is not an object', () => {
assert.throws( () => new Nodecaf(false), /Options/ );
});
it('Should fail when API builder is not a function', () => {
assert.throws( () => new Nodecaf({ api: 3 }), /API/ );
});
it('Should execute the API Builder passing the method funcs', done => {
new Nodecaf({
api(funcs){
assert.strictEqual(typeof funcs, 'object');
done();
}
});
});
it('Should allow registering routes', async () => {
let app = new Nodecaf({
api({ post, del, patch }){
post('/foo', ({res}) => res.status(500).end() );
assert.strictEqual(typeof del, 'function');
assert.strictEqual(typeof patch, 'function');
}
});
await app.start();
let { assert: { status } } = await base.post('foo');
status.is(500);
await app.stop();
});
it('Should preserve flash vars across handlers in a route', async function(){
this.timeout(4000);
let app = new Nodecaf({
api({ get }){
get('/bar',
({ flash, next }) => { flash.foo = 'bar'; next(); },
({ flash, res }) => {
res.type('text/plain');
res.end(flash.foo);
});
}
});
await app.start();
let { assert: { body } } = await base.get('bar');
body.exactly('bar');
await app.stop();
});
it('Should NOT bulid the API right away if setup so [opts.alwaysRebuildAPI]', () => {
let app = new Nodecaf({
alwaysRebuildAPI: true,
api({ get }){
get('/foobar', ({ res }) => res.end());
}
});
assert(!app._router.routes['/foobar']);
});
it('Should store any settings sent', () => {
let app = new Nodecaf({ key: 'value' });
let app = new Nodecaf({ conf: { key: 'value' } });
assert.strictEqual(app.conf.key, 'value');
});
it('Should fail when startup handler is not a function', () => {
assert.throws( () => new Nodecaf({ startup: 3 }), /function/ );
});
it('Should fail when shutdown handler is not a function', () => {
assert.throws( () => new Nodecaf({ shutdown: 3 }), /function/ );
});
});

@@ -43,3 +111,3 @@

it('Should start the http server on port sent', async () => {
let app = new Nodecaf({ port: 8765 });
let app = new Nodecaf({ conf: { port: 8765 } });
await app.start();

@@ -52,5 +120,4 @@ let { assert } = await get('http://127.0.0.1:8765/');

it('Should trigger before start event', async () => {
let app = new Nodecaf();
let done = false;
app.startup(() => done = true);
let app = new Nodecaf({ startup: () => done = true });
await app.start();

@@ -61,5 +128,4 @@ assert(done);

it('Should rebuild the api when setup [this.alwaysRebuildAPI]', async () => {
let app = new Nodecaf();
app.alwaysRebuildAPI = true;
it('Should rebuild the api when setup so [this.alwaysRebuildAPI]', async () => {
let app = new Nodecaf({ alwaysRebuildAPI: true });
await app.start();

@@ -80,96 +146,2 @@ let { assert } = await base.get('');

describe('#startup', () => {
it('Should fail when startup handler is not a function', () => {
let app = new Nodecaf();
assert.throws( () => app.startup(), /function/ );
});
});
describe('#shutdown', () => {
it('Should fail when shutdown handler is not a function', () => {
let app = new Nodecaf();
assert.throws( () => app.shutdown(), /function/ );
});
});
describe('#api', () => {
it('Should fail when builder is not a function', () => {
let app = new Nodecaf();
assert.throws( () => app.api(), /function/ );
});
it('Should execute the callback passing the method funcs', done => {
let app = new Nodecaf();
app.api(function(funcs){
assert.strictEqual(typeof funcs, 'object');
done();
});
});
it('Should allow registering routes', async () => {
let app = new Nodecaf();
app.api(function({ post, del, patch }){
post('/foo', ({res}) => res.status(500).end() );
assert.strictEqual(typeof del, 'function');
assert.strictEqual(typeof patch, 'function');
});
await app.start();
let { assert: { status } } = await base.post('foo');
status.is(500);
await app.stop();
});
it('Should preserve flash vars across handlers in a route', async function(){
this.timeout(4000);
let app = new Nodecaf();
app.api(function({ get }){
get('/bar',
({ flash, next }) => { flash.foo = 'bar'; next(); },
({ flash, res }) => {
res.type('text/plain');
res.end(flash.foo);
});
});
await app.start();
let { assert: { body } } = await base.get('bar');
body.exactly('bar');
await app.stop();
});
it('Should NOT bulid the API right away if setup [this.alwaysRebuildAPI]', async () => {
let app = new Nodecaf();
app.alwaysRebuildAPI = true;
app.api(function({ get }){
get('/foobar', ({ res }) => res.end());
});
app.alwaysRebuildAPI = false;
await app.start();
let { assert } = await base.get('foobar');
assert.status.is(404);
await app.stop();
});
});
describe('#global', () => {
it('Should store data to be accessible to all handlers', async () => {
let app = new Nodecaf();
app.global({ foo: 'foobar' });
app.api(function({ post }){
post('/bar', ({ foo, res }) => res.text(foo));
});
await app.start();
let { assert: { body } } = await base.post('bar');
body.exactly('foobar');
await app.stop();
});
});
describe('#stop', () => {

@@ -186,5 +158,4 @@

it('Should trigger after stop event', async () => {
let app = new Nodecaf();
let done = false;
app.shutdown(() => done = true);
let app = new Nodecaf({ shutdown: () => done = true });
await app.start();

@@ -229,3 +200,3 @@ await app.stop();

it('Should apply settings on top of existing one', () => {
let app = new Nodecaf({ key: 'value' });
let app = new Nodecaf({ conf: { key: 'value' } });
app.setup({ key: 'value2', key2: 'value' });

@@ -237,3 +208,3 @@ assert.strictEqual(app.conf.key, 'value2');

it('Should load form file when path is sent', () => {
let app = new Nodecaf({ key: 'valueOld' });
let app = new Nodecaf({ conf: { key: 'valueOld' } });
app.setup('test/res/conf.toml');

@@ -243,16 +214,2 @@ assert.strictEqual(app.conf.key, 'value');

it('Should rebuild the api when setup [this.alwaysRebuildAPI]', async () => {
let app = new Nodecaf();
app.alwaysRebuildAPI = true;
app._api = function({ get }){
get('/foobar', ({ res }) => res.end());
};
app.setup();
app.alwaysRebuildAPI = false;
await app.start();
let { assert: { status} } = await base.get('foobar');
status.is(200);
await app.stop();
});
});

@@ -265,8 +222,9 @@

it('Should fail when receiving invalid route handlers', () => {
let app = new Nodecaf();
app.api(function({ post }){
assert.throws(() => post('/foobar', undefined), TypeError);
assert.throws(() => post('/foobar'), /empty/);
post('/foobaz', Function.prototype);
assert.throws(() => post('/foobaz', Function.prototype), /already/);
new Nodecaf({
api({ post }){
assert.throws(() => post('/foobar', undefined), TypeError);
assert.throws(() => post('/foobar'), /empty/);
post('/foobaz', Function.prototype);
assert.throws(() => post('/foobaz', Function.prototype), /already/);
}
});

@@ -276,11 +234,12 @@ });

it('Should pass all the required args to handler', async () => {
let app = new Nodecaf();
app.api(function({ get }){
get('/foo', function(obj){
assert(obj.res && obj.req && obj.next && !obj.body
&& obj.params && obj.query && obj.flash
&& obj.conf && obj.log);
assert(this instanceof Nodecaf);
obj.res.end();
});
let app = new Nodecaf({
api({ get }){
get('/foo', function(obj){
assert(obj.res && obj.req && obj.next && !obj.body
&& obj.params && obj.query && obj.flash
&& obj.conf && obj.log);
assert(this instanceof Nodecaf);
obj.res.end();
});
}
});

@@ -293,9 +252,10 @@ await app.start();

it('Should pass all present parameters to handler', async () => {
let app = new Nodecaf();
app.api(function({ get }){
get('/fo/:o', Function.prototype);
get('/foo/:bar', function({ params, res }){
res.badRequest(params.bar !== 'test');
res.end();
});
let app = new Nodecaf({
api({ get }){
get('/fo/:o', Function.prototype);
get('/foo/:bar', function({ params, res }){
res.badRequest(params.bar !== 'test');
res.end();
});
}
});

@@ -308,9 +268,10 @@ await app.start();

it('Should parse URL query string', async () => {
let app = new Nodecaf();
app.api(function({ post }){
post('/foobar', ({ query, res, next }) => {
assert.strictEqual(query.foo, 'bar');
res.end();
next();
});
let app = new Nodecaf({
api({ post }){
post('/foobar', ({ query, res, next }) => {
assert.strictEqual(query.foo, 'bar');
res.end();
next();
});
}
});

@@ -325,3 +286,2 @@ await app.start();

let app = new Nodecaf();
app.api(function(){ });
await app.start();

@@ -334,7 +294,8 @@ let { status } = await base.post('foobar');

it('Should parse object as json response [res.json()]', async () => {
let app = new Nodecaf();
app.api(function({ get }){
get('/foo', function({ res }){
res.json('{"hey":"ho"}');
});
let app = new Nodecaf({
api({ get }){
get('/foo', function({ res }){
res.json('{"hey":"ho"}');
});
}
});

@@ -354,9 +315,10 @@ await app.start();

const FormData = require('form-data');
let app = new Nodecaf();
app.api(function({ post }){
post('/bar', ({ body, res }) => {
assert(body.foobar.size > 10);
res.set('X-Test', body.foobar.name);
res.end();
});
let app = new Nodecaf({
api({ post }){
post('/bar', ({ body, res }) => {
assert(body.foobar.size > 10);
res.set('X-Test', body.foobar.name);
res.end();
});
}
});

@@ -379,8 +341,9 @@ await app.start();

it('Should parse JSON request body payloads', async () => {
let app = new Nodecaf();
app.api(function({ post }){
post('/foobar', ({ body, res }) => {
assert.strictEqual(body.foo, 'bar');
res.end();
});
let app = new Nodecaf({
api({ post }){
post('/foobar', ({ body, res }) => {
assert.strictEqual(body.foo, 'bar');
res.end();
});
}
});

@@ -396,8 +359,9 @@ await app.start();

it('Should parse Raw request body payloads', async () => {
let app = new Nodecaf();
app.api(function({ post }){
post('/foobar', ({ body, res }) => {
assert.strictEqual(body, '{"foo":"bar"}');
res.end();
});
let app = new Nodecaf({
api({ post }){
post('/foobar', ({ body, res }) => {
assert.strictEqual(body, '{"foo":"bar"}');
res.end();
});
}
});

@@ -415,8 +379,9 @@ await app.start();

it('Should parse URLEncoded request body payloads', async () => {
let app = new Nodecaf();
app.api(function({ post }){
post('/foobar', ({ body, res }) => {
assert.strictEqual(body.foo, 'bar');
res.end();
});
let app = new Nodecaf({
api({ post }){
post('/foobar', ({ body, res }) => {
assert.strictEqual(body.foo, 'bar');
res.end();
});
}
});

@@ -434,9 +399,11 @@ await app.start();

it('Should not parse request body when setup so', async () => {
let app = new Nodecaf();
app.shouldParseBody = false;
app.api(function({ post }){
post('/foobar', ({ body, res }) => {
assert(!body);
res.end();
});
let app = new Nodecaf({
shouldParseBody: false,
api({ post }){
post('/foobar', ({ body, res }) => {
console.log(body);
assert(!body);
res.end();
});
}
});

@@ -455,34 +422,17 @@ await app.start();

describe('CORS', () => {
it('Should send permissive CORS headers when setup so [cors]', async () => {
let app = new Nodecaf({ cors: true });
app.api(function({ get }){
get('/foobar', ({ res }) => res.end() );
});
await app.start();
const { assert } = await base.get('foobar', { 'Origin': 'http://outsider.com' });
assert.status.is(200);
assert.headers.match('access-control-allow-origin', '*');
const { assert: { headers } } = await base.options('foobar', { 'Origin': 'http://outsider.com' });
headers.match('access-control-allow-methods', 'GET,HEAD,PUT,PATCH,POST,DELETE');
await app.stop();
});
});
describe('Assertions', () => {
it('Should throw when condition evaluates to true', async () => {
let app = new Nodecaf();
app.api(function({ get }){
get('/foo', function({ res }){
assert.throws( () => res.badRequest(true) );
assert.throws( () => res.unauthorized(true) );
assert.throws( () => res.forbidden(true) );
assert.throws( () => res.notFound(true) );
assert.throws( () => res.conflict(true) );
assert.throws( () => res.gone(true) );
res.end();
});
let app = new Nodecaf({
api({ get }){
get('/foo', function({ res }){
assert.throws( () => res.badRequest(true) );
assert.throws( () => res.unauthorized(true) );
assert.throws( () => res.forbidden(true) );
assert.throws( () => res.notFound(true) );
assert.throws( () => res.conflict(true) );
assert.throws( () => res.gone(true) );
res.end();
});
}
});

@@ -495,13 +445,14 @@ await app.start();

it('Should do nothing when condition evaluates to false', async () => {
let app = new Nodecaf();
app.api(function({ get }){
get('/foo', function({ res }){
assert.doesNotThrow( () => res.badRequest(false) );
assert.doesNotThrow( () => res.unauthorized(false) );
assert.doesNotThrow( () => res.forbidden(false) );
assert.doesNotThrow( () => res.notFound(false) );
assert.doesNotThrow( () => res.conflict(false) );
assert.doesNotThrow( () => res.gone(false) );
res.end();
});
let app = new Nodecaf({
api({ get }){
get('/foo', function({ res }){
assert.doesNotThrow( () => res.badRequest(false) );
assert.doesNotThrow( () => res.unauthorized(false) );
assert.doesNotThrow( () => res.forbidden(false) );
assert.doesNotThrow( () => res.notFound(false) );
assert.doesNotThrow( () => res.conflict(false) );
assert.doesNotThrow( () => res.gone(false) );
res.end();
});
}
});

@@ -519,7 +470,8 @@ await app.start();

it('Should handle Error thrown sync on the route', async () => {
let app = new Nodecaf();
app.api(function({ post }){
post('/unknown', () => {
throw new Error('othererr');
});
let app = new Nodecaf({
api({ post }){
post('/unknown', () => {
throw new Error('othererr');
});
}
});

@@ -533,13 +485,14 @@ await app.start();

it('Should handle Error injected sync on the route', async () => {
let app = new Nodecaf();
app.api(function({ post }){
post('/known', ({ res }) => {
throw res.error(404);
});
post('/unknown', ({ res }) => {
throw res.error(new Error('errfoobar'));
});
post('/serverfault', ({ res }) => {
throw res.error(501);
});
let app = new Nodecaf({
api({ post }){
post('/known', ({ res }) => {
throw res.error(404);
});
post('/unknown', ({ res }) => {
throw res.error(new Error('errfoobar'));
});
post('/serverfault', ({ res }) => {
throw res.error(501, { test: 'foo' });
});
}
});

@@ -557,7 +510,8 @@ await app.start();

it('Should handle Rejection on async route', async () => {
let app = new Nodecaf();
app.api(function({ post }){
post('/async', async () => {
await new Promise((y, n) => n());
});
let app = new Nodecaf({
api({ post }){
post('/async', async () => {
await new Promise((y, n) => n());
});
}
});

@@ -571,17 +525,18 @@ await app.start();

it('Should handle Error injected ASYNC on the route', async () => {
let app = new Nodecaf();
app.api(function({ post }){
post('/known', ({ res }) => {
fs.readdir('.', function(){
res.error(404, 'errfoobar');
let app = new Nodecaf({
api({ post }){
post('/known', ({ res }) => {
fs.readdir('.', function(){
res.error(404, 'errfoobar');
});
});
});
post('/unknown', async ({ res }) => {
await fs.readdir('.', function(){
res.error(new Error('errfoobar'));
post('/unknown', async ({ res }) => {
await fs.readdir('.', function(){
res.error(new Error('errfoobar'));
});
});
});
post('/unknown/object', () => {
throw 'resterr';
});
post('/unknown/object', () => {
throw 'resterr';
});
}
});

@@ -658,9 +613,10 @@ await app.start();

it('Should log given event', async () => {
let app = new Nodecaf();
app.api(function({ post }){
post('/foo', ({ log, res }) => {
let entry = log.info('foobar');
assert.strictEqual(entry.msg, 'foobar');
res.end();
});
let app = new Nodecaf({
api({ post }){
post('/foo', ({ log, res }) => {
let entry = log.info('foobar');
assert.strictEqual(entry.msg, 'foobar');
res.end();
});
}
});

@@ -684,32 +640,2 @@ await app.start();

describe('HTTPS', () => {
const https = require('https');
it('Should start HTTPS server when specified', async function(){
let app = new Nodecaf({
ssl: {
key: './test/res/key.pem',
cert: './test/res/cert.pem'
}
});
app.api(function({ get }){
get('/foo', ({ res }) => res.end('bar') );
});
await app.start();
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0;
let res = await new Promise( resolve =>
https.get('https://localhost/foo', resolve) );
await new Promise( resolve =>
res.on('data', chunk => {
assert.strictEqual(chunk.toString(), 'bar');
resolve();
}) );
await app.stop();
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 1;
});
});
describe('Regression', () => {

@@ -719,7 +645,8 @@ const WebSocket = require('ws');

it('Should handle errors even when error event has no listeners', async () => {
let app = new Nodecaf();
app.api(function({ post }){
post('/bar', () => {
throw new Error('errfoobar');
});
let app = new Nodecaf({
api({ post }){
post('/bar', () => {
throw new Error('errfoobar');
});
}
});

@@ -788,16 +715,17 @@ await app.start();

let count = 0;
let app = new Nodecaf();
app.api(({ ws }) => {
ws('/foo', {
connect: () => count++,
async message({ message }){
assert.strictEqual('foobar', message);
await app.stop();
count++;
},
close(){
assert.strictEqual(count, 2);
done();
}
});
let app = new Nodecaf({
api({ ws }){
ws('/foo', {
connect: () => count++,
async message({ message }){
assert.strictEqual('foobar', message);
await app.stop();
count++;
},
close(){
assert.strictEqual(count, 2);
done();
}
});
}
});

@@ -830,17 +758,18 @@ (async function(){

let count = 0;
let app = new Nodecaf();
app.api(({ ws }) => {
ws('/foo', {
connect: () => count++,
error: Function.prototype,
async message({ message }){
assert.strictEqual('foobar', message);
await app.stop();
count++;
},
close(){
assert.strictEqual(count, 2);
done();
}
});
let app = new Nodecaf({
api({ ws }){
ws('/foo', {
connect: () => count++,
error: Function.prototype,
async message({ message }){
assert.strictEqual('foobar', message);
await app.stop();
count++;
},
close(){
assert.strictEqual(count, 2);
done();
}
});
}
});

@@ -858,4 +787,5 @@ (async function(){

it('Should reject connection to path that is not setup', function(done){
let app = new Nodecaf();
app.api(({ ws }) => ws('/foo', {}));
let app = new Nodecaf({
api: ({ ws }) => ws('/foo', {})
});
(async function(){

@@ -898,8 +828,70 @@ await app.start();

describe('Other Features', function(){
const https = require('https');
it('Should delay server initialization by given milliseconds [delay]', async function(){
let app = new Nodecaf({ delay: 1500 });
app.api(function({ get }){
get('/foobar', ({ res }) => res.end());
it('Should start HTTPS server when specified', async function(){
let app = new Nodecaf({
conf: {
ssl: {
key: './test/res/key.pem',
cert: './test/res/cert.pem'
}
},
api({ get }){
get('/foo', ({ res }) => res.end('bar') );
}
});
await app.start();
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0;
let res = await new Promise( resolve =>
https.get('https://localhost/foo', resolve) );
await new Promise( resolve =>
res.on('data', chunk => {
assert.strictEqual(chunk.toString(), 'bar');
resolve();
}) );
await app.stop();
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 1;
});
it('Should send permissive CORS headers when setup so [cors]', async () => {
let app = new Nodecaf({
conf: { cors: true },
api({ get }){
get('/foobar', ({ res }) => res.end() );
}
});
await app.start();
const { assert } = await base.get('foobar', { 'Origin': 'http://outsider.com' });
assert.status.is(200);
assert.headers.match('access-control-allow-origin', '*');
const { assert: { headers } } = await base.options('foobar', { 'Origin': 'http://outsider.com' });
headers.match('access-control-allow-methods', 'GET,HEAD,PUT,PATCH,POST,DELETE');
await app.stop();
});
it('Should store data to be accessible to all handlers [app.global]', async () => {
let app = new Nodecaf({
api({ post }){
post('/bar', ({ foo, res }) => {
res.text(foo);
})
}
});
app.global.foo = 'foobar';
await app.start();
let { assert: { body } } = await base.post('bar');
body.exactly('foobar');
await app.stop();
});
it('Should delay server initialization by given milliseconds [conf.delay]', async function(){
let app = new Nodecaf({
conf: { delay: 1500 },
api({ get }){
get('/foobar', ({ res }) => res.end());
}
});
let ps = app.start();

@@ -906,0 +898,0 @@ await new Promise(done => setTimeout(done, 400));

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