huxy-node-server 1.0.3 → 1.0.4

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