json-server 0.17.3 → 1.0.0-alpha.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/package.json CHANGED
@@ -1,102 +1,49 @@
1
1
  {
2
2
  "name": "json-server",
3
- "version": "0.17.3",
4
- "description": "Get a full fake REST API with zero coding in less than 30 seconds",
5
- "main": "./lib/server/index.js",
6
- "bin": "./lib/cli/bin.js",
3
+ "version": "1.0.0-alpha.1",
4
+ "description": "",
5
+ "type": "module",
6
+ "exports": "./lib/index.js",
7
+ "types": "lib",
7
8
  "files": [
8
- "lib",
9
- "public"
9
+ "lib"
10
10
  ],
11
11
  "scripts": {
12
- "prepare": "husky install",
13
- "test": "npm run build && cross-env NODE_ENV=test jest",
14
- "start": "babel-node -- src/cli/bin db.json -r routes.json",
15
- "lint": "eslint . --ignore-path .gitignore",
16
- "fix": "npm run lint -- --fix",
17
- "build": "babel src -d lib",
18
- "toc": "markdown-toc -i README.md",
19
- "postversion": "git push && git push --tags",
20
- "prepublish": "npm test && npm run build"
21
- },
22
- "dependencies": {
23
- "body-parser": "^1.19.0",
24
- "chalk": "^4.1.2",
25
- "compression": "^1.7.4",
26
- "connect-pause": "^0.1.1",
27
- "cors": "^2.8.5",
28
- "errorhandler": "^1.5.1",
29
- "express": "^4.17.1",
30
- "express-urlrewrite": "^1.4.0",
31
- "json-parse-helpfulerror": "^1.0.3",
32
- "lodash": "^4.17.21",
33
- "lodash-id": "^0.14.1",
34
- "lowdb": "^1.0.0",
35
- "method-override": "^3.0.0",
36
- "morgan": "^1.10.0",
37
- "nanoid": "^3.1.23",
38
- "please-upgrade-node": "^3.2.0",
39
- "pluralize": "^8.0.0",
40
- "server-destroy": "^1.0.1",
41
- "standard": "^17.0.0",
42
- "yargs": "^17.0.1"
12
+ "css": "tailwindcss -i ./views/input.css -o ./public/output.css",
13
+ "watch-ts": "tsx watch src/bin.ts db.json",
14
+ "watch-css": "npm run css -- --watch",
15
+ "dev": "concurrently npm:watch-*",
16
+ "build": "rm -rf lib && tsc && npm run css",
17
+ "test": "node --import tsx/esm --test src/**/*.test.ts",
18
+ "prepare": "husky install"
43
19
  },
20
+ "keywords": [],
21
+ "author": "",
22
+ "license": "SEE LICENSE IN ./LICENSE",
44
23
  "devDependencies": {
45
- "@babel/cli": "^7.12.1",
46
- "@babel/core": "^7.12.3",
47
- "@babel/node": "^7.12.6",
48
- "@babel/preset-env": "^7.12.1",
49
- "cross-env": "^7.0.2",
50
- "eslint": "^7.13.0",
51
- "eslint-config-prettier": "^8.3.0",
52
- "eslint-config-standard": "^16.0.1",
53
- "eslint-plugin-import": "^2.22.1",
54
- "eslint-plugin-node": "^11.1.0",
55
- "eslint-plugin-prettier": "^3.1.4",
56
- "eslint-plugin-promise": "^4.2.1",
57
- "eslint-plugin-standard": "^4.1.0",
58
- "husky": "^6.0.0",
59
- "jest": "^26.6.3",
60
- "markdown-toc": "^1.2.0",
61
- "mkdirp": "^1.0.4",
62
- "npm-run-all": "^4.1.5",
63
- "os-tmpdir": "^2.0.0",
64
- "prettier": "^2.3.2",
65
- "rimraf": "^3.0.2",
66
- "server-ready": "^0.3.1",
67
- "supertest": "^6.0.1",
68
- "temp-write": "^4.0.0"
24
+ "@sindresorhus/tsconfig": "^5.0.0",
25
+ "@tailwindcss/typography": "^0.5.10",
26
+ "@types/node": "^20.10.0",
27
+ "@typicode/eslint-config": "^1.2.0",
28
+ "concurrently": "^8.2.2",
29
+ "get-port": "^7.0.0",
30
+ "husky": "^8.0.3",
31
+ "tailwindcss": "^3.3.5",
32
+ "tempy": "^3.1.0",
33
+ "tsx": "^4.5.0",
34
+ "type-fest": "^4.8.2",
35
+ "typescript": "^5.3.2"
69
36
  },
70
- "repository": {
71
- "type": "git",
72
- "url": "git://github.com/typicode/json-server.git"
73
- },
74
- "keywords": [
75
- "JSON",
76
- "server",
77
- "fake",
78
- "REST",
79
- "API",
80
- "prototyping",
81
- "mock",
82
- "mocking",
83
- "test",
84
- "testing",
85
- "rest",
86
- "data",
87
- "dummy",
88
- "sandbox"
89
- ],
90
- "author": "Typicode <typicode@gmail.com>",
91
- "license": "MIT",
92
- "bugs": {
93
- "url": "https://github.com/typicode/json-server/issues"
94
- },
95
- "homepage": "https://github.com/typicode/json-server",
96
- "engines": {
97
- "node": ">=12"
98
- },
99
- "jest": {
100
- "testURL": "http://localhost/"
37
+ "dependencies": {
38
+ "@tinyhttp/app": "^2.2.1",
39
+ "chokidar": "^3.5.3",
40
+ "dot-prop": "^8.0.2",
41
+ "eta": "^3.1.1",
42
+ "inflection": "^3.0.0",
43
+ "lowdb": "^6.1.1",
44
+ "milliparsec": "^2.3.0",
45
+ "sirv": "^2.0.3",
46
+ "sort-on": "^6.0.0",
47
+ "zod": "^3.22.4"
101
48
  }
102
49
  }
package/lib/cli/bin.js DELETED
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
-
4
- require('please-upgrade-node')(require('../../package.json'));
5
-
6
- require('./')();
package/lib/cli/index.js DELETED
@@ -1,81 +0,0 @@
1
- "use strict";
2
-
3
- const yargs = require('yargs');
4
-
5
- const run = require('./run');
6
-
7
- const pkg = require('../../package.json');
8
-
9
- module.exports = function () {
10
- const argv = yargs.config('config').usage('$0 [options] <source>').options({
11
- port: {
12
- alias: 'p',
13
- description: 'Set port',
14
- default: 3000
15
- },
16
- host: {
17
- alias: 'H',
18
- description: 'Set host',
19
- default: 'localhost'
20
- },
21
- watch: {
22
- alias: 'w',
23
- description: 'Watch file(s)'
24
- },
25
- routes: {
26
- alias: 'r',
27
- description: 'Path to routes file'
28
- },
29
- middlewares: {
30
- alias: 'm',
31
- array: true,
32
- description: 'Paths to middleware files'
33
- },
34
- static: {
35
- alias: 's',
36
- description: 'Set static files directory'
37
- },
38
- 'read-only': {
39
- alias: 'ro',
40
- description: 'Allow only GET requests'
41
- },
42
- 'no-cors': {
43
- alias: 'nc',
44
- description: 'Disable Cross-Origin Resource Sharing'
45
- },
46
- 'no-gzip': {
47
- alias: 'ng',
48
- description: 'Disable GZIP Content-Encoding'
49
- },
50
- snapshots: {
51
- alias: 'S',
52
- description: 'Set snapshots directory',
53
- default: '.'
54
- },
55
- delay: {
56
- alias: 'd',
57
- description: 'Add delay to responses (ms)'
58
- },
59
- id: {
60
- alias: 'i',
61
- description: 'Set database id property (e.g. _id)',
62
- default: 'id'
63
- },
64
- foreignKeySuffix: {
65
- alias: 'fks',
66
- description: 'Set foreign key suffix (e.g. _id as in post_id)',
67
- default: 'Id'
68
- },
69
- quiet: {
70
- alias: 'q',
71
- description: 'Suppress log messages from output'
72
- },
73
- config: {
74
- alias: 'c',
75
- description: 'Path to config file',
76
- default: 'json-server.json'
77
- }
78
- }).boolean('watch').boolean('read-only').boolean('quiet').boolean('no-cors').boolean('no-gzip').help('help').alias('help', 'h').version(pkg.version).alias('version', 'v').example('$0 db.json', '').example('$0 file.js', '').example('$0 http://example.com/db.json', '').epilog('https://github.com/typicode/json-server').require(1, 'Missing <source> argument').argv;
79
-
80
- run(argv);
81
- };
package/lib/cli/run.js DELETED
@@ -1,235 +0,0 @@
1
- "use strict";
2
-
3
- const fs = require('fs');
4
-
5
- const path = require('path');
6
-
7
- const jph = require('json-parse-helpfulerror');
8
-
9
- const _ = require('lodash');
10
-
11
- const chalk = require('chalk');
12
-
13
- const enableDestroy = require('server-destroy');
14
-
15
- const pause = require('connect-pause');
16
-
17
- const is = require('./utils/is');
18
-
19
- const load = require('./utils/load');
20
-
21
- const jsonServer = require('../server');
22
-
23
- function prettyPrint(argv, object, rules) {
24
- const root = `http://${argv.host}:${argv.port}`;
25
- console.log();
26
- console.log(chalk.bold(' Resources'));
27
-
28
- for (const prop in object) {
29
- // skip printing $schema nodes
30
- if (prop === '$schema') continue;
31
- console.log(` ${root}/${prop}`);
32
- }
33
-
34
- if (rules) {
35
- console.log();
36
- console.log(chalk.bold(' Other routes'));
37
-
38
- for (const rule in rules) {
39
- console.log(` ${rule} -> ${rules[rule]}`);
40
- }
41
- }
42
-
43
- console.log();
44
- console.log(chalk.bold(' Home'));
45
- console.log(` ${root}`);
46
- console.log();
47
- }
48
-
49
- function createApp(db, routes, middlewares, argv) {
50
- const app = jsonServer.create();
51
- const {
52
- foreignKeySuffix
53
- } = argv;
54
- const router = jsonServer.router(db, foreignKeySuffix ? {
55
- foreignKeySuffix
56
- } : undefined);
57
- const defaultsOpts = {
58
- logger: !argv.quiet,
59
- readOnly: argv.readOnly,
60
- noCors: argv.noCors,
61
- noGzip: argv.noGzip,
62
- bodyParser: true
63
- };
64
-
65
- if (argv.static) {
66
- defaultsOpts.static = path.join(process.cwd(), argv.static);
67
- }
68
-
69
- const defaults = jsonServer.defaults(defaultsOpts);
70
- app.use(defaults);
71
-
72
- if (routes) {
73
- const rewriter = jsonServer.rewriter(routes);
74
- app.use(rewriter);
75
- }
76
-
77
- if (middlewares) {
78
- app.use(middlewares);
79
- }
80
-
81
- if (argv.delay) {
82
- app.use(pause(argv.delay));
83
- }
84
-
85
- router.db._.id = argv.id;
86
- app.db = router.db;
87
- app.use(router);
88
- return app;
89
- }
90
-
91
- module.exports = function (argv) {
92
- const source = argv._[0];
93
- let app;
94
- let server;
95
-
96
- if (!fs.existsSync(argv.snapshots)) {
97
- console.log(`Error: snapshots directory ${argv.snapshots} doesn't exist`);
98
- process.exit(1);
99
- } // noop log fn
100
-
101
-
102
- if (argv.quiet) {
103
- console.log = () => {};
104
- }
105
-
106
- console.log();
107
- console.log(chalk.cyan(' \\{^_^}/ hi!'));
108
-
109
- function start(cb) {
110
- console.log();
111
- console.log(chalk.gray(' Loading', source));
112
- server = undefined; // create db and load object, JSON file, JS or HTTP database
113
-
114
- return load(source).then(db => {
115
- // Load additional routes
116
- let routes;
117
-
118
- if (argv.routes) {
119
- console.log(chalk.gray(' Loading', argv.routes));
120
- routes = JSON.parse(fs.readFileSync(argv.routes));
121
- } // Load middlewares
122
-
123
-
124
- let middlewares;
125
-
126
- if (argv.middlewares) {
127
- middlewares = argv.middlewares.map(function (m) {
128
- console.log(chalk.gray(' Loading', m));
129
- return require(path.resolve(m));
130
- });
131
- } // Done
132
-
133
-
134
- console.log(chalk.gray(' Done')); // Create app and server
135
-
136
- app = createApp(db, routes, middlewares, argv);
137
- server = app.listen(argv.port, argv.host); // Enhance with a destroy function
138
-
139
- enableDestroy(server); // Display server informations
140
-
141
- prettyPrint(argv, db.getState(), routes); // Catch and handle any error occurring in the server process
142
-
143
- process.on('uncaughtException', error => {
144
- if (error.errno === 'EADDRINUSE') console.log(chalk.red(`Cannot bind to the port ${error.port}. Please specify another port number either through --port argument or through the json-server.json configuration file`));else console.log('Some error occurred', error);
145
- process.exit(1);
146
- });
147
- });
148
- } // Start server
149
-
150
-
151
- start().then(() => {
152
- // Snapshot
153
- console.log(chalk.gray(' Type s + enter at any time to create a snapshot of the database')); // Support nohup
154
- // https://github.com/typicode/json-server/issues/221
155
-
156
- process.stdin.on('error', () => {
157
- console.log(` Error, can't read from stdin`);
158
- console.log(` Creating a snapshot from the CLI won't be possible`);
159
- });
160
- process.stdin.setEncoding('utf8');
161
- process.stdin.on('data', chunk => {
162
- if (chunk.trim().toLowerCase() === 's') {
163
- const filename = `db-${Date.now()}.json`;
164
- const file = path.join(argv.snapshots, filename);
165
- const state = app.db.getState();
166
- fs.writeFileSync(file, JSON.stringify(state, null, 2), 'utf-8');
167
- console.log(` Saved snapshot to ${path.relative(process.cwd(), file)}\n`);
168
- }
169
- }); // Watch files
170
-
171
- if (argv.watch) {
172
- console.log(chalk.gray(' Watching...'));
173
- console.log();
174
- const source = argv._[0]; // Can't watch URL
175
-
176
- if (is.URL(source)) throw new Error("Can't watch URL"); // Watch .js or .json file
177
- // Since lowdb uses atomic writing, directory is watched instead of file
178
-
179
- const watchedDir = path.dirname(source);
180
- let readError = false;
181
- fs.watch(watchedDir, (event, file) => {
182
- // https://github.com/typicode/json-server/issues/420
183
- // file can be null
184
- if (file) {
185
- const watchedFile = path.resolve(watchedDir, file);
186
-
187
- if (watchedFile === path.resolve(source)) {
188
- if (is.FILE(watchedFile)) {
189
- let obj;
190
-
191
- try {
192
- obj = jph.parse(fs.readFileSync(watchedFile));
193
-
194
- if (readError) {
195
- console.log(chalk.green(` Read error has been fixed :)`));
196
- readError = false;
197
- }
198
- } catch (e) {
199
- readError = true;
200
- console.log(chalk.red(` Error reading ${watchedFile}`));
201
- console.error(e.message);
202
- return;
203
- } // Compare .json file content with in memory database
204
-
205
-
206
- const isDatabaseDifferent = !_.isEqual(obj, app.db.getState());
207
-
208
- if (isDatabaseDifferent) {
209
- console.log(chalk.gray(` ${source} has changed, reloading...`));
210
- server && server.destroy(() => start());
211
- }
212
- }
213
- }
214
- }
215
- }); // Watch routes
216
-
217
- if (argv.routes) {
218
- const watchedDir = path.dirname(argv.routes);
219
- fs.watch(watchedDir, (event, file) => {
220
- if (file) {
221
- const watchedFile = path.resolve(watchedDir, file);
222
-
223
- if (watchedFile === path.resolve(argv.routes)) {
224
- console.log(chalk.gray(` ${argv.routes} has changed, reloading...`));
225
- server && server.destroy(() => start());
226
- }
227
- }
228
- });
229
- }
230
- }
231
- }).catch(err => {
232
- console.log(err);
233
- process.exit(1);
234
- });
235
- };
@@ -1,19 +0,0 @@
1
- "use strict";
2
-
3
- module.exports = {
4
- FILE,
5
- JS,
6
- URL
7
- };
8
-
9
- function FILE(s) {
10
- return !URL(s) && /\.json$/.test(s);
11
- }
12
-
13
- function JS(s) {
14
- return !URL(s) && /\.c?js$/.test(s);
15
- }
16
-
17
- function URL(s) {
18
- return /^(http|https):/.test(s);
19
- }
@@ -1,82 +0,0 @@
1
- "use strict";
2
-
3
- const fs = require('fs');
4
-
5
- const path = require('path');
6
-
7
- const http = require('http');
8
-
9
- const https = require('https');
10
-
11
- const low = require('lowdb');
12
-
13
- const FileAsync = require('lowdb/adapters/FileAsync');
14
-
15
- const Memory = require('lowdb/adapters/Memory');
16
-
17
- const is = require('./is');
18
-
19
- const chalk = require('chalk');
20
-
21
- const example = {
22
- posts: [{
23
- id: 1,
24
- title: 'json-server',
25
- author: 'typicode'
26
- }],
27
- comments: [{
28
- id: 1,
29
- body: 'some comment',
30
- postId: 1
31
- }],
32
- profile: {
33
- name: 'typicode'
34
- }
35
- };
36
-
37
- module.exports = function (source) {
38
- return new Promise((resolve, reject) => {
39
- if (is.FILE(source)) {
40
- if (!fs.existsSync(source)) {
41
- console.log(chalk.yellow(` Oops, ${source} doesn't seem to exist`));
42
- console.log(chalk.yellow(` Creating ${source} with some default data`));
43
- console.log();
44
- fs.writeFileSync(source, JSON.stringify(example, null, 2));
45
- }
46
-
47
- resolve(low(new FileAsync(source)));
48
- } else if (is.URL(source)) {
49
- // Normalize the source into a URL object.
50
- const sourceUrl = new URL(source); // Pick the client based on the protocol scheme
51
-
52
- const client = sourceUrl.protocol === 'https:' ? https : http;
53
- client.get(sourceUrl, res => {
54
- let dbData = '';
55
- res.on('data', data => {
56
- dbData += data;
57
- });
58
- res.on('end', () => {
59
- resolve(low(new Memory()).setState(JSON.parse(dbData)));
60
- });
61
- }).on('error', error => {
62
- return reject(error);
63
- });
64
- } else if (is.JS(source)) {
65
- // Clear cache
66
- const filename = path.resolve(source);
67
- delete require.cache[filename];
68
-
69
- const dataFn = require(filename);
70
-
71
- if (typeof dataFn !== 'function') {
72
- throw new Error('The database is a JavaScript file but the export is not a function.');
73
- } // Run dataFn to generate data
74
-
75
-
76
- const data = dataFn();
77
- resolve(low(new Memory()).setState(data));
78
- } else {
79
- throw new Error(`Unsupported source ${source}`);
80
- }
81
- });
82
- };
@@ -1,10 +0,0 @@
1
- "use strict";
2
-
3
- const bodyParser = require('body-parser');
4
-
5
- module.exports = [bodyParser.json({
6
- limit: '10mb',
7
- extended: false
8
- }), bodyParser.urlencoded({
9
- extended: false
10
- })];
@@ -1,80 +0,0 @@
1
- "use strict";
2
-
3
- const fs = require('fs');
4
-
5
- const path = require('path');
6
-
7
- const express = require('express');
8
-
9
- const logger = require('morgan');
10
-
11
- const cors = require('cors');
12
-
13
- const compression = require('compression');
14
-
15
- const errorhandler = require('errorhandler');
16
-
17
- const bodyParser = require('./body-parser');
18
-
19
- module.exports = function (opts) {
20
- const userDir = path.join(process.cwd(), 'public');
21
- const defaultDir = path.join(__dirname, '../../public');
22
- const staticDir = fs.existsSync(userDir) ? userDir : defaultDir;
23
- opts = Object.assign({
24
- logger: true,
25
- static: staticDir
26
- }, opts);
27
- const arr = []; // Compress all requests
28
-
29
- if (!opts.noGzip) {
30
- arr.push(compression());
31
- } // Enable CORS for all the requests, including static files
32
-
33
-
34
- if (!opts.noCors) {
35
- arr.push(cors({
36
- origin: true,
37
- credentials: true
38
- }));
39
- }
40
-
41
- if (process.env.NODE_ENV === 'development') {
42
- // only use in development
43
- arr.push(errorhandler());
44
- } // Serve static files
45
-
46
-
47
- arr.push(express.static(opts.static)); // Logger
48
-
49
- if (opts.logger) {
50
- arr.push(logger('dev', {
51
- skip: req => process.env.NODE_ENV === 'test' || req.path === '/favicon.ico'
52
- }));
53
- } // No cache for IE
54
- // https://support.microsoft.com/en-us/kb/234067
55
-
56
-
57
- arr.push((req, res, next) => {
58
- res.header('Cache-Control', 'no-cache');
59
- res.header('Pragma', 'no-cache');
60
- res.header('Expires', '-1');
61
- next();
62
- }); // Read-only
63
-
64
- if (opts.readOnly) {
65
- arr.push((req, res, next) => {
66
- if (req.method === 'GET') {
67
- next(); // Continue
68
- } else {
69
- res.sendStatus(403); // Forbidden
70
- }
71
- });
72
- } // Add middlewares
73
-
74
-
75
- if (opts.bodyParser) {
76
- arr.push(bodyParser);
77
- }
78
-
79
- return arr;
80
- };
@@ -1,11 +0,0 @@
1
- "use strict";
2
-
3
- const express = require('express');
4
-
5
- module.exports = {
6
- create: () => express().set('json spaces', 2),
7
- defaults: require('./defaults'),
8
- router: require('./router'),
9
- rewriter: require('./rewriter'),
10
- bodyParser: require('./body-parser')
11
- };