1 | const jsonServer = require("json-server");
|
2 | const { handleAggs } = require("./aggregation");
|
3 | const toJsonServer = require("./query-to-jsonserver");
|
4 | const _ = require("lodash");
|
5 | const { safeToArray } = require("./util");
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | function 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 |
|
27 | app.use(jsonServer.rewriter(rewrites));
|
28 |
|
29 |
|
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 |
|
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 |
|
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 |
|
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 |
|
81 | routers.forEach(router => app.use(router));
|
82 |
|
83 |
|
84 | const handleSelect = (req, data = []) => {
|
85 | const query = req.cusQuery || {};
|
86 |
|
87 | const select = safeToArray(query._select);
|
88 |
|
89 |
|
90 | if (select) {
|
91 |
|
92 | const positive = select.filter(s => !_.startsWith(s, "-"));
|
93 |
|
94 |
|
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 |
|
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 |
|
137 | module.exports = MockServer;
|