huxy-node-server
Advanced tools
+6
-6
@@ -1,9 +0,7 @@ | ||
| import {startServer, startStatic, logger, createLogger, dateTime} from './src/index.js'; | ||
| import {startServer, startStatic, createLogger, dateTime} from './src/index.js'; | ||
| logger.info(dateTime()); | ||
| const testLogger = createLogger('test'); | ||
| testLogger.info({x: 123}, '测试'); | ||
| logger.error({status: 400}, 'HTTP请求错误'); | ||
| testLogger.info({x: 123}, dateTime()); | ||
| testLogger.error({status: 400}, '测试'); | ||
@@ -14,2 +12,3 @@ // startServer | ||
| host: 'localhost', | ||
| appName: '测试Demo', | ||
| // ... | ||
@@ -35,2 +34,3 @@ }, (config, app, httpServer, logger) => { | ||
| buildPath: './build', | ||
| httpLogger: console, | ||
| // ssl: { | ||
@@ -40,3 +40,3 @@ // key: '/path/to/name.key', | ||
| // }, | ||
| }, (config, app) => { | ||
| }, (config, app, httpServer, logger) => { | ||
| logger.info(config); | ||
@@ -43,0 +43,0 @@ }); |
+1
-1
| { | ||
| "name": "huxy-node-server", | ||
| "version": "1.0.9", | ||
| "version": "1.0.10", | ||
| "description": "一个精炼、高性能的 Express.js 服务器模板,为现代 Node.js 应用程序设计,提供灵活的功能和最佳实践。", | ||
@@ -5,0 +5,0 @@ "type": "module", |
+104
-104
@@ -6,25 +6,24 @@ import L from 'express'; | ||
| import Y from 'compression'; | ||
| import Z from 'pino-http'; | ||
| import {createServer as C} from 'node:http'; | ||
| import q from 'node:https'; | ||
| import Z from 'node:https'; | ||
| import b from 'pino'; | ||
| import j from 'node:os'; | ||
| import G from 'node:net'; | ||
| var m = (e = new Date()) => e.toLocaleString('zh-CN', {timeZone: 'Asia/Shanghai', hour12: !1}), | ||
| w = e => Object.prototype.toString.call(e).slice(8, -1).toLowerCase(), | ||
| h = e => { | ||
| let r = e ? 'https' : 'http', | ||
| t = j.networkInterfaces(), | ||
| var m = (t = new Date()) => t.toLocaleString('zh-CN', {timeZone: 'Asia/Shanghai', hour12: !1}), | ||
| w = t => Object.prototype.toString.call(t).slice(8, -1).toLowerCase(), | ||
| h = t => { | ||
| let r = t ? 'https' : 'http', | ||
| e = j.networkInterfaces(), | ||
| o = []; | ||
| return (Object.keys(t).map(n => o.push(...t[n])), o.filter(n => n.family === 'IPv4').map(n => n.address)); | ||
| return (Object.keys(e).map(n => o.push(...e[n])), o.filter(n => n.family === 'IPv4').map(n => n.address)); | ||
| }, | ||
| y = e => { | ||
| let r = e ?? process.argv.slice(2) ?? [], | ||
| t = {}; | ||
| y = t => { | ||
| let r = t ?? process.argv.slice(2) ?? [], | ||
| e = {}; | ||
| return ( | ||
| r.map(o => { | ||
| let [s, n] = o.split('='); | ||
| t[s] = n; | ||
| e[s] = n; | ||
| }), | ||
| t | ||
| e | ||
| ); | ||
@@ -46,34 +45,34 @@ }, | ||
| }, | ||
| V = (e, r, t) => { | ||
| let [o, s] = e.split('.'); | ||
| o && s ? (t[o] || (t[o] = {}), (t[o][s] = r)) : (t[o] = r); | ||
| V = (t, r, e) => { | ||
| let [o, s] = t.split('.'); | ||
| o && s ? (e[o] || (e[o] = {}), (e[o][s] = r)) : (e[o] = r); | ||
| }, | ||
| v = (e = {}, r = F) => { | ||
| let {env: t} = process; | ||
| v = (t = {}, r = F) => { | ||
| let {env: e} = process; | ||
| Object.keys(r).map(s => { | ||
| let n = t[s] ?? e[s]; | ||
| n && V(r[s], n, e); | ||
| let n = e[s] ?? t[s]; | ||
| n && V(r[s], n, t); | ||
| }); | ||
| let o = {...e, ...y()}; | ||
| let o = {...t, ...y()}; | ||
| return ((o.port = o.staticPort || o.port), (o.isDev = o.nodeEnv === 'development'), (o.protocol = 'http'), o); | ||
| }, | ||
| x = (e, r = '127.0.0.1') => | ||
| new Promise(t => { | ||
| x = (t, r = '127.0.0.1') => | ||
| new Promise(e => { | ||
| let o = G.createServer(); | ||
| (o.once('error', s => { | ||
| (o.close(), t((s.code === 'EADDRINUSE', !1))); | ||
| (o.close(), e((s.code === 'EADDRINUSE', !1))); | ||
| }), | ||
| o.once('listening', () => { | ||
| (o.close(), t(!0)); | ||
| (o.close(), e(!0)); | ||
| }), | ||
| o.listen(Number(e), r)); | ||
| o.listen(Number(t), r)); | ||
| }), | ||
| A = (e, r = {}, t) => { | ||
| A = (t, r = {}, e) => { | ||
| let o = s => { | ||
| (t.warn(`\u6536\u5230 ${s} \u4FE1\u53F7, \u{1F6D1} \u6B63\u5728\u5173\u95ED\u670D\u52A1\u5668...`), | ||
| e.close(async () => { | ||
| (t.info('\u{1F44B} \u670D\u52A1\u5668\u5DF2\u5173\u95ED'), await r.shutdown?.(), process.exit(0)); | ||
| (e.warn(`\u6536\u5230 ${s} \u4FE1\u53F7, \u{1F6D1} \u6B63\u5728\u5173\u95ED\u670D\u52A1\u5668...`), | ||
| t.close(async () => { | ||
| (e.info('\u{1F44B} \u670D\u52A1\u5668\u5DF2\u5173\u95ED'), await r.shutdown?.(), process.exit(0)); | ||
| }), | ||
| setTimeout(() => { | ||
| (t.error('\u274C \u5F3A\u5236\u5173\u95ED\u670D\u52A1\u5668'), process.exit(1)); | ||
| (e.error('\u274C \u5F3A\u5236\u5173\u95ED\u670D\u52A1\u5668'), process.exit(1)); | ||
| }, 5e3)); | ||
@@ -84,9 +83,9 @@ }; | ||
| process.on('uncaughtException', s => { | ||
| (t.fatal(s, `\u{1F4A5} \u672A\u6355\u83B7\u7684\u5F02\u5E38: ${s.message}`), process.exit(1)); | ||
| (e.fatal(s, `\u{1F4A5} \u672A\u6355\u83B7\u7684\u5F02\u5E38: ${s.message}`), process.exit(1)); | ||
| }), | ||
| process.on('unhandledRejection', (s, n) => { | ||
| (t.fatal({reason: s, promise: n}, '\u26A0\uFE0F \u672A\u5904\u7406\u7684 Promise \u62D2\u7EDD'), process.exit(1)); | ||
| (e.fatal({reason: s, promise: n}, '\u26A0\uFE0F \u672A\u5904\u7406\u7684 Promise \u62D2\u7EDD'), process.exit(1)); | ||
| })); | ||
| }, | ||
| $ = (e, {port: r, host: t = '0.0.0.0'} = {}) => | ||
| $ = (t, {port: r, host: e = '0.0.0.0'} = {}) => | ||
| new Promise((o, s) => { | ||
@@ -97,14 +96,14 @@ let n = c => { | ||
| i = () => { | ||
| (a(), o(e)); | ||
| (a(), o(t)); | ||
| }, | ||
| a = () => { | ||
| (e.off('error', n), e.off('listening', i)); | ||
| (t.off('error', n), t.off('listening', i)); | ||
| }; | ||
| (e.once('error', n), e.once('listening', i), e.listen(r, t)); | ||
| (t.once('error', n), t.once('listening', i), t.listen(r, e)); | ||
| }), | ||
| R = (e, r = 56) => { | ||
| let t = e.length, | ||
| o = r - t, | ||
| R = (t, r = 56) => { | ||
| let e = t.length, | ||
| o = r - e, | ||
| s = ~~(o / 2); | ||
| return `${'-'.repeat(s)}${e}${'-'.repeat(o - s)}`; | ||
| return `${'-'.repeat(s)}${t}${'-'.repeat(o - s)}`; | ||
| }; | ||
@@ -132,5 +131,5 @@ import 'dotenv'; | ||
| S = W; | ||
| var u = (e, {transportOpt: r, ...t} = {}) => | ||
| var u = (t, {transportOpt: r, ...e} = {}) => | ||
| b({ | ||
| name: e, | ||
| name: t, | ||
| level: S.logLevel, | ||
@@ -141,25 +140,25 @@ formatters: {level: o => ({level: o})}, | ||
| transport: {target: 'pino-pretty', options: {colorize: !0, levelFirst: !0, ...r}, ignore: 'pid,hostname,level,time', translateTime: 'SYS:yyyy-mm-dd HH:MM:ss'}, | ||
| ...t, | ||
| ...e, | ||
| }); | ||
| var f = u; | ||
| var O = u('error-handler'), | ||
| N = e => (r, t, o) => { | ||
| N = t => (r, e, o) => { | ||
| (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'), | ||
| t.status(404).json({success: !1, status: 404, url: r.originalUrl, message: `\u8DEF\u7531 [${r.method} ${r.originalUrl}] \u4E0D\u5B58\u5728`, timestamp: m()})); | ||
| e.status(404).json({success: !1, status: 404, url: r.originalUrl, message: `\u8DEF\u7531 [${r.method} ${r.originalUrl}] \u4E0D\u5B58\u5728`, timestamp: m()})); | ||
| }, | ||
| _ = e => (r, t, o, s) => { | ||
| _ = t => (r, e, o, s) => { | ||
| let n = r.status || 500, | ||
| i = r.message; | ||
| (O.error({message: i, timestamp: m(), stack: r.stack, url: t.originalUrl, method: t.method, ip: t.ip, userAgent: t.get('User-Agent')}, '\u670D\u52A1\u5668\u5185\u90E8\u9519\u8BEF'), | ||
| o.status(n).json({success: !1, message: (e.isDev, i), stack: e.isDev ? r.stack : void 0, timestamp: m()})); | ||
| (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'), | ||
| o.status(n).json({success: !1, message: (t.isDev, i), stack: t.isDev ? r.stack : void 0, timestamp: m()})); | ||
| }; | ||
| import {Router as K} from 'express'; | ||
| var z = e => { | ||
| var z = t => { | ||
| let r = K(); | ||
| return ( | ||
| r.use('/health', (t, o) => { | ||
| o.status(200).json({status: 'OK', timestamp: m(), environment: e.nodeEnv, uptime: process.uptime(), memoryUsage: process.memoryUsage(), pid: process.pid}); | ||
| r.use('/health', (e, o) => { | ||
| o.status(200).json({status: 'OK', timestamp: m(), environment: t.nodeEnv, uptime: process.uptime(), memoryUsage: process.memoryUsage(), pid: process.pid}); | ||
| }), | ||
| r.get('/', (t, o) => { | ||
| o.status(200).json({message: 'Node.js \u670D\u52A1\u5668\u8FD0\u884C\u4E2D', timestamp: m(), environment: e.nodeEnv}); | ||
| r.get('/', (e, o) => { | ||
| o.status(200).json({message: 'Node.js \u670D\u52A1\u5668\u8FD0\u884C\u4E2D', timestamp: m(), environment: t.nodeEnv}); | ||
| }), | ||
@@ -170,27 +169,28 @@ r | ||
| M = z; | ||
| var ee = (e, r = {}) => { | ||
| (e.disable('x-powered-by'), | ||
| e.set('trust proxy', r.trustProxy ?? 1), | ||
| r.httpLogger | ||
| ? e.use((t, o, s) => { | ||
| t.log = r.httpLogger; | ||
| }) | ||
| : e.use(Z({logger: f('http-request', r.loggerConfig), quietReqLogger: !0, autoLogging: !1, genReqId: !1})), | ||
| e.use(Y()), | ||
| e.use(B(r.helmet)), | ||
| e.use(X(r.cors)), | ||
| 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})), | ||
| e.use(L.json({limit: '20mb'})), | ||
| e.use(L.urlencoded({extended: !0, limit: '20mb'}))); | ||
| var q = async (t, r = {}) => { | ||
| if ((t.disable('x-powered-by'), t.set('trust proxy', r.trustProxy ?? 1), r.httpLogger)) | ||
| t.use((e, o, s) => { | ||
| e.log = r.httpLogger; | ||
| }); | ||
| else { | ||
| let e = (await import('pino-http')).default; | ||
| t.use(e({logger: f('http-request', r.loggerConfig), quietReqLogger: !0, autoLogging: !1, genReqId: !1})); | ||
| } | ||
| (t.use(Y()), | ||
| t.use(B(r.helmet)), | ||
| t.use(X(r.cors)), | ||
| 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})), | ||
| t.use(L.json({limit: '20mb'})), | ||
| t.use(L.urlencoded({extended: !0, limit: '20mb'}))); | ||
| }, | ||
| te = (e, r = {}) => { | ||
| (e.use(M(r)), e.use(N(r)), e.use(_(r))); | ||
| ee = (t, r = {}) => { | ||
| (t.use(M(r)), t.use(N(r)), t.use(_(r))); | ||
| }, | ||
| oe = async (e = {}, r) => { | ||
| let t = v(e), | ||
| o = t.logger ?? f(t.loggerName || 'huxy', t.loggerConfig), | ||
| {port: s, ssl: n} = t; | ||
| (await x(s, t.host)) || ((t.port = Number(s) + 1), o.warn(`\u7AEF\u53E3 ${s} \u5DF2\u88AB\u5360\u7528\uFF0C\u73B0\u5728\u4F7F\u7528\u7AEF\u53E3 ${t.port}`)); | ||
| te = async (t = {}, r) => { | ||
| let e = v(t), | ||
| o = e.logger ?? f(e.loggerName || 'huxy', e.loggerConfig), | ||
| {port: s, ssl: n} = e; | ||
| (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}`)); | ||
| let a = L(); | ||
| ee(a, t); | ||
| await q(a, e); | ||
| let c; | ||
@@ -200,11 +200,11 @@ (n | ||
| (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)), | ||
| (t.protocol = 'https'), | ||
| (c = q.createServer(n, a)), | ||
| (e.protocol = 'https'), | ||
| (c = Z.createServer(n, a)), | ||
| C((l, d) => { | ||
| (d.writeHead(301, {Location: `${t.protocol}://${l.headers.host}${l.url}`}), d.end()); | ||
| (d.writeHead(301, {Location: `${e.protocol}://${l.headers.host}${l.url}`}), d.end()); | ||
| }).listen(80)) | ||
| : (c = C(a)), | ||
| A(c, t, o)); | ||
| A(c, e, o)); | ||
| try { | ||
| await $(c, t); | ||
| await $(c, e); | ||
| } catch (p) { | ||
@@ -214,13 +214,13 @@ (o.error({err: p}, '\u26A0\uFE0F \u670D\u52A1\u5668\u542F\u52A8\u5931\u8D25'), process.exit(1)); | ||
| try { | ||
| await r?.(t, a, c, o); | ||
| await r?.(e, a, c, o); | ||
| } catch (p) { | ||
| (o.error({err: p}, `\u274C \u56DE\u8C03\u51FD\u6570\u9519\u8BEF\uFF1A${p.message}`), process.exit(1)); | ||
| } | ||
| return (te(a, t), {app: a, httpServer: c, config: t, logger: o}); | ||
| return (ee(a, e), {app: a, httpServer: c, config: e, logger: o}); | ||
| }, | ||
| D = oe; | ||
| var re = (e, r, t) => | ||
| D({...S, ...e}, async (o, s, n, i) => { | ||
| D = te; | ||
| var oe = (t, r, e) => | ||
| D({...S, ...t}, async (o, s, n, i) => { | ||
| let {port: a, host: c, nodeEnv: p, basepath: l, appName: d = 'HuxyServer', protocol: g} = o; | ||
| if (!t) { | ||
| if (!e) { | ||
| let U = h() | ||
@@ -236,15 +236,15 @@ .filter(E => E !== c) | ||
| }), | ||
| T = re; | ||
| import ae from 'express'; | ||
| import {fileURLToPath as se} from 'node:url'; | ||
| import {dirname as ne, resolve as ie} from 'node:path'; | ||
| var P = (e = import.meta.url) => ne(se(e)), | ||
| I = (...e) => ie(P(), ...e), | ||
| T = oe; | ||
| import ie from 'express'; | ||
| import {fileURLToPath as re} from 'node:url'; | ||
| import {dirname as se, resolve as ne} from 'node:path'; | ||
| var P = (t = import.meta.url) => se(re(t)), | ||
| I = (...t) => ne(P(), ...t), | ||
| H = I; | ||
| var ce = {port: 9e3, host: 'localhost', basepath: '/', buildPath: './build'}, | ||
| me = e => (e ? (e.endsWith('/') ? e : `${e}/`) : '/'), | ||
| pe = (e, r) => | ||
| T({...ce, ...e}, async (t, o, s, n) => { | ||
| await r?.(t, o, s, n); | ||
| let {basepath: i, buildPath: a} = t; | ||
| var ae = {port: 9e3, host: 'localhost', basepath: '/', buildPath: './build'}, | ||
| ce = t => (t ? (t.endsWith('/') ? t : `${t}/`) : '/'), | ||
| me = (t, r) => | ||
| T({...ae, ...t}, async (e, o, s, n) => { | ||
| await r?.(e, o, s, n); | ||
| let {basepath: i, buildPath: a} = e; | ||
| (i !== '/' && | ||
@@ -255,4 +255,4 @@ o.get('/', (l, d, g) => { | ||
| }), | ||
| o.use(i, ae.static(a, {...t.staticCache}))); | ||
| let c = me(i), | ||
| o.use(i, ie.static(a, {...e.staticCache}))); | ||
| let c = ce(i), | ||
| p = new RegExp(`^${c.replace(/\//g, '\\/')}(.*)$`); | ||
@@ -263,4 +263,4 @@ o.get(p, (l, d) => { | ||
| }), | ||
| k = pe; | ||
| var ot = {startServer: T, startStatic: k, logger: f, createLogger: u, dateTime: m, localIPs: h, nodeArgs: y, getEnvConfig: v, checkPort: x, getDirName: P, resolvePath: I}; | ||
| k = me; | ||
| var et = {startServer: T, startStatic: k, logger: f, createLogger: u, dateTime: m, localIPs: h, nodeArgs: y, getEnvConfig: v, checkPort: x, getDirName: P, resolvePath: I}; | ||
| export { | ||
@@ -270,3 +270,3 @@ x as checkPort, | ||
| m as dateTime, | ||
| ot as default, | ||
| et as default, | ||
| P as getDirName, | ||
@@ -273,0 +273,0 @@ v as getEnvConfig, |
Network access
Supply chain riskThis module accesses the network.
Network access
Supply chain riskThis module accesses the network.
24481
0.25%304
0.33%