mirror of
https://github.com/abrendan/MicDropMessages.git
synced 2025-08-25 14:02:03 +02:00
Initial commit
This commit is contained in:
7
node_modules/server/router/del.js
generated
vendored
Normal file
7
node_modules/server/router/del.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// Import the generic REST handler
|
||||
const generic = require('./generic');
|
||||
|
||||
// Defined the actual method
|
||||
module.exports = (...middle) => {
|
||||
return generic('DELETE', ...middle);
|
||||
};
|
25
node_modules/server/router/error.js
generated
vendored
Normal file
25
node_modules/server/router/error.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
const join = require('../src/join');
|
||||
const parse = require('./parse');
|
||||
const params = require('./path-to-regexp-wrap')();
|
||||
|
||||
module.exports = (...all) => {
|
||||
// Extracted or otherwise it'd shift once per call; also more performant
|
||||
const { path, middle } = parse(all);
|
||||
const match = params(path || '');
|
||||
|
||||
const generic = () => {};
|
||||
generic.error = async ctx => {
|
||||
|
||||
// Only do this if the correct path
|
||||
ctx.error.code = ctx.error.code || '';
|
||||
ctx.error.params = match(ctx.error.code);
|
||||
|
||||
// Add an extra-allowing initial matching
|
||||
if (!ctx.error.params && ctx.error.code.slice(0, path.length) !== path) return;
|
||||
|
||||
const ret = await middle[0](ctx);
|
||||
delete ctx.error;
|
||||
return ret;
|
||||
};
|
||||
return generic;
|
||||
};
|
8
node_modules/server/router/errors.js
generated
vendored
Normal file
8
node_modules/server/router/errors.js
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
// YOU MIGHT BE LOOKING FOR 'error.js' (without the "s")
|
||||
|
||||
const error = require('../error')('/server/test/');
|
||||
|
||||
error.router = 'This is a demo error';
|
||||
error.simplerouter = ({ text }) => `Simple message: ${text}`;
|
||||
|
||||
module.exports = error;
|
31
node_modules/server/router/generic.js
generated
vendored
Normal file
31
node_modules/server/router/generic.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
const join = require('../src/join');
|
||||
const parse = require('./parse');
|
||||
const params = require('./path-to-regexp-wrap')();
|
||||
|
||||
// Generic request handler
|
||||
module.exports = (method, ...all) => {
|
||||
|
||||
// Extracted or otherwise it'd shift once per call; also more performant
|
||||
const { path, middle } = parse(all);
|
||||
|
||||
const match = params(path || '');
|
||||
|
||||
return async ctx => {
|
||||
|
||||
// A route should be solved only once per request
|
||||
if (ctx.req.solved) return;
|
||||
|
||||
// Only for the correct method
|
||||
if (method !== ctx.req.method) return;
|
||||
|
||||
// Only do this if the correct path
|
||||
ctx.req.params = match(ctx.req.path);
|
||||
if (!ctx.req.params) return;
|
||||
ctx.params = ctx.req.params;
|
||||
|
||||
// Perform this promise chain
|
||||
await join(middle)(ctx);
|
||||
|
||||
ctx.req.solved = true;
|
||||
};
|
||||
};
|
7
node_modules/server/router/get.js
generated
vendored
Normal file
7
node_modules/server/router/get.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// Import the generic REST handler
|
||||
const generic = require('./generic');
|
||||
|
||||
// Defined the actual method
|
||||
module.exports = (...middle) => {
|
||||
return generic('GET', ...middle);
|
||||
};
|
21
node_modules/server/router/index.js
generated
vendored
Normal file
21
node_modules/server/router/index.js
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// Define the router methods that are available to use as middleware
|
||||
// Each of these is available through:
|
||||
// const { get } = require('server').router;
|
||||
// const { get } = require('server/router');
|
||||
// const get = require('server/router/get');
|
||||
|
||||
// Perform the routing required
|
||||
module.exports = {
|
||||
|
||||
// REST
|
||||
get : require('./get'),
|
||||
post : require('./post'),
|
||||
put : require('./put'),
|
||||
del : require('./del'),
|
||||
|
||||
// Special cases
|
||||
sub : require('./sub'),
|
||||
error : require('./error'),
|
||||
join : require('../src/join'),
|
||||
socket : require('../plugins/socket').router
|
||||
};
|
219
node_modules/server/router/integration.test.js
generated
vendored
Normal file
219
node_modules/server/router/integration.test.js
generated
vendored
Normal file
@@ -0,0 +1,219 @@
|
||||
// Integration - test the router within the whole server functionality
|
||||
const server = require('server');
|
||||
const run = require('server/test/run');
|
||||
const { get, post, put, del, sub, error } = server.router;
|
||||
|
||||
|
||||
|
||||
// Mock middlewares and data:
|
||||
const question = { answer: 42 };
|
||||
const mirror = ctx => ctx.data;
|
||||
const hello = () => 'Hello 世界';
|
||||
const throwError = () => {
|
||||
const err = new Error('MockError');
|
||||
err.code = 'test';
|
||||
throw err;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// CSRF validation is checked in another place; disable it for these tests
|
||||
run.options = { security: false };
|
||||
|
||||
describe('Basic router types', () => {
|
||||
it('can do a GET request', async () => {
|
||||
const mid = get('/', hello);
|
||||
|
||||
const res = await run(mid).get('/');
|
||||
expect(res).toMatchObject({ status: 200, body: 'Hello 世界' });
|
||||
});
|
||||
|
||||
it('can do a POST request', async () => {
|
||||
const mid = post('/', ctx => ctx.data);
|
||||
|
||||
const res = await run(mid).post('/', { body: question });
|
||||
expect(res.body).toEqual({ answer: 42 });
|
||||
expect(res.status).toBe(200);
|
||||
});
|
||||
|
||||
it('can do a PUT request', async () => {
|
||||
const mid = post('/', ctx => ctx.data);
|
||||
|
||||
const res = await run(mid).post('/', { body: question });
|
||||
expect(res.body).toEqual({ answer: 42 });
|
||||
expect(res.status).toBe(200);
|
||||
});
|
||||
|
||||
it('can do a DELETE request', async () => {
|
||||
const mid = del('/', ctx => 'Hello 世界');
|
||||
|
||||
const res = await run(mid).del('/', { body: question });
|
||||
expect(res.body).toEqual('Hello 世界');
|
||||
expect(res.status).toBe(200);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('Generic paths', () => {
|
||||
it('can do a GET request', async () => {
|
||||
const mid = get(hello);
|
||||
|
||||
const res = await run(mid).get('/');
|
||||
expect(res).toMatchObject({ status: 200, body: 'Hello 世界' });
|
||||
});
|
||||
|
||||
it('can do a GET request', async () => {
|
||||
const mid = get('*', hello);
|
||||
|
||||
const res = await run(mid).get('/');
|
||||
expect(res).toMatchObject({ status: 200, body: 'Hello 世界' });
|
||||
});
|
||||
|
||||
// it('can do a POST request', async () => {
|
||||
// const mid = post('/', ctx => ctx.data);
|
||||
//
|
||||
// const res = await run(mid).post('/', { body: question });
|
||||
// expect(res.body).toEqual({ answer: 42 });
|
||||
// expect(res.status).toBe(200);
|
||||
// });
|
||||
//
|
||||
// it('can do a PUT request', async () => {
|
||||
// const mid = post('/', ctx => ctx.data);
|
||||
//
|
||||
// const res = await run(mid).post('/', { body: question });
|
||||
// expect(res.body).toEqual({ answer: 42 });
|
||||
// expect(res.status).toBe(200);
|
||||
// });
|
||||
//
|
||||
// it('can do a DELETE request', async () => {
|
||||
// const mid = del('/', ctx => 'Hello 世界');
|
||||
//
|
||||
// const res = await run(mid).del('/', { body: question });
|
||||
// expect(res.body).toEqual('Hello 世界');
|
||||
// expect(res.status).toBe(200);
|
||||
// });
|
||||
});
|
||||
|
||||
|
||||
describe('Subdomain router', () => {
|
||||
it('can do a request to a subdomain', async () => {
|
||||
const mid = sub('api', get('/', hello));
|
||||
|
||||
const res = await run((ctx) => {
|
||||
ctx.headers.host = 'api.example.com';
|
||||
}, mid).get('/');
|
||||
expect(res).toMatchObject({ status: 200, body: 'Hello 世界' });
|
||||
});
|
||||
|
||||
it('can handle regex', async () => {
|
||||
const mid = sub(/^api$/, get('/', hello));
|
||||
|
||||
const res = await run((ctx) => {
|
||||
ctx.headers.host = 'api.example.com';
|
||||
}, mid).get('/');
|
||||
expect(res).toMatchObject({ status: 200, body: 'Hello 世界' });
|
||||
});
|
||||
|
||||
it('does not do partial match', async () => {
|
||||
const mid = sub(/^api$/, get('/', hello));
|
||||
|
||||
const res = await run((ctx) => {
|
||||
ctx.headers.host = 'bla.api.example.com';
|
||||
}, mid, () => 'Did not match').get('/');
|
||||
expect(res).toMatchObject({ status: 200, body: 'Did not match' });
|
||||
});
|
||||
|
||||
it('can do a request to a multi-level subdomain', async () => {
|
||||
const mid = sub('api.local', get('/', hello));
|
||||
|
||||
const res = await run((ctx) => {
|
||||
ctx.headers.host = 'api.local.example.com';
|
||||
}, mid).get('/');
|
||||
expect(res).toMatchObject({ status: 200, body: 'Hello 世界' });
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('Ends where it should end', () => {
|
||||
|
||||
it('uses the matching method', async () => {
|
||||
const mid = [
|
||||
post('/', throwError),
|
||||
put('/', throwError),
|
||||
del('/', throwError),
|
||||
get('/', hello)
|
||||
];
|
||||
|
||||
const res = await run(mid).get('/');
|
||||
expect(res).toMatchObject({ status: 200, body: 'Hello 世界' });
|
||||
});
|
||||
|
||||
|
||||
it('uses the matching path', async () => {
|
||||
const mid = [
|
||||
get('/bla', throwError),
|
||||
get('/:id', throwError),
|
||||
get('/', hello)
|
||||
];
|
||||
|
||||
const res = await run(mid).get('/');
|
||||
expect(res).toMatchObject({ status: 200, body: 'Hello 世界' });
|
||||
});
|
||||
|
||||
|
||||
it('uses a route only once', async () => {
|
||||
const mid = [
|
||||
get('/', hello),
|
||||
get('/', throwError)
|
||||
];
|
||||
|
||||
const res = await run(mid).get('/');
|
||||
expect(res).toMatchObject({ status: 200, body: 'Hello 世界' });
|
||||
});
|
||||
|
||||
|
||||
it('parses params correctly', async () => {
|
||||
const mid = get('/:id', ctx => ctx.params.id);
|
||||
|
||||
const res = await run(mid).get('/42?ignored=true');
|
||||
expect(res.body).toBe('42');
|
||||
});
|
||||
|
||||
// A bug shifted the router's middleware on each request so now we test for
|
||||
// multiple request to make sure the middleware remains the same
|
||||
it('does not modify the router', async () => {
|
||||
const inst = run(get('/', hello)).alive(async api => {
|
||||
for (let url of [0, 1, 2]) {
|
||||
const res = await api.get('/');
|
||||
expect(res.body).toBe('Hello 世界');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('does generic error matching', async () => {
|
||||
let err;
|
||||
const res = await run(throwError, error(ctx => {
|
||||
err = ctx.error;
|
||||
return 'Hello world';
|
||||
})).get('/');
|
||||
expect(res.body).toBe('Hello world');
|
||||
expect(err.message).toMatch(/MockError/);
|
||||
});
|
||||
|
||||
it('does path error matching', async () => {
|
||||
let err;
|
||||
const res = await run(throwError, error('test', ctx => {
|
||||
err = ctx.error;
|
||||
return 'Hello world';
|
||||
})).get('/');
|
||||
expect(res.body).toBe('Hello world');
|
||||
expect(err.message).toMatch(/MockError/);
|
||||
});
|
||||
|
||||
it('does empty error matching', async () => {
|
||||
let err;
|
||||
const res = await run(throwError).get('/');
|
||||
expect(res.status).toBe(500);
|
||||
});
|
||||
});
|
5
node_modules/server/router/parse.js
generated
vendored
Normal file
5
node_modules/server/router/parse.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
// Parse the request parameters
|
||||
module.exports = middle => {
|
||||
const path = typeof middle[0] === 'string' ? middle.shift() : '*';
|
||||
return { path, middle };
|
||||
};
|
57
node_modules/server/router/path-to-regexp-wrap.js
generated
vendored
Normal file
57
node_modules/server/router/path-to-regexp-wrap.js
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
// This comes from https://github.com/teologov/path-to-regexp-wrap
|
||||
// because of this bug: https://github.com/franciscop/server/issues/43
|
||||
|
||||
/**
|
||||
* Path to regexp lib wrapper
|
||||
* @author Andrey Teologov <teologov.and@gmail.com>
|
||||
* @date 16.04.14
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const path = require('path-to-regexp');
|
||||
|
||||
/**
|
||||
* Routes lib
|
||||
* @type {exports}
|
||||
*/
|
||||
module.exports = function(options) {
|
||||
options = options || {};
|
||||
|
||||
/**
|
||||
* String decoder
|
||||
* @param {String} str
|
||||
* @returns {*}
|
||||
*/
|
||||
function decodeUri(str) {
|
||||
try {
|
||||
str = decodeURIComponent(str);
|
||||
} catch(e) {
|
||||
throw new Error(`Cannot decodeURIComponent: ${str}` );
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
return function(route) {
|
||||
const keys = [];
|
||||
const reg = path.apply(this, [route, keys, options]);
|
||||
|
||||
return function(route, config) {
|
||||
const res = reg.exec(route);
|
||||
const params = config || {};
|
||||
|
||||
if (!res) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 1, l = res.length; i < l; i++) {
|
||||
if (!res[i]) {
|
||||
continue;
|
||||
}
|
||||
params[keys[i - 1].name] = decodeUri(res[i]);
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
}
|
||||
};
|
7
node_modules/server/router/post.js
generated
vendored
Normal file
7
node_modules/server/router/post.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// Import the generic REST handler
|
||||
const generic = require('./generic');
|
||||
|
||||
// Defined the actual method
|
||||
module.exports = (...middle) => {
|
||||
return generic('POST', ...middle);
|
||||
};
|
7
node_modules/server/router/put.js
generated
vendored
Normal file
7
node_modules/server/router/put.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// Import the generic REST handler
|
||||
const generic = require('./generic');
|
||||
|
||||
// Defined the actual method
|
||||
module.exports = (...middle) => {
|
||||
return generic('PUT', ...middle);
|
||||
};
|
10
node_modules/server/router/sub.js
generated
vendored
Normal file
10
node_modules/server/router/sub.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
const join = require('../src/join');
|
||||
|
||||
module.exports = (path, ...middle) => async ctx => {
|
||||
const full = ctx.req.subdomains.reverse().join('.');
|
||||
if ((typeof path === 'string' && path === full) ||
|
||||
(path instanceof RegExp && path.test(full))) {
|
||||
await join(middle)(ctx);
|
||||
ctx.req.solved = true;
|
||||
}
|
||||
};
|
146
node_modules/server/router/unit.test.js
generated
vendored
Normal file
146
node_modules/server/router/unit.test.js
generated
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
// Unit - test the router on its own
|
||||
const extend = require('extend');
|
||||
const loadware = require('loadware');
|
||||
const join = require('server/src/join');
|
||||
const { get, error } = require('server/router');
|
||||
const RouterError = require('./errors');
|
||||
|
||||
const run = require('server/test/run');
|
||||
|
||||
const createCtx = ({ url = '/', path = '/', method = 'GET' } = {}) => extend({
|
||||
req: { url, path, method },
|
||||
res: { send: () => {} },
|
||||
options: {}
|
||||
});
|
||||
|
||||
|
||||
const router = require('.');
|
||||
|
||||
|
||||
describe('server/router definition', () => {
|
||||
it('loads the main router', () => {
|
||||
expect(router).toEqual(require('server').router);
|
||||
expect(router).toBe(require('server/router'));
|
||||
});
|
||||
|
||||
it('has the right methods defined', () => {
|
||||
expect(router.get ).toEqual(jasmine.any(Function));
|
||||
expect(router.get ).toEqual(jasmine.any(Function));
|
||||
expect(router.post ).toEqual(jasmine.any(Function));
|
||||
expect(router.put ).toEqual(jasmine.any(Function));
|
||||
expect(router.del ).toEqual(jasmine.any(Function));
|
||||
expect(router.sub ).toEqual(jasmine.any(Function));
|
||||
expect(router.error).toEqual(jasmine.any(Function));
|
||||
});
|
||||
|
||||
it('can load all the methods manually', () => {
|
||||
expect(require('server/router/get' )).toEqual(jasmine.any(Function));
|
||||
expect(require('server/router/get' )).toEqual(jasmine.any(Function));
|
||||
expect(require('server/router/post' )).toEqual(jasmine.any(Function));
|
||||
expect(require('server/router/put' )).toEqual(jasmine.any(Function));
|
||||
expect(require('server/router/del' )).toEqual(jasmine.any(Function));
|
||||
expect(require('server/router/sub' )).toEqual(jasmine.any(Function));
|
||||
expect(require('server/router/error')).toEqual(jasmine.any(Function));
|
||||
});
|
||||
});
|
||||
|
||||
describe('server/router works', () => {
|
||||
it('works', async () => {
|
||||
const mid = [
|
||||
() => new Promise((resolve) => resolve()),
|
||||
get('/aaa', () => { throw new Error(); }),
|
||||
get('/', () => 'Hello 世界'),
|
||||
get('/sth', () => { throw new Error(); }),
|
||||
get('/', () => { throw new Error(); })
|
||||
];
|
||||
|
||||
const ctx = createCtx();
|
||||
await join(mid)(ctx);
|
||||
expect(ctx.req.solved).toBe(true);
|
||||
});
|
||||
|
||||
it('works even when wrapped with join() and loadware()', async () => {
|
||||
const middles = [
|
||||
() => new Promise((resolve) => resolve()),
|
||||
get('/aaa', () => { throw new Error(); }),
|
||||
join(loadware(get('/', () => 'Hello 世界'))),
|
||||
get('/sth', () => { throw new Error(); }),
|
||||
get('/', () => { throw new Error(); })
|
||||
];
|
||||
|
||||
// Returns the promise to be handled async
|
||||
const ctx = createCtx();
|
||||
await join(middles)(ctx);
|
||||
expect(ctx.req.solved).toBe(true);
|
||||
});
|
||||
|
||||
|
||||
it('works with parameters', async () => {
|
||||
const ctx = createCtx({ path: '/test/francisco/presencia/bla' });
|
||||
await get('/test/:name/:lastname/bla')(ctx);
|
||||
expect(ctx.req.solved).toBe(true);
|
||||
expect(ctx.req.params.name).toBe('francisco');
|
||||
expect(ctx.req.params.lastname).toBe('presencia');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
describe('Error routes', () => {
|
||||
it('can catch errors', async () => {
|
||||
const generate = () => { throw new Error('Should be caught'); };
|
||||
const handle = error(() => 'Error 世界');
|
||||
|
||||
const res = await run([generate, handle]).get('/');
|
||||
expect(res.body).toBe('Error 世界');
|
||||
});
|
||||
|
||||
it('can catch errors with full path', async () => {
|
||||
const generate = ctx => { throw new RouterError('router'); };
|
||||
const handle = error('/server/test/router', ctx => {
|
||||
return ctx.error.code;
|
||||
});
|
||||
const res = await run([generate, handle]).get('/');
|
||||
expect(res.body).toBe('/server/test/router');
|
||||
});
|
||||
|
||||
it('can catch errors with partial path', async () => {
|
||||
const generate = ctx => { throw new RouterError('router'); };
|
||||
const handle = error('/server/test', ctx => {
|
||||
return ctx.error.code;
|
||||
});
|
||||
const res = await run([generate, handle]).get('/');
|
||||
expect(res.body).toBe('/server/test/router');
|
||||
});
|
||||
|
||||
const errors = {
|
||||
'test:pre:1': new Error('Hi there 1'),
|
||||
'test:pre:a': new Error('Hi there a'),
|
||||
'test:pre:b': new Error('Hi there b'),
|
||||
'test:pre:build': opts => new Error(`Hi there ${opts.name}`)
|
||||
};
|
||||
|
||||
it('can generate errors', async () => {
|
||||
const generate = ctx => {
|
||||
throw new RouterError('router');
|
||||
};
|
||||
const handle = error('/server/test/router', ctx => {
|
||||
return ctx.error.code;
|
||||
});
|
||||
|
||||
const res = await run({ errors }, [generate, handle]).get('/');
|
||||
expect(res.body).toBe('/server/test/router');
|
||||
});
|
||||
|
||||
it('can generate errors with options', async () => {
|
||||
const generate = ctx => {
|
||||
throw new RouterError('simplerouter', { text: 'ABC' });
|
||||
};
|
||||
const handle = error('/server/test/simplerouter', ctx => {
|
||||
return ctx.error.message;
|
||||
});
|
||||
|
||||
const res = await run({ errors }, [generate, handle]).get('/');
|
||||
expect(res.body).toBe(`Simple message: ABC`);
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user