json-server 0.9.4 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.babelrc CHANGED
@@ -1,5 +1,10 @@
1
1
  {
2
2
  "presets": [
3
- ["es2015", { "loose": true }]
3
+ ["env", {
4
+ "targets": {
5
+ "node": 4
6
+ },
7
+ "exclude": ["transform-regenerator"]
8
+ }]
4
9
  ]
5
10
  }
package/.travis.yml CHANGED
@@ -2,4 +2,4 @@ sudo: false
2
2
  language: node_js
3
3
  node_js:
4
4
  - "stable"
5
- # - "0.12"
5
+ - "4"
package/CHANGELOG.md CHANGED
@@ -1,9 +1,29 @@
1
1
  # Change Log
2
2
 
3
+ ## [0.10.1][2017-05-16] `GET /posts?_sort=user,views&_order=desc,asc`
4
+
5
+ * Multiple fields sorting
6
+
7
+ ## [0.10.0][2017-04-26]
8
+
9
+ * __Drop Node `v0.12` support__
10
+ * Prevent `TypeError` when a filter is applied on a `null` value [#510](https://github.com/typicode/json-server/issues/510)
11
+
12
+ ## [0.9.6][2017-03-08]
13
+
14
+ * Update index page
15
+ * Improve performances ([lowdb](https://github.com/typicode/lowdb) `v0.15`)
16
+ * Add `Location` header to newly created resources [#473](https://github.com/typicode/json-server/pull/473)
17
+
18
+ ## [0.9.5][2017-02-11]
19
+
20
+ * Display custom routes on homepage
21
+ * Fix duplicate query params error [#352](https://github.com/typicode/json-server/issues/352)
22
+
3
23
  ## [0.9.4][2016-12-08]
4
24
 
5
25
  * Improve rewriter [#431](https://github.com/typicode/json-server/issues/431)
6
- * Improve watch mode [#427](https://github.com/typicode/json-server/pull/427)
26
+ * Improve watch mode [#427](https://github.com/typicode/json-server/pull/427)
7
27
 
8
28
  ## [0.9.3][2016-12-07]
9
29
 
@@ -30,7 +50,7 @@
30
50
  * [#363](https://github.com/typicode/json-server/issues/363) [#365](https://github.com/typicode/json-server/issues/365)
31
51
  * [#374](https://github.com/typicode/json-server/issues/374)
32
52
  * [#383](https://github.com/typicode/json-server/issues/383)
33
- * Updated dependencies and codebase to ES6
53
+ * Updated dependencies and codebase to ES6
34
54
 
35
55
  ## [0.8.23][2016-11-03]
36
56
 
package/README.md CHANGED
@@ -8,8 +8,9 @@ Created with <3 for front-end developers who need a quick back-end for prototypi
8
8
  * [JSONPlaceholder - Live running version](http://jsonplaceholder.typicode.com)
9
9
 
10
10
  See also:
11
- * :hotel: [hotel - Start apps from your browser and get local dev domains in seconds](https://github.com/typicode/hotel)
12
11
  * :dog: [husky - Git hooks made easy](https://github.com/typicode/husky)
12
+ * :camera: [tlapse - Create a timelapse of your web development](https://github.com/typicode/tlapse)
13
+ * :hotel: [hotel - Process manager for developers with local .dev domain out of the box](https://github.com/typicode/hotel)
13
14
 
14
15
  ## Table of contents
15
16
 
@@ -153,8 +154,14 @@ _10 items are returned by default_
153
154
  Add `_sort` and `_order` (ascending order by default)
154
155
 
155
156
  ```
156
- GET /posts?_sort=views&_order=DESC
157
- GET /posts/1/comments?_sort=votes&_order=ASC
157
+ GET /posts?_sort=views&_order=asc
158
+ GET /posts/1/comments?_sort=votes&_order=asc
159
+ ```
160
+
161
+ For multiple fields, use the following format:
162
+
163
+ ```
164
+ GET /posts?_sort=user,views&_order=desc,asc
158
165
  ```
159
166
 
160
167
  ### Slice
@@ -167,6 +174,8 @@ GET /posts/1/comments?_start=20&_end=30
167
174
  GET /posts/1/comments?_start=20&_limit=10
168
175
  ```
169
176
 
177
+ _Works exactly as [Array.slice](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) (i.e. `_start` is inclusive and `_end` exclusive)_
178
+
170
179
  ### Operators
171
180
 
172
181
  Add `_gte` or `_lte` for getting a range
@@ -276,11 +285,11 @@ Using JS instead of a JSON file, you can create data programmatically.
276
285
 
277
286
  ```javascript
278
287
  // index.js
279
- module.exports = function() {
280
- var data = { users: [] }
288
+ module.exports = () => {
289
+ const data = { users: [] }
281
290
  // Create 1000 users
282
- for (var i = 0; i < 1000; i++) {
283
- data.users.push({ id: i, name: 'user' + i })
291
+ for (let i = 0; i < 1000; i++) {
292
+ data.users.push({ id: i, name: `user${i}` })
284
293
  }
285
294
  return data
286
295
  }
@@ -304,7 +313,7 @@ Create a `routes.json` file. Pay attention to start every route with `/`.
304
313
  {
305
314
  "/api/": "/",
306
315
  "/blog/:resource/:id/show": "/:resource/:id",
307
- "/blog/:category": "/posts/:id?category=:category"
316
+ "/blog/:category": "/posts?category=:category"
308
317
  }
309
318
  ```
310
319
 
@@ -329,7 +338,7 @@ You can add your middlewares from the CLI using `--middlewares` option:
329
338
 
330
339
  ```js
331
340
  // hello.js
332
- module.exports = function (req, res, next) {
341
+ module.exports = (req, res, next) => {
333
342
  res.header('X-Hello', 'World')
334
343
  next()
335
344
  }
@@ -385,16 +394,20 @@ If you need to add authentication, validation, or __any behavior__, you can use
385
394
 
386
395
  #### Simple example
387
396
 
397
+ ```sh
398
+ $ npm install json-server --save-dev
399
+ ```
400
+
388
401
  ```js
389
402
  // server.js
390
- var jsonServer = require('json-server')
391
- var server = jsonServer.create()
392
- var router = jsonServer.router('db.json')
393
- var middlewares = jsonServer.defaults()
403
+ const jsonServer = require('json-server')
404
+ const server = jsonServer.create()
405
+ const router = jsonServer.router('db.json')
406
+ const middlewares = jsonServer.defaults()
394
407
 
395
408
  server.use(middlewares)
396
409
  server.use(router)
397
- server.listen(3000, function () {
410
+ server.listen(3000, () => {
398
411
  console.log('JSON Server is running')
399
412
  })
400
413
  ```
@@ -406,8 +419,8 @@ $ node server.js
406
419
  The path you provide to the `jsonServer.router` function is relative to the directory from where you launch your node process. If you run the above code from another directory, it’s better to use an absolute path:
407
420
 
408
421
  ```js
409
- var path = require('path')
410
- var router = jsonServer.router(path.join(__dirname, 'db.json'))
422
+ const path = require('path')
423
+ const router = jsonServer.router(path.join(__dirname, 'db.json'))
411
424
  ```
412
425
 
413
426
  For an in-memory database, simply pass an object to `jsonServer.router()`.
@@ -419,23 +432,23 @@ Please note also that `jsonServer.router()` can be used in existing Express proj
419
432
  Let's say you want a route that echoes query parameters and another one that set a timestamp on every resource created.
420
433
 
421
434
  ```js
422
- var jsonServer = require('json-server')
423
- var server = jsonServer.create()
424
- var router = jsonServer.router('db.json')
425
- var middlewares = jsonServer.defaults()
435
+ const jsonServer = require('json-server')
436
+ const server = jsonServer.create()
437
+ const router = jsonServer.router('db.json')
438
+ const middlewares = jsonServer.defaults()
426
439
 
427
440
  // Set default middlewares (logger, static, cors and no-cache)
428
441
  server.use(middlewares)
429
442
 
430
443
  // Add custom routes before JSON Server router
431
- server.get('/echo', function (req, res) {
444
+ server.get('/echo', (req, res) => {
432
445
  res.jsonp(req.query)
433
446
  })
434
447
 
435
448
  // To handle POST, PUT and PATCH you need to use a body-parser
436
449
  // You can use the one used by JSON Server
437
450
  server.use(jsonServer.bodyParser)
438
- server.use(function (req, res, next) {
451
+ server.use((req, res, next) => {
439
452
  if (req.method === 'POST') {
440
453
  req.body.createdAt = Date.now()
441
454
  }
@@ -445,7 +458,7 @@ server.use(function (req, res, next) {
445
458
 
446
459
  // Use default router
447
460
  server.use(router)
448
- server.listen(3000, function () {
461
+ server.listen(3000, () => {
449
462
  console.log('JSON Server is running')
450
463
  })
451
464
  ```
@@ -453,13 +466,13 @@ server.listen(3000, function () {
453
466
  #### Access control example
454
467
 
455
468
  ```js
456
- var jsonServer = require('json-server')
457
- var server = jsonServer.create()
458
- var router = jsonServer.router('db.json')
459
- var middlewares = jsonServer.defaults()
469
+ const jsonServer = require('json-server')
470
+ const server = jsonServer.create()
471
+ const router = jsonServer.router('db.json')
472
+ const middlewares = jsonServer.defaults()
460
473
 
461
474
  server.use(middlewares)
462
- server.use(function (req, res, next) {
475
+ server.use((req, res, next) => {
463
476
  if (isAuthorized(req)) { // add your authorization logic here
464
477
  next() // continue to JSON Server router
465
478
  } else {
@@ -467,7 +480,7 @@ server.use(function (req, res, next) {
467
480
  }
468
481
  })
469
482
  server.use(router)
470
- server.listen(3000, function () {
483
+ server.listen(3000, () => {
471
484
  console.log('JSON Server is running')
472
485
  })
473
486
  ```
@@ -478,9 +491,9 @@ To modify responses, overwrite `router.render` method:
478
491
 
479
492
  ```javascript
480
493
  // In this example, returned resources will be wrapped in a body property
481
- router.render = function (req, res) {
494
+ router.render = (req, res) => {
482
495
  res.jsonp({
483
- body: res.locals.data
496
+ body: res.locals.data
484
497
  })
485
498
  }
486
499
  ```
package/db.json CHANGED
@@ -1,20 +1,9 @@
1
1
  {
2
2
  "posts": [
3
- {
4
- "id": 1,
5
- "title": "json-server",
6
- "author": "typicode"
7
- }
3
+ { "id": 1, "title": "json-server", "author": "typicode" }
8
4
  ],
9
5
  "comments": [
10
- {
11
- "id": 1,
12
- "body": "some comment",
13
- "postId": 1
14
- }
6
+ { "id": 1, "body": "some comment", "postId": 1 }
15
7
  ],
16
- "profile": {
17
- "name": "typicode"
18
- },
19
- "images": [1]
20
- }
8
+ "profile": { "name": "typicode" }
9
+ }
package/lib/cli/index.js CHANGED
@@ -6,7 +6,7 @@ var run = require('./run');
6
6
  var pkg = require('../../package.json');
7
7
 
8
8
  module.exports = function () {
9
- updateNotifier({ pkg: pkg }).notify();
9
+ updateNotifier({ pkg }).notify();
10
10
 
11
11
  var argv = yargs.config('config').usage('$0 [options] <source>').options({
12
12
  port: {
package/lib/cli/run.js CHANGED
@@ -15,7 +15,7 @@ var jsonServer = require('../server');
15
15
  function prettyPrint(argv, object, rules) {
16
16
  var host = argv.host === '0.0.0.0' ? 'localhost' : argv.host;
17
17
  var port = argv.port;
18
- var root = 'http://' + host + ':' + port;
18
+ var root = `http://${host}:${port}`;
19
19
 
20
20
  console.log();
21
21
  console.log(chalk.bold(' Resources'));
@@ -90,7 +90,7 @@ module.exports = function (argv) {
90
90
  var server = void 0;
91
91
 
92
92
  if (!fs.existsSync(argv.snapshots)) {
93
- console.log('Error: snapshots directory ' + argv.snapshots + ' doesn\'t exist');
93
+ console.log(`Error: snapshots directory ${argv.snapshots} doesn't exist`);
94
94
  process.exit(1);
95
95
  }
96
96
 
@@ -107,8 +107,8 @@ module.exports = function (argv) {
107
107
 
108
108
  // Be nice and create a default db.json if it doesn't exist
109
109
  if (is.JSON(source) && !fs.existsSync(source)) {
110
- console.log(chalk.yellow(' Oops, ' + source + ' doesn\'t seem to exist'));
111
- console.log(chalk.yellow(' Creating ' + source + ' with some default data'));
110
+ console.log(chalk.yellow(` Oops, ${source} doesn't seem to exist`));
111
+ console.log(chalk.yellow(` Creating ${source} with some default data`));
112
112
  console.log();
113
113
  fs.writeFileSync(source, JSON.stringify(example, null, 2));
114
114
  }
@@ -160,8 +160,8 @@ module.exports = function (argv) {
160
160
  // Support nohup
161
161
  // https://github.com/typicode/json-server/issues/221
162
162
  process.stdin.on('error', function () {
163
- console.log(' Error, can\'t read from stdin');
164
- console.log(' Creating a snapshot from the CLI won\'t be possible');
163
+ console.log(` Error, can't read from stdin`);
164
+ console.log(` Creating a snapshot from the CLI won't be possible`);
165
165
  });
166
166
  process.stdin.setEncoding('utf8');
167
167
  process.stdin.on('data', function (chunk) {
@@ -170,74 +170,70 @@ module.exports = function (argv) {
170
170
  var file = path.join(argv.snapshots, filename);
171
171
  var state = app.db.getState();
172
172
  fs.writeFileSync(file, JSON.stringify(state, null, 2), 'utf-8');
173
- console.log(' Saved snapshot to ' + path.relative(process.cwd(), file) + '\n');
173
+ console.log(` Saved snapshot to ${path.relative(process.cwd(), file)}\n`);
174
174
  }
175
175
  });
176
176
 
177
177
  // Watch files
178
178
  if (argv.watch) {
179
- (function () {
180
- console.log(chalk.gray(' Watching...'));
181
- console.log();
182
- var source = argv._[0];
183
-
184
- // Can't watch URL
185
- if (is.URL(source)) throw new Error('Can\'t watch URL');
186
-
187
- // Watch .js or .json file
188
- // Since lowdb uses atomic writing, directory is watched instead of file
189
- var watchedDir = path.dirname(source);
190
- var readError = false;
191
- fs.watch(watchedDir, function (event, file) {
192
- // https://github.com/typicode/json-server/issues/420
193
- // file can be null
194
- if (file) {
195
- var watchedFile = path.resolve(watchedDir, file);
196
- if (watchedFile === path.resolve(source)) {
197
- if (is.JSON(watchedFile)) {
198
- var obj = void 0;
199
- try {
200
- obj = jph.parse(fs.readFileSync(watchedFile));
201
- if (readError) {
202
- console.log(chalk.green(' Read error has been fixed :)'));
203
- readError = false;
204
- }
205
- } catch (e) {
206
- readError = true;
207
- console.log(chalk.red(' Error reading ' + watchedFile));
208
- console.error(e.message);
209
- return;
179
+ console.log(chalk.gray(' Watching...'));
180
+ console.log();
181
+ var _source = argv._[0];
182
+
183
+ // Can't watch URL
184
+ if (is.URL(_source)) throw new Error('Can\'t watch URL');
185
+
186
+ // Watch .js or .json file
187
+ // Since lowdb uses atomic writing, directory is watched instead of file
188
+ var watchedDir = path.dirname(_source);
189
+ var readError = false;
190
+ fs.watch(watchedDir, function (event, file) {
191
+ // https://github.com/typicode/json-server/issues/420
192
+ // file can be null
193
+ if (file) {
194
+ var watchedFile = path.resolve(watchedDir, file);
195
+ if (watchedFile === path.resolve(_source)) {
196
+ if (is.JSON(watchedFile)) {
197
+ var obj = void 0;
198
+ try {
199
+ obj = jph.parse(fs.readFileSync(watchedFile));
200
+ if (readError) {
201
+ console.log(chalk.green(` Read error has been fixed :)`));
202
+ readError = false;
210
203
  }
204
+ } catch (e) {
205
+ readError = true;
206
+ console.log(chalk.red(` Error reading ${watchedFile}`));
207
+ console.error(e.message);
208
+ return;
209
+ }
211
210
 
212
- // Compare .json file content with in memory database
213
- var isDatabaseDifferent = !_.isEqual(obj, app.db.getState());
214
- if (isDatabaseDifferent) {
215
- console.log(chalk.gray(' ' + source + ' has changed, reloading...'));
216
- server && server.destroy();
217
- start();
218
- }
211
+ // Compare .json file content with in memory database
212
+ var isDatabaseDifferent = !_.isEqual(obj, app.db.getState());
213
+ if (isDatabaseDifferent) {
214
+ console.log(chalk.gray(` ${_source} has changed, reloading...`));
215
+ server && server.destroy();
216
+ start();
219
217
  }
220
218
  }
221
219
  }
222
- });
223
-
224
- // Watch routes
225
- if (argv.routes) {
226
- (function () {
227
- var watchedDir = path.dirname(argv.routes);
228
- fs.watch(watchedDir, function (event, file) {
229
- if (file) {
230
- var watchedFile = path.resolve(watchedDir, file);
231
- if (watchedFile === path.resolve(argv.routes)) {
232
- console.log(chalk.gray(' ' + argv.routes + ' has changed, reloading...'));
233
- server && server.destroy();
234
- start();
235
- }
236
- }
237
- });
238
- })();
239
220
  }
240
- })();
221
+ });
222
+
223
+ // Watch routes
224
+ if (argv.routes) {
225
+ var _watchedDir = path.dirname(argv.routes);
226
+ fs.watch(_watchedDir, function (event, file) {
227
+ if (file) {
228
+ var watchedFile = path.resolve(_watchedDir, file);
229
+ if (watchedFile === path.resolve(argv.routes)) {
230
+ console.log(chalk.gray(` ${argv.routes} has changed, reloading...`));
231
+ server && server.destroy();
232
+ start();
233
+ }
234
+ }
235
+ });
236
+ }
241
237
  }
242
238
  });
243
239
  };
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
 
3
3
  module.exports = {
4
- JSON: JSON,
5
- JS: JS,
6
- URL: URL
4
+ JSON,
5
+ JS,
6
+ URL
7
7
  };
8
8
 
9
9
  function JSON(s) {
@@ -3,7 +3,7 @@
3
3
  var path = require('path');
4
4
  var request = require('request');
5
5
  var low = require('lowdb');
6
- var fileAsync = require('lowdb/lib/file-async');
6
+ var fileAsync = require('lowdb/lib/storages/file-async');
7
7
  var is = require('./is');
8
8
 
9
9
  module.exports = function (source, cb) {
@@ -4,9 +4,9 @@ var shortid = require('shortid');
4
4
  var pluralize = require('pluralize');
5
5
 
6
6
  module.exports = {
7
- getRemovable: getRemovable,
8
- createId: createId,
9
- deepQuery: deepQuery
7
+ getRemovable,
8
+ createId,
9
+ deepQuery
10
10
  };
11
11
 
12
12
  // Returns document ids that have unsatisfied relations
@@ -36,7 +36,7 @@ function getRemovable(db) {
36
36
  }
37
37
 
38
38
  // Return incremented id or uuid
39
- // Used to override underscore-db's createId with utils.createId
39
+ // Used to override lodash-id's createId with utils.createId
40
40
  function createId(coll) {
41
41
  var _ = this;
42
42
  var idProperty = _.__id();
@@ -1,80 +1,54 @@
1
1
  <html>
2
2
  <head>
3
3
  <title>JSON Server</title>
4
- <link href="//netdna.bootstrapcdn.com/bootswatch/3.1.1/flatly/bootstrap.min.css" rel="stylesheet">
5
- <link rel="stylesheet" href="stylesheets/style.css">
4
+ <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,300italic,700,700italic">
5
+ <link rel="stylesheet" href="//cdn.rawgit.com/necolas/normalize.css/master/normalize.css">
6
+ <link rel="stylesheet" href="//cdn.rawgit.com/milligram/milligram/master/dist/milligram.min.css">
7
+ <link rel="stylesheet" href="style.css">
6
8
  </head>
7
9
  <body>
8
- <div class="container">
9
- <p>
10
- <a href="https://github.com/typicode/json-server" class="logo">
11
- <img src="images/json.png">
10
+ <header>
11
+ <div class="container">
12
+ <a href="https://github.com/typicode/json-server">
13
+ <h3>JSON Server</h3>
12
14
  </a>
13
- </p>
14
-
15
- <hr>
16
-
17
- <p>
18
- <em>
19
- Congrats! You're successfully running JSON Server.
20
- </em>
21
- </p>
22
-
23
- <hr>
24
-
25
- <h4>Routes</h4>
26
- <p>
27
- Here are the resources that JSON Server has loaded:
28
- </p>
29
- <ul id="resources">loading, please wait...</ul>
30
-
31
- <p>
32
- You can view database current state at any time:
33
- </p>
34
- <ul>
35
- <li>
36
- <a href="db">db</a>
37
- </li>
38
- </ul>
39
-
40
- <p>
41
- You can use any HTTP verbs (GET, POST, PUT, PATCH and DELETE) and access your resources from anywhere
42
- using CORS and JSONP.
43
- </p>
44
-
45
- <h4>Documentation</h4>
46
- <p>
47
- View
48
- <a href="https://github.com/typicode/json-server">README</a>
49
- on GitHub.
50
- </p>
51
-
52
- <h4>Issues</h4>
53
- <p>Please go
54
- <a href="https://github.com/typicode/json-server/issues">here</a>.
55
- </p>
56
-
57
- <hr>
58
-
59
- <p>
60
- <i>To replace this page, create an index.html file in ./public, JSON Server will load it.</i>
61
- </p>
62
- </div>
63
-
64
-
65
- <script
66
- src="https://code.jquery.com/jquery-3.0.0.min.js"
67
- integrity="sha256-JmvOoLtYsmqlsWxa7mDSLMwa6dZ9rrIdtrrVYRnDRH0=" crossorigin="anonymous"></script>
68
- <script>
69
- $(function() {
70
- $.get('db').then(function(data) {
71
- $('#resources').empty();
72
- $.each(data, function(key, value) {
73
- $('#resources')
74
- .append('<li><a href="'+ key + '">' + key + '</a></li>');
75
- })
76
- })
77
- })
78
- </script>
15
+ </div>
16
+ </header>
17
+ <main>
18
+ <div class="container">
19
+ <h4>Congrats!</h4>
20
+ <p>
21
+ You're successfully running JSON Server<br>
22
+ ✧*。٩(ˊᗜˋ*)و✧*。
23
+ </p>
24
+
25
+ <div id="resources"></div>
26
+
27
+ <p>
28
+ To access and modify resources, you can use any HTTP method
29
+ <br>
30
+ <code>GET</code>
31
+ <code>POST</code>
32
+ <code>PUT</code>
33
+ <code>PATCH</code>
34
+ <code>DELETE</code>
35
+ <code>OPTIONS</code>
36
+ </p>
37
+
38
+ <div id="custom-routes"></div>
39
+ </div>
40
+ </main>
41
+
42
+ <footer>
43
+ <div class="container">
44
+ <p>
45
+ To replace this page, create a <code>./public</code> directory with an
46
+ <code>index.html</code> file in it.
47
+ </p>
48
+ </div>
49
+ </footer>
50
+
51
+ <script src="https://unpkg.com/mithril/mithril.min.js"></script>
52
+ <script src="main.js"></script>
79
53
  </body>
80
54
  </html>
@@ -0,0 +1,39 @@
1
+ 'use strict';
2
+
3
+ /* global m */
4
+
5
+ // Resource list
6
+ var db = {};
7
+
8
+ m.request('db').then(function (data) {
9
+ db = data;
10
+ });
11
+
12
+ m.mount(document.getElementById('resources'), {
13
+ view: function view() {
14
+ var keys = Object.keys(db);
15
+ var resourceList = m('ul', keys.map(function (key) {
16
+ return m('li', [m('a', { href: key }, '/' + key), m('sup', Array.isArray(db[key]) ? ' ' + db[key].length + 'x' : ' object')]);
17
+ }).concat([m('a', { href: 'db' }, '/db'), m('sup', m('em', ' state'))]));
18
+
19
+ return [m('h4', 'Resources'), keys.length ? resourceList : m('p', 'No resources found')];
20
+ }
21
+ });
22
+
23
+ // Custom routes
24
+ var customRoutes = {};
25
+
26
+ m.request('__rules').then(function (data) {
27
+ customRoutes = data;
28
+ });
29
+
30
+ m.mount(document.getElementById('custom-routes'), {
31
+ view: function view() {
32
+ var rules = Object.keys(customRoutes);
33
+ if (rules.length) {
34
+ return [m('h4', 'Custom routes'), m('table', rules.map(function (rule) {
35
+ return m('tr', [m('td', rule), m('td', '⇢ ' + customRoutes[rule])]);
36
+ }))];
37
+ }
38
+ }
39
+ });