-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
113 lines (90 loc) · 2.84 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
'use strict';
var JSONScript = require('jsonscript-js');
var _ = require('lodash');
var processRequest = require('supertest');
module.exports = jsonscriptExpress;
var METHODS = ['get', 'post', 'put', 'delete'];
function jsonscriptExpress(app, options, js) {
options = _.defaults(options, {
routerExecutor: 'router',
basePath: '',
jsonscript: { strict: true },
Promise: (typeof Promise !== 'undefined') && Promise
});
var processResponse = processResponseFunc(options);
js = js || new JSONScript(options.jsonscript);
addExecutorMethods();
js.addExecutor(options.routerExecutor, execRouter);
evaluator.js = js;
return evaluator;
function evaluator(req, res) {
var script = req.body.script;
var data = req.body.data;
var valid = js.validate(script);
if (valid) {
js.evaluate(script, data)
.then(function (value) {
res.json(value);
}, function (err) {
res.status(err.errors ? 400 : err.statusCode || 500)
.send({
error: err.message,
errors: err.errors
});
});
} else {
res.status(400)
.send({
error: 'script is invalid',
errors: js.validate.errors
});
}
}
function execRouter(args) {
var request = processRequest(app)[args.method](options.basePath + args.path)
.set('Accept', 'application/json');
if (args.headers) request.set(args.headers);
if (args.body) request.send(args.body);
return new options.Promise(function (resolve, reject) {
request.end(function (err, resp) {
if (err) return reject(err);
try { resolve(processResponse(resp, args)); }
catch(e) { reject(e); }
});
});
}
function addExecutorMethods() {
METHODS.forEach(function (method) {
execRouter[method] = function(args) {
if (args.method && args.method != method) {
console.warn('method specified in args (' + args.method +
') is different from $method in instruction (' + method + '), used ' + method);
}
args.method = method;
return execRouter(args);
};
});
}
}
function processResponseFunc(options) {
return options.processResponse == 'body'
? bodyProcessResponse
: typeof options.processResponse == 'function'
? options.processResponse
: defaultProcessResponse;
}
function bodyProcessResponse(resp) {
if (resp.statusCode < 300) return resp.body;
throw new HttpError(resp);
}
function defaultProcessResponse(resp, args) {
resp = _.pick(resp, 'statusCode', 'headers', 'body');
resp.request = args;
return resp;
}
function HttpError(resp) {
this.message = resp.body ? JSON.stringify(resp.body) : 'Error';
this.statusCode = resp.statusCode;
}
HttpError.prototype = Object.create(Error.prototype);
HttpError.prototype.constructor = HttpError;