UNPKG

3.1 kBJavaScriptView Raw
1const jsonServer = require("json-server");
2const { handleAggs } = require("./aggregation");
3const toJsonServer = require("./query-to-jsonserver");
4const _ = require("lodash");
5const { safeToArray } = require("./util");
6
7/**
8 *
9 * @param {import('express').Application} app
10 * @param {Object} opts
11 * @param {Function} shouldMock
12 */
13function MockServer(opts) {
14 const {
15 db = {},
16 rewrites = {},
17 routers = [],
18 aggregations = {},
19 shouldMock,
20 } = opts;
21
22 const app = opts.app ? opts.app : jsonServer.create();
23
24 const dbRouter = jsonServer.router(db);
25
26 // rewrites
27 app.use(jsonServer.rewriter(rewrites));
28
29 // user defined routers
30 app.use(jsonServer.bodyParser);
31
32 if (!shouldMock) {
33 app.use((req, res, next) => {
34 req.query = toJsonServer(req.query);
35 return next();
36 });
37 } else {
38 app.use((req, res, next) => {
39 if (shouldMock(req)) {
40 req.query = toJsonServer(req.query);
41 return next();
42 }
43 return next();
44 });
45 }
46
47 // if has _group or _select, remove _limit, _start, _sort, _order from query
48 app.use((req, res, next) => {
49 const query = req.query || {};
50 const path = req.path;
51 const { _group, _select, _limit, _start, _sort, _order } = query;
52
53 // has agg config
54 const agg = aggregations[path];
55
56 req.cusQuery = {};
57
58 if (_group) req.cusQuery._group = _group;
59 if (_select) req.cusQuery._select = _select;
60
61 // has agg and _group, move _limit, _start, _sort, _order to cusQuery
62 if (agg && _group) {
63 req.cusQuery._limit = _limit;
64 req.cusQuery._start = _start;
65 req.cusQuery._sort = _sort;
66 req.cusQuery._order = _order;
67
68 delete req.query._limit;
69 delete req.query._start;
70 delete req.query._sort;
71 delete req.query._order;
72 }
73
74 delete req.query._group;
75 delete req.query._select;
76
77 return next();
78 });
79
80 // routes
81 routers.forEach(router => app.use(router));
82
83 // handle select
84 const handleSelect = (req, data = []) => {
85 const query = req.cusQuery || {};
86
87 const select = safeToArray(query._select);
88
89 // handle select
90 if (select) {
91 // positive
92 const positive = select.filter(s => !_.startsWith(s, "-"));
93
94 // minus
95 const minus = select
96 .filter(s => s.startsWith("-"))
97 .map(s => _.trimStart(s, "-"))
98 .filter(s => s !== "id");
99
100 let chain = _.chain(data);
101
102 if (positive && positive.length > 0) {
103 chain = chain.map(d => _.pick(d, ["id", ...positive]));
104 }
105
106 if (minus && minus.length > 0) {
107 chain = chain.map(d => _.omit(d, minus));
108 }
109
110 return chain.value();
111 }
112
113 return data;
114 };
115
116 // handle aggs
117 dbRouter.render = (req, res) => {
118 let data = handleAggs(aggregations, req, res);
119 data = handleSelect(req, data);
120 res.jsonp(data);
121 };
122
123 if (!shouldMock) {
124 app.use(dbRouter);
125 } else {
126 app.use((req, res, next) => {
127 if (shouldMock(req)) {
128 return dbRouter(req, res, next);
129 }
130 return next();
131 });
132 }
133
134 return app;
135}
136
137module.exports = MockServer;