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 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
- // Parse args
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 Show this message
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
- // Handle --watch
61
- if (values.watch) {
62
- console.log(chalk.yellow('--watch/-w can be omitted, JSON Server 1+ watches for file changes by default'));
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
- // App args and options
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: values.static });
115
+ const app = createApp(db, { logger: false, static: staticArr });
88
116
  function logRoutes(data) {
89
- console.log([
90
- chalk.bold('Endpoints:'),
91
- ...Object.keys(data).map((key) => `${chalk.gray(`http://${host}:${port}/`)}${chalk.blue(key)}`),
92
- ].join('\n'));
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.16",
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.10.7",
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 (* ^ω^)</strong>
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">GitHub</span>
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
  <% } %>