json-server 1.0.0-alpha.16 → 1.0.0-alpha.18
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/lib/bin.js +86 -54
- package/package.json +5 -2
- package/public/output.css +37 -0
- package/views/index.html +4 -3
package/lib/bin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
3
|
import { extname, join } from 'node:path';
|
|
4
4
|
import { parseArgs } from 'node:util';
|
|
5
5
|
import chalk from 'chalk';
|
|
@@ -9,66 +9,94 @@ import { Low } from 'lowdb';
|
|
|
9
9
|
import { DataFile, JSONFile } from 'lowdb/node';
|
|
10
10
|
import { createApp } from './app.js';
|
|
11
11
|
import { Observer } from './observer.js';
|
|
12
|
-
|
|
13
|
-
const { values, positionals } = parseArgs({
|
|
14
|
-
args: process.argv.slice(2),
|
|
15
|
-
options: {
|
|
16
|
-
port: {
|
|
17
|
-
type: 'string',
|
|
18
|
-
short: 'p',
|
|
19
|
-
},
|
|
20
|
-
host: {
|
|
21
|
-
type: 'string',
|
|
22
|
-
short: 'h',
|
|
23
|
-
},
|
|
24
|
-
static: {
|
|
25
|
-
type: 'string',
|
|
26
|
-
short: 's',
|
|
27
|
-
multiple: true,
|
|
28
|
-
},
|
|
29
|
-
help: {
|
|
30
|
-
type: 'boolean',
|
|
31
|
-
},
|
|
32
|
-
version: {
|
|
33
|
-
type: 'boolean',
|
|
34
|
-
},
|
|
35
|
-
// Deprecated
|
|
36
|
-
watch: {
|
|
37
|
-
type: 'boolean',
|
|
38
|
-
short: 'w',
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
allowPositionals: true,
|
|
42
|
-
});
|
|
43
|
-
// --help
|
|
44
|
-
if (values.help || positionals.length === 0) {
|
|
12
|
+
function help() {
|
|
45
13
|
console.log(`Usage: json-server [options] <file>
|
|
14
|
+
|
|
46
15
|
Options:
|
|
47
16
|
-p, --port <port> Port (default: 3000)
|
|
48
17
|
-h, --host <host> Host (default: localhost)
|
|
49
18
|
-s, --static <dir> Static files directory (multiple allowed)
|
|
50
|
-
--help
|
|
19
|
+
--help Show this message
|
|
20
|
+
--version Show version number
|
|
51
21
|
`);
|
|
52
|
-
process.exit();
|
|
53
|
-
}
|
|
54
|
-
// --version
|
|
55
|
-
if (values.version) {
|
|
56
|
-
const pkg = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf8'));
|
|
57
|
-
console.log(pkg.version);
|
|
58
|
-
process.exit();
|
|
59
22
|
}
|
|
60
|
-
//
|
|
61
|
-
|
|
62
|
-
|
|
23
|
+
// Parse args
|
|
24
|
+
function args() {
|
|
25
|
+
try {
|
|
26
|
+
const { values, positionals } = parseArgs({
|
|
27
|
+
options: {
|
|
28
|
+
port: {
|
|
29
|
+
type: 'string',
|
|
30
|
+
short: 'p',
|
|
31
|
+
default: process.env['PORT'] ?? '3000',
|
|
32
|
+
},
|
|
33
|
+
host: {
|
|
34
|
+
type: 'string',
|
|
35
|
+
short: 'h',
|
|
36
|
+
default: process.env['HOST'] ?? 'localhost',
|
|
37
|
+
},
|
|
38
|
+
static: {
|
|
39
|
+
type: 'string',
|
|
40
|
+
short: 's',
|
|
41
|
+
multiple: true,
|
|
42
|
+
default: [],
|
|
43
|
+
},
|
|
44
|
+
help: {
|
|
45
|
+
type: 'boolean',
|
|
46
|
+
},
|
|
47
|
+
version: {
|
|
48
|
+
type: 'boolean',
|
|
49
|
+
},
|
|
50
|
+
// Deprecated
|
|
51
|
+
watch: {
|
|
52
|
+
type: 'boolean',
|
|
53
|
+
short: 'w',
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
allowPositionals: true,
|
|
57
|
+
});
|
|
58
|
+
// --version
|
|
59
|
+
if (values.version) {
|
|
60
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf8'));
|
|
61
|
+
console.log(pkg.version);
|
|
62
|
+
process.exit();
|
|
63
|
+
}
|
|
64
|
+
// Handle --watch
|
|
65
|
+
if (values.watch) {
|
|
66
|
+
console.log(chalk.yellow('--watch/-w can be omitted, JSON Server 1+ watches for file changes by default'));
|
|
67
|
+
}
|
|
68
|
+
if (values.help || positionals.length === 0) {
|
|
69
|
+
help();
|
|
70
|
+
process.exit();
|
|
71
|
+
}
|
|
72
|
+
// App args and options
|
|
73
|
+
return {
|
|
74
|
+
file: positionals[0] ?? '',
|
|
75
|
+
port: parseInt(values.port),
|
|
76
|
+
host: values.host,
|
|
77
|
+
static: values.static,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
catch (e) {
|
|
81
|
+
if (e.code === 'ERR_PARSE_ARGS_UNKNOWN_OPTION') {
|
|
82
|
+
console.log(chalk.red(e.message.split('.')[0]));
|
|
83
|
+
help();
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
throw e;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
63
90
|
}
|
|
64
|
-
|
|
65
|
-
const file = positionals[0] ?? '';
|
|
66
|
-
const port = parseInt(values.port ?? process.env['PORT'] ?? '3000');
|
|
67
|
-
const host = values.host ?? process.env['HOST'] ?? 'localhost';
|
|
91
|
+
const { file, port, host, static: staticArr } = args();
|
|
68
92
|
if (!existsSync(file)) {
|
|
69
93
|
console.log(chalk.red(`File ${file} not found`));
|
|
70
94
|
process.exit(1);
|
|
71
95
|
}
|
|
96
|
+
// Handle empty string JSON file
|
|
97
|
+
if (readFileSync(file, 'utf-8').trim() === '') {
|
|
98
|
+
writeFileSync(file, '{}');
|
|
99
|
+
}
|
|
72
100
|
// Set up database
|
|
73
101
|
let adapter;
|
|
74
102
|
if (extname(file) === '.json5') {
|
|
@@ -84,12 +112,16 @@ const observer = new Observer(adapter);
|
|
|
84
112
|
const db = new Low(observer, {});
|
|
85
113
|
await db.read();
|
|
86
114
|
// Create app
|
|
87
|
-
const app = createApp(db, { logger: false, static:
|
|
115
|
+
const app = createApp(db, { logger: false, static: staticArr });
|
|
88
116
|
function logRoutes(data) {
|
|
89
|
-
console.log(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
117
|
+
console.log(chalk.bold('Endpoints:'));
|
|
118
|
+
if (Object.keys(data).length === 0) {
|
|
119
|
+
console.log(chalk.gray(`No endpoints found, try adding some data to ${file}`));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
console.log(Object.keys(data)
|
|
123
|
+
.map((key) => `${chalk.gray(`http://${host}:${port}/`)}${chalk.blue(key)}`)
|
|
124
|
+
.join('\n'));
|
|
93
125
|
}
|
|
94
126
|
const kaomojis = ['♡⸜(˶˃ ᵕ ˂˶)⸝♡', '♡( ◡‿◡ )', '( ˶ˆ ᗜ ˆ˵ )', '(˶ᵔ ᵕ ᵔ˶)'];
|
|
95
127
|
function randomItem(items) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "json-server",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.18",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
"public",
|
|
13
13
|
"views"
|
|
14
14
|
],
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=18.3"
|
|
17
|
+
},
|
|
15
18
|
"scripts": {
|
|
16
19
|
"css": "tailwindcss -i ./views/input.css -o ./public/output.css",
|
|
17
20
|
"watch-ts": "tsx watch src/bin.ts fixtures/db.json",
|
|
@@ -29,7 +32,7 @@
|
|
|
29
32
|
"devDependencies": {
|
|
30
33
|
"@sindresorhus/tsconfig": "^5.0.0",
|
|
31
34
|
"@tailwindcss/typography": "^0.5.10",
|
|
32
|
-
"@types/node": "^20.
|
|
35
|
+
"@types/node": "^20.11.0",
|
|
33
36
|
"@typicode/eslint-config": "^1.2.0",
|
|
34
37
|
"concurrently": "^8.2.2",
|
|
35
38
|
"get-port": "^7.0.0",
|
package/public/output.css
CHANGED
|
@@ -1116,6 +1116,30 @@ video {
|
|
|
1116
1116
|
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
|
1117
1117
|
}
|
|
1118
1118
|
|
|
1119
|
+
.bg-gradient-to-r {
|
|
1120
|
+
background-image: linear-gradient(to right, var(--tw-gradient-stops));
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
.from-purple-500 {
|
|
1124
|
+
--tw-gradient-from: #a855f7 var(--tw-gradient-from-position);
|
|
1125
|
+
--tw-gradient-to: rgb(168 85 247 / 0) var(--tw-gradient-to-position);
|
|
1126
|
+
--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
.via-pink-500 {
|
|
1130
|
+
--tw-gradient-to: rgb(236 72 153 / 0) var(--tw-gradient-to-position);
|
|
1131
|
+
--tw-gradient-stops: var(--tw-gradient-from), #ec4899 var(--tw-gradient-via-position), var(--tw-gradient-to);
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
.to-red-500 {
|
|
1135
|
+
--tw-gradient-to: #ef4444 var(--tw-gradient-to-position);
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
.bg-clip-text {
|
|
1139
|
+
-webkit-background-clip: text;
|
|
1140
|
+
background-clip: text;
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1119
1143
|
.py-1 {
|
|
1120
1144
|
padding-top: 0.25rem;
|
|
1121
1145
|
padding-bottom: 0.25rem;
|
|
@@ -1125,16 +1149,29 @@ video {
|
|
|
1125
1149
|
padding-top: 1.5rem;
|
|
1126
1150
|
}
|
|
1127
1151
|
|
|
1152
|
+
.font-semibold {
|
|
1153
|
+
font-weight: 600;
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1128
1156
|
.text-gray-500 {
|
|
1129
1157
|
--tw-text-opacity: 1;
|
|
1130
1158
|
color: rgb(107 114 128 / var(--tw-text-opacity));
|
|
1131
1159
|
}
|
|
1132
1160
|
|
|
1161
|
+
.text-red-500 {
|
|
1162
|
+
--tw-text-opacity: 1;
|
|
1163
|
+
color: rgb(239 68 68 / var(--tw-text-opacity));
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1133
1166
|
.text-slate-900 {
|
|
1134
1167
|
--tw-text-opacity: 1;
|
|
1135
1168
|
color: rgb(15 23 42 / var(--tw-text-opacity));
|
|
1136
1169
|
}
|
|
1137
1170
|
|
|
1171
|
+
.text-transparent {
|
|
1172
|
+
color: transparent;
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1138
1175
|
@media (prefers-color-scheme: dark) {
|
|
1139
1176
|
.dark\:prose-invert {
|
|
1140
1177
|
--tw-prose-body: var(--tw-prose-invert-body);
|
package/views/index.html
CHANGED
|
@@ -10,18 +10,19 @@
|
|
|
10
10
|
<body class="container mx-auto prose dark:prose-invert dark:bg-slate-900 pt-6 bg-white text-slate-900">
|
|
11
11
|
<header>
|
|
12
12
|
<nav class="mx-auto flex items-center justify-between">
|
|
13
|
-
<strong>JSON Server
|
|
13
|
+
<strong>JSON Server</strong>
|
|
14
14
|
<div class="flex gap-x-6">
|
|
15
15
|
<a href="https://github.com/typicode/json-server">
|
|
16
|
-
<span class="ml-2">
|
|
16
|
+
<span class="ml-2">Docs</span>
|
|
17
17
|
</a>
|
|
18
|
-
<a href="https://github.com/sponsors/typicode">
|
|
18
|
+
<a href="https://github.com/sponsors/typicode" class="text-red-500 font-semibold">
|
|
19
19
|
<span class="ml-2">♡ Sponsor</span>
|
|
20
20
|
</a>
|
|
21
21
|
</div>
|
|
22
22
|
</nav>
|
|
23
23
|
</header>
|
|
24
24
|
<main class="my-12">
|
|
25
|
+
<p class="bg-gradient-to-r from-purple-500 via-pink-500 to-red-500 text-transparent bg-clip-text">✧*。٩(ˊᗜˋ*)و✧*。</p>
|
|
25
26
|
<% if (Object.keys(it.data).length === 0) { %>
|
|
26
27
|
<p>No resources found in JSON file</p>
|
|
27
28
|
<% } %>
|