huxy-node-server 1.0.8 → 1.0.10

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.
Files changed (3) hide show
  1. package/example.js +6 -6
  2. package/package.json +1 -1
  3. package/src/index.js +149 -146
package/example.js CHANGED
@@ -1,16 +1,15 @@
1
- import {startServer, startStatic, logger, createLogger, dateTime} from './src/index.js';
2
-
3
- logger.info(dateTime());
1
+ import {startServer, startStatic, createLogger, dateTime} from './src/index.js';
4
2
 
5
3
  const testLogger = createLogger('test');
6
4
 
7
- testLogger.info({x: 123}, '测试');
8
- logger.error({status: 400}, 'HTTP请求错误');
5
+ testLogger.info({x: 123}, dateTime());
6
+ testLogger.error({status: 400}, '测试');
9
7
 
10
8
  // startServer
11
9
  const {app, config, httpServer} = await startServer({
12
10
  port: 8080,
13
11
  host: 'localhost',
12
+ appName: '测试Demo',
14
13
  // ...
15
14
  }, (config, app, httpServer, logger) => {
16
15
  app.get('/config', (req, res) => {
@@ -31,11 +30,12 @@ const huxyServer = await startStatic({
31
30
  port: 9000,
32
31
  basepath: '/',
33
32
  buildPath: './build',
33
+ httpLogger: console,
34
34
  // ssl: {
35
35
  // key: '/path/to/name.key',
36
36
  // cert: '/path/to/name.pem',
37
37
  // },
38
- }, (config, app) => {
38
+ }, (config, app, httpServer, logger) => {
39
39
  logger.info(config);
40
40
  });
41
41
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "huxy-node-server",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "一个精炼、高性能的 Express.js 服务器模板,为现代 Node.js 应用程序设计,提供灵活的功能和最佳实践。",
5
5
  "type": "module",
6
6
  "module": "./src/index.js",
package/src/index.js CHANGED
@@ -3,29 +3,28 @@ import B from 'helmet';
3
3
  import X from 'cors';
4
4
  import {rateLimit as Q, ipKeyGenerator as J} from 'express-rate-limit';
5
5
  import Y from 'compression';
6
- import Z from 'pino-http';
7
6
  import {createServer as C} from 'node:http';
8
- import q from 'node:https';
7
+ import Z from 'node:https';
9
8
  import b from 'pino';
10
9
  import j from 'node:os';
11
10
  import G from 'node:net';
12
- var c = (e = new Date()) => e.toLocaleString('zh-CN', {timeZone: 'Asia/Shanghai', hour12: !1}),
13
- w = e => Object.prototype.toString.call(e).slice(8, -1).toLowerCase(),
14
- g = e => {
15
- let r = e ? 'https' : 'http',
16
- o = j.networkInterfaces(),
17
- t = [];
18
- return (Object.keys(o).map(n => t.push(...o[n])), t.filter(n => n.family === 'IPv4').map(n => n.address));
11
+ var m = (t = new Date()) => t.toLocaleString('zh-CN', {timeZone: 'Asia/Shanghai', hour12: !1}),
12
+ w = t => Object.prototype.toString.call(t).slice(8, -1).toLowerCase(),
13
+ h = t => {
14
+ let r = t ? 'https' : 'http',
15
+ e = j.networkInterfaces(),
16
+ o = [];
17
+ return (Object.keys(e).map(n => o.push(...e[n])), o.filter(n => n.family === 'IPv4').map(n => n.address));
19
18
  },
20
- y = e => {
21
- let r = e ?? process.argv.slice(2) ?? [],
22
- o = {};
19
+ y = t => {
20
+ let r = t ?? process.argv.slice(2) ?? [],
21
+ e = {};
23
22
  return (
24
- r.map(t => {
25
- let [s, n] = t.split('=');
26
- o[s] = n;
23
+ r.map(o => {
24
+ let [s, n] = o.split('=');
25
+ e[s] = n;
27
26
  }),
28
- o
27
+ e
29
28
  );
30
29
  },
31
30
  F = {
@@ -42,67 +41,67 @@ var c = (e = new Date()) => e.toLocaleString('zh-CN', {timeZone: 'Asia/Shanghai'
42
41
  JWT_SECRET: 'secret',
43
42
  AUTH_TOKEN: 'authToken',
44
43
  },
45
- V = (e, r, o) => {
46
- let [t, s] = e.split('.');
47
- t && s ? (o[t] || (o[t] = {}), (o[t][s] = r)) : (o[t] = r);
44
+ V = (t, r, e) => {
45
+ let [o, s] = t.split('.');
46
+ o && s ? (e[o] || (e[o] = {}), (e[o][s] = r)) : (e[o] = r);
48
47
  },
49
- v = (e = {}, r = F) => {
50
- let {env: o} = process;
48
+ v = (t = {}, r = F) => {
49
+ let {env: e} = process;
51
50
  Object.keys(r).map(s => {
52
- let n = o[s] ?? e[s];
53
- n && V(r[s], n, e);
51
+ let n = e[s] ?? t[s];
52
+ n && V(r[s], n, t);
54
53
  });
55
- let t = {...e, ...y()};
56
- return ((t.port = t.staticPort || t.port), (t.isDev = t.nodeEnv === 'development'), (t.protocol = 'http'), t);
54
+ let o = {...t, ...y()};
55
+ return ((o.port = o.staticPort || o.port), (o.isDev = o.nodeEnv === 'development'), (o.protocol = 'http'), o);
57
56
  },
58
- x = (e, r = '127.0.0.1') =>
59
- new Promise(o => {
60
- let t = G.createServer();
61
- (t.once('error', s => {
62
- (t.close(), o((s.code === 'EADDRINUSE', !1)));
57
+ x = (t, r = '127.0.0.1') =>
58
+ new Promise(e => {
59
+ let o = G.createServer();
60
+ (o.once('error', s => {
61
+ (o.close(), e((s.code === 'EADDRINUSE', !1)));
63
62
  }),
64
- t.once('listening', () => {
65
- (t.close(), o(!0));
63
+ o.once('listening', () => {
64
+ (o.close(), e(!0));
66
65
  }),
67
- t.listen(Number(e), r));
66
+ o.listen(Number(t), r));
68
67
  }),
69
- A = (e, r = {}, o) => {
70
- let t = s => {
71
- (o.warn(`\u6536\u5230 ${s} \u4FE1\u53F7, \u{1F6D1} \u6B63\u5728\u5173\u95ED\u670D\u52A1\u5668...`),
72
- e.close(async () => {
73
- (o.info('\u{1F44B} \u670D\u52A1\u5668\u5DF2\u5173\u95ED'), await r.shutdown?.(), process.exit(0));
68
+ A = (t, r = {}, e) => {
69
+ let o = s => {
70
+ (e.warn(`\u6536\u5230 ${s} \u4FE1\u53F7, \u{1F6D1} \u6B63\u5728\u5173\u95ED\u670D\u52A1\u5668...`),
71
+ t.close(async () => {
72
+ (e.info('\u{1F44B} \u670D\u52A1\u5668\u5DF2\u5173\u95ED'), await r.shutdown?.(), process.exit(0));
74
73
  }),
75
74
  setTimeout(() => {
76
- (o.error('\u274C \u5F3A\u5236\u5173\u95ED\u670D\u52A1\u5668'), process.exit(1));
75
+ (e.error('\u274C \u5F3A\u5236\u5173\u95ED\u670D\u52A1\u5668'), process.exit(1));
77
76
  }, 5e3));
78
77
  };
79
- (process.on('SIGTERM', () => t('SIGTERM')),
80
- process.on('SIGINT', () => t('SIGINT')),
78
+ (process.on('SIGTERM', () => o('SIGTERM')),
79
+ process.on('SIGINT', () => o('SIGINT')),
81
80
  process.on('uncaughtException', s => {
82
- (o.fatal(s, `\u{1F4A5} \u672A\u6355\u83B7\u7684\u5F02\u5E38: ${s.message}`), process.exit(1));
81
+ (e.fatal(s, `\u{1F4A5} \u672A\u6355\u83B7\u7684\u5F02\u5E38: ${s.message}`), process.exit(1));
83
82
  }),
84
83
  process.on('unhandledRejection', (s, n) => {
85
- (o.fatal({reason: s, promise: n}, '\u26A0\uFE0F \u672A\u5904\u7406\u7684 Promise \u62D2\u7EDD'), process.exit(1));
84
+ (e.fatal({reason: s, promise: n}, '\u26A0\uFE0F \u672A\u5904\u7406\u7684 Promise \u62D2\u7EDD'), process.exit(1));
86
85
  }));
87
86
  },
88
- $ = (e, {port: r, host: o = '0.0.0.0'} = {}) =>
89
- new Promise((t, s) => {
90
- let n = a => {
91
- (p(), s(a));
87
+ $ = (t, {port: r, host: e = '0.0.0.0'} = {}) =>
88
+ new Promise((o, s) => {
89
+ let n = c => {
90
+ (a(), s(c));
92
91
  },
93
92
  i = () => {
94
- (p(), t(e));
93
+ (a(), o(t));
95
94
  },
96
- p = () => {
97
- (e.off('error', n), e.off('listening', i));
95
+ a = () => {
96
+ (t.off('error', n), t.off('listening', i));
98
97
  };
99
- (e.once('error', n), e.once('listening', i), e.listen(r, o));
98
+ (t.once('error', n), t.once('listening', i), t.listen(r, e));
100
99
  }),
101
- R = (e, r = 56) => {
102
- let o = e.length,
103
- t = r - o,
104
- s = ~~(t / 2);
105
- return `${'-'.repeat(s)}${e}${'-'.repeat(t - s)}`;
100
+ R = (t, r = 56) => {
101
+ let e = t.length,
102
+ o = r - e,
103
+ s = ~~(o / 2);
104
+ return `${'-'.repeat(s)}${t}${'-'.repeat(o - s)}`;
106
105
  };
107
106
  import 'dotenv';
108
107
  var W = {
@@ -125,138 +124,142 @@ var W = {
125
124
  logLevel: process.env.LOG_LEVEL || 30,
126
125
  },
127
126
  S = W;
128
- var f = (e, {transportOpt: r, ...o} = {}) =>
127
+ var u = (t, {transportOpt: r, ...e} = {}) =>
129
128
  b({
130
- name: e,
129
+ name: t,
131
130
  level: S.logLevel,
132
- formatters: {level: t => ({level: t})},
131
+ formatters: {level: o => ({level: o})},
133
132
  timestamp: b.stdTimeFunctions.isoTime,
134
133
  base: null,
135
134
  transport: {target: 'pino-pretty', options: {colorize: !0, levelFirst: !0, ...r}, ignore: 'pid,hostname,level,time', translateTime: 'SYS:yyyy-mm-dd HH:MM:ss'},
136
- ...o,
135
+ ...e,
137
136
  });
138
- var h = f;
139
- var O = f('error-handler'),
140
- N = e => (r, o, t) => {
141
- (O.error({message: 'Not Found', timestamp: c(), url: r.originalUrl, method: r.method, ip: r.ip, userAgent: r.get('User-Agent')}, '\u627E\u4E0D\u5230\u8DEF\u5F84'),
142
- o.status(404).json({success: !1, status: 404, url: r.originalUrl, message: `\u8DEF\u7531 [${r.method} ${r.originalUrl}] \u4E0D\u5B58\u5728`, timestamp: c()}));
137
+ var f = u;
138
+ var O = u('error-handler'),
139
+ N = t => (r, e, o) => {
140
+ (O.error({message: 'Not Found', timestamp: m(), url: r.originalUrl, method: r.method, ip: r.ip, userAgent: r.get('User-Agent')}, '\u627E\u4E0D\u5230\u8DEF\u5F84'),
141
+ e.status(404).json({success: !1, status: 404, url: r.originalUrl, message: `\u8DEF\u7531 [${r.method} ${r.originalUrl}] \u4E0D\u5B58\u5728`, timestamp: m()}));
143
142
  },
144
- _ = e => (r, o, t, s) => {
143
+ _ = t => (r, e, o, s) => {
145
144
  let n = r.status || 500,
146
145
  i = r.message;
147
- (O.error({message: i, timestamp: c(), stack: r.stack, url: o.originalUrl, method: o.method, ip: o.ip, userAgent: o.get('User-Agent')}, '\u670D\u52A1\u5668\u5185\u90E8\u9519\u8BEF'),
148
- t.status(n).json({success: !1, message: (e.isDev, i), stack: e.isDev ? r.stack : void 0, timestamp: c()}));
146
+ (O.error({message: i, timestamp: m(), stack: r.stack, url: e.originalUrl, method: e.method, ip: e.ip, userAgent: e.get('User-Agent')}, '\u670D\u52A1\u5668\u5185\u90E8\u9519\u8BEF'),
147
+ o.status(n).json({success: !1, message: (t.isDev, i), stack: t.isDev ? r.stack : void 0, timestamp: m()}));
149
148
  };
150
149
  import {Router as K} from 'express';
151
- var z = e => {
150
+ var z = t => {
152
151
  let r = K();
153
152
  return (
154
- r.use('/health', (o, t) => {
155
- t.status(200).json({status: 'OK', timestamp: c(), environment: e.nodeEnv, uptime: process.uptime(), memoryUsage: process.memoryUsage(), pid: process.pid});
153
+ r.use('/health', (e, o) => {
154
+ o.status(200).json({status: 'OK', timestamp: m(), environment: t.nodeEnv, uptime: process.uptime(), memoryUsage: process.memoryUsage(), pid: process.pid});
156
155
  }),
157
- r.get('/', (o, t) => {
158
- t.status(200).json({message: 'Node.js \u670D\u52A1\u5668\u8FD0\u884C\u4E2D', timestamp: c(), environment: e.nodeEnv});
156
+ r.get('/', (e, o) => {
157
+ o.status(200).json({message: 'Node.js \u670D\u52A1\u5668\u8FD0\u884C\u4E2D', timestamp: m(), environment: t.nodeEnv});
159
158
  }),
160
159
  r
161
160
  );
162
161
  },
163
162
  M = z;
164
- var ee = (e, r = {}, o) => {
165
- (e.disable('x-powered-by'),
166
- e.set('trust proxy', r.trustProxy ?? 1),
167
- e.use(Z({logger: o, quietReqLogger: !0, autoLogging: !1, genReqId: !1})),
168
- e.use(Y()),
169
- e.use(B(r.helmet)),
170
- e.use(X(r.cors)),
171
- e.use(r.apiPrefix, Q({keyGenerator: t => J(t.ip) || t.headers['x-huxy-auth'] || t.headers['x-api-key'] || t.headers.authorization, ...r.rateLimit})),
172
- e.use(L.json({limit: '20mb'})),
173
- e.use(L.urlencoded({extended: !0, limit: '20mb'})));
163
+ var q = async (t, r = {}) => {
164
+ if ((t.disable('x-powered-by'), t.set('trust proxy', r.trustProxy ?? 1), r.httpLogger))
165
+ t.use((e, o, s) => {
166
+ e.log = r.httpLogger;
167
+ });
168
+ else {
169
+ let e = (await import('pino-http')).default;
170
+ t.use(e({logger: f('http-request', r.loggerConfig), quietReqLogger: !0, autoLogging: !1, genReqId: !1}));
171
+ }
172
+ (t.use(Y()),
173
+ t.use(B(r.helmet)),
174
+ t.use(X(r.cors)),
175
+ t.use(r.apiPrefix, Q({keyGenerator: e => J(e.ip) || e.headers['x-huxy-auth'] || e.headers['x-api-key'] || e.headers.authorization, ...r.rateLimit})),
176
+ t.use(L.json({limit: '20mb'})),
177
+ t.use(L.urlencoded({extended: !0, limit: '20mb'})));
174
178
  },
175
- te = (e, r = {}) => {
176
- (e.use(M(r)), e.use(N(r)), e.use(_(r)));
179
+ ee = (t, r = {}) => {
180
+ (t.use(M(r)), t.use(N(r)), t.use(_(r)));
177
181
  },
178
- oe = async (e = {}, r) => {
179
- let o = h(e.loggerName || 'huxy', e.loggerConfig),
180
- t = h('http-request', e.loggerConfig),
181
- s = v(e),
182
- {port: n, ssl: i} = s;
183
- (await x(n, s.host)) || ((s.port = Number(n) + 1), o.warn(`\u7AEF\u53E3 ${n} \u5DF2\u88AB\u5360\u7528\uFF0C\u73B0\u5728\u4F7F\u7528\u7AEF\u53E3 ${s.port}`));
182
+ te = async (t = {}, r) => {
183
+ let e = v(t),
184
+ o = e.logger ?? f(e.loggerName || 'huxy', e.loggerConfig),
185
+ {port: s, ssl: n} = e;
186
+ (await x(s, e.host)) || ((e.port = Number(s) + 1), o.warn(`\u7AEF\u53E3 ${s} \u5DF2\u88AB\u5360\u7528\uFF0C\u73B0\u5728\u4F7F\u7528\u7AEF\u53E3 ${e.port}`));
184
187
  let a = L();
185
- ee(a, s, t);
186
- let l;
187
- (i
188
- ? (w(i) === 'object' ||
188
+ await q(a, e);
189
+ let c;
190
+ (n
191
+ ? (w(n) === 'object' ||
189
192
  (o.error({ssl: {key: '/path/to/name.key', cert: '/path/to/name.pem'}}, '\u26A0\uFE0F \u8BF7\u8BBE\u7F6E\u6709\u6548 SSL \u6216\u8BBE\u7F6E {ssl: false}'), process.exit(1)),
190
- (s.protocol = 'https'),
191
- (l = q.createServer(i, a)),
192
- C((d, u) => {
193
- (u.writeHead(301, {Location: `${s.protocol}://${d.headers.host}${d.url}`}), u.end());
193
+ (e.protocol = 'https'),
194
+ (c = Z.createServer(n, a)),
195
+ C((l, d) => {
196
+ (d.writeHead(301, {Location: `${e.protocol}://${l.headers.host}${l.url}`}), d.end());
194
197
  }).listen(80))
195
- : (l = C(a)),
196
- A(l, s, o));
198
+ : (c = C(a)),
199
+ A(c, e, o));
197
200
  try {
198
- await $(l, s);
199
- } catch (m) {
200
- (o.error({err: m}, '\u26A0\uFE0F \u670D\u52A1\u5668\u542F\u52A8\u5931\u8D25'), process.exit(1));
201
+ await $(c, e);
202
+ } catch (p) {
203
+ (o.error({err: p}, '\u26A0\uFE0F \u670D\u52A1\u5668\u542F\u52A8\u5931\u8D25'), process.exit(1));
201
204
  }
202
205
  try {
203
- await r?.(s, a, l, o);
204
- } catch (m) {
205
- (o.error({err: m}, `\u274C \u56DE\u8C03\u51FD\u6570\u9519\u8BEF\uFF1A${m.message}`), process.exit(1));
206
+ await r?.(e, a, c, o);
207
+ } catch (p) {
208
+ (o.error({err: p}, `\u274C \u56DE\u8C03\u51FD\u6570\u9519\u8BEF\uFF1A${p.message}`), process.exit(1));
206
209
  }
207
- return (te(a, s), {app: a, httpServer: l, config: s, logger: o});
210
+ return (ee(a, e), {app: a, httpServer: c, config: e, logger: o});
208
211
  },
209
- D = oe;
210
- var re = (e, r, o) =>
211
- D({...S, ...e}, async (t, s, n, i) => {
212
- let {port: p, host: a, nodeEnv: l, basepath: m, appName: d = 'HuxyServer', protocol: u} = t;
213
- if (!o) {
214
- let U = g()
215
- .filter(E => E !== a)
216
- .map(E => `${u}://${E}:${p}${m}`);
212
+ D = te;
213
+ var oe = (t, r, e) =>
214
+ D({...S, ...t}, async (o, s, n, i) => {
215
+ let {port: a, host: c, nodeEnv: p, basepath: l, appName: d = 'HuxyServer', protocol: g} = o;
216
+ if (!e) {
217
+ let U = h()
218
+ .filter(E => E !== c)
219
+ .map(E => `${g}://${E}:${a}${l}`);
217
220
  (i.info(R(d)),
218
- i.info(`\u{1F680} \u670D\u52A1\u8FD0\u884C\u5728\u3010${l}\u3011\u73AF\u5883: ${u}://${a}:${p}${m}`),
219
- i.info(`-----------------[${c()}]------------------`),
221
+ i.info(`\u{1F680} \u670D\u52A1\u8FD0\u884C\u5728\u3010${p}\u3011\u73AF\u5883: ${g}://${c}:${a}${l}`),
222
+ i.info(`-----------------[${m()}]------------------`),
220
223
  i.info({ips: U}, '\u672C\u5730\u5730\u5740\uFF1A'));
221
224
  }
222
- await r?.(t, s, n, i);
225
+ await r?.(o, s, n, i);
223
226
  }),
224
- T = re;
225
- import ae from 'express';
226
- import {fileURLToPath as se} from 'node:url';
227
- import {dirname as ne, resolve as ie} from 'node:path';
228
- var P = (e = import.meta.url) => ne(se(e)),
229
- I = (...e) => ie(P(), ...e),
227
+ T = oe;
228
+ import ie from 'express';
229
+ import {fileURLToPath as re} from 'node:url';
230
+ import {dirname as se, resolve as ne} from 'node:path';
231
+ var P = (t = import.meta.url) => se(re(t)),
232
+ I = (...t) => ne(P(), ...t),
230
233
  H = I;
231
- var ce = {port: 9e3, host: 'localhost', basepath: '/', buildPath: './build'},
232
- me = e => (e ? (e.endsWith('/') ? e : `${e}/`) : '/'),
233
- pe = (e, r) =>
234
- T({...ce, ...e}, async (o, t, s, n) => {
235
- await r?.(o, t, s, n);
236
- let {basepath: i, buildPath: p} = o;
234
+ var ae = {port: 9e3, host: 'localhost', basepath: '/', buildPath: './build'},
235
+ ce = t => (t ? (t.endsWith('/') ? t : `${t}/`) : '/'),
236
+ me = (t, r) =>
237
+ T({...ae, ...t}, async (e, o, s, n) => {
238
+ await r?.(e, o, s, n);
239
+ let {basepath: i, buildPath: a} = e;
237
240
  (i !== '/' &&
238
- t.get('/', (m, d, u) => {
239
- if (m.path === '/') return d.redirect(i);
240
- u();
241
+ o.get('/', (l, d, g) => {
242
+ if (l.path === '/') return d.redirect(i);
243
+ g();
241
244
  }),
242
- t.use(i, ae.static(p, {...o.staticCache})));
243
- let a = me(i),
244
- l = new RegExp(`^${a.replace(/\//g, '\\/')}(.*)$`);
245
- t.get(l, (m, d) => {
246
- d.sendFile(H(p, 'index.html'));
245
+ o.use(i, ie.static(a, {...e.staticCache})));
246
+ let c = ce(i),
247
+ p = new RegExp(`^${c.replace(/\//g, '\\/')}(.*)$`);
248
+ o.get(p, (l, d) => {
249
+ d.sendFile(H(a, 'index.html'));
247
250
  });
248
251
  }),
249
- k = pe;
250
- var ot = {startServer: T, startStatic: k, logger: h, createLogger: f, dateTime: c, localIPs: g, nodeArgs: y, getEnvConfig: v, checkPort: x, getDirName: P, resolvePath: I};
252
+ k = me;
253
+ var et = {startServer: T, startStatic: k, logger: f, createLogger: u, dateTime: m, localIPs: h, nodeArgs: y, getEnvConfig: v, checkPort: x, getDirName: P, resolvePath: I};
251
254
  export {
252
255
  x as checkPort,
253
- f as createLogger,
254
- c as dateTime,
255
- ot as default,
256
+ u as createLogger,
257
+ m as dateTime,
258
+ et as default,
256
259
  P as getDirName,
257
260
  v as getEnvConfig,
258
- g as localIPs,
259
- h as logger,
261
+ h as localIPs,
262
+ f as logger,
260
263
  y as nodeArgs,
261
264
  I as resolvePath,
262
265
  T as startServer,