huxy-node-server
Advanced tools
+1
-1
| { | ||
| "name": "huxy-node-server", | ||
| "version": "1.1.4", | ||
| "version": "1.1.5", | ||
| "description": "一个精炼、高性能的 Express.js 服务器模板,为现代 Node.js 应用程序设计,提供灵活的功能和最佳实践。", | ||
@@ -5,0 +5,0 @@ "type": "module", |
+140
-152
@@ -1,2 +0,2 @@ | ||
| import T from 'express'; | ||
| import E from 'express'; | ||
| import K from 'helmet'; | ||
@@ -10,17 +10,17 @@ import z from 'cors'; | ||
| import k from 'node:net'; | ||
| var l = (t = new Date()) => t.toLocaleString('zh-CN', {timeZone: 'Asia/Shanghai', hour12: !1}), | ||
| w = t => Object.prototype.toString.call(t).slice(8, -1).toLowerCase(), | ||
| f = t => { | ||
| let s = t ? 'https' : 'http', | ||
| var m = (e = new Date()) => e.toLocaleString('zh-CN', {timeZone: 'Asia/Shanghai', hour12: !1}), | ||
| y = e => Object.prototype.toString.call(e).slice(8, -1).toLowerCase(), | ||
| f = e => { | ||
| let r = e ? 'https' : 'http', | ||
| o = H.networkInterfaces(), | ||
| e = []; | ||
| return (Object.keys(o).map(n => e.push(...o[n])), e.filter(n => n.family === 'IPv4').map(n => n.address)); | ||
| t = []; | ||
| return (Object.keys(o).map(n => t.push(...o[n])), t.filter(n => n.family === 'IPv4').map(n => n.address)); | ||
| }, | ||
| y = t => { | ||
| let s = t ?? process.argv.slice(2) ?? [], | ||
| T = e => { | ||
| let r = e ?? process.argv.slice(2) ?? [], | ||
| o = {}; | ||
| return ( | ||
| s.map(e => { | ||
| let [r, n] = e.split('='); | ||
| o[r] = n; | ||
| r.map(t => { | ||
| let [s, n] = t.split('='); | ||
| o[s] = n; | ||
| }), | ||
@@ -44,38 +44,38 @@ o | ||
| }, | ||
| j = (t, s, o) => { | ||
| let [e, r] = t.split('.'); | ||
| e && r ? (o[e] || (o[e] = {}), (o[e][r] = s)) : (o[e] = s); | ||
| j = (e, r, o) => { | ||
| let [t, s] = e.split('.'); | ||
| t && s ? (o[t] || (o[t] = {}), (o[t][s] = r)) : (o[t] = r); | ||
| }, | ||
| G = t => { | ||
| let {connectSrc: s, ...o} = t; | ||
| if (!s) return o; | ||
| G = e => { | ||
| let {connectSrc: r, ...o} = e; | ||
| if (!r) return o; | ||
| (o.helmet.contentSecurityPolicy || (o.helmet.contentSecurityPolicy = {}), o.helmet.contentSecurityPolicy.directives || (o.helmet.contentSecurityPolicy.directives = {})); | ||
| let e = typeof s == 'string' ? s.split(',').map(r => r.trim()) : Array.isArray(s) ? s : []; | ||
| return ((o.helmet.contentSecurityPolicy.directives.connectSrc = [...o.helmet.contentSecurityPolicy.directives.connectSrc, ...e]), o); | ||
| let t = typeof r == 'string' ? r.split(',').map(s => s.trim()) : Array.isArray(r) ? r : []; | ||
| return ((o.helmet.contentSecurityPolicy.directives.connectSrc = [...o.helmet.contentSecurityPolicy.directives.connectSrc, ...t]), o); | ||
| }, | ||
| h = (t = {}, s = U) => { | ||
| h = (e = {}, r = U) => { | ||
| let {env: o} = process; | ||
| Object.keys(s).map(r => { | ||
| let n = o[r] ?? t[r]; | ||
| n && j(s[r], n, t); | ||
| Object.keys(r).map(s => { | ||
| let n = o[s] ?? e[s]; | ||
| n && j(r[s], n, e); | ||
| }); | ||
| let e = {...t, ...y()}; | ||
| return ((e.port = e.staticPort || e.port), (e.isDev = e.nodeEnv === 'development'), (e.protocol = 'http'), G(e)); | ||
| let t = {...e, ...T()}; | ||
| return ((t.port = t.staticPort || t.port), (t.isDev = t.nodeEnv === 'development'), (t.protocol = 'http'), G(t)); | ||
| }, | ||
| g = (t, s = '127.0.0.1') => | ||
| g = (e, r = '127.0.0.1') => | ||
| new Promise(o => { | ||
| let e = k.createServer(); | ||
| (e.once('error', r => { | ||
| (e.close(), o((r.code === 'EADDRINUSE', !1))); | ||
| let t = k.createServer(); | ||
| (t.once('error', s => { | ||
| (t.close(), o((s.code === 'EADDRINUSE', !1))); | ||
| }), | ||
| e.once('listening', () => { | ||
| (e.close(), o(!0)); | ||
| t.once('listening', () => { | ||
| (t.close(), o(!0)); | ||
| }), | ||
| e.listen(Number(t), s)); | ||
| t.listen(Number(e), r)); | ||
| }), | ||
| I = (t, s = {}, o) => { | ||
| let e = r => { | ||
| (o.warn(`\u6536\u5230 ${r} \u4FE1\u53F7, \u{1F6D1} \u6B63\u5728\u5173\u95ED\u670D\u52A1\u5668...`), | ||
| t.close(async () => { | ||
| (o.info('\u{1F44B} \u670D\u52A1\u5668\u5DF2\u5173\u95ED'), await s.shutdown?.(), process.exit(0)); | ||
| I = (e, r = {}, o) => { | ||
| let t = s => { | ||
| (o.warn(`\u6536\u5230 ${s} \u4FE1\u53F7, \u{1F6D1} \u6B63\u5728\u5173\u95ED\u670D\u52A1\u5668...`), | ||
| e.close(async () => { | ||
| (o.info('\u{1F44B} \u670D\u52A1\u5668\u5DF2\u5173\u95ED'), await r.shutdown?.(), process.exit(0)); | ||
| }), | ||
@@ -86,37 +86,37 @@ setTimeout(() => { | ||
| }; | ||
| (process.on('SIGTERM', () => e('SIGTERM')), | ||
| process.on('SIGINT', () => e('SIGINT')), | ||
| process.on('uncaughtException', r => { | ||
| (o.fatal(r, `\u{1F4A5} \u672A\u6355\u83B7\u7684\u5F02\u5E38: ${r.message}`), process.exit(1)); | ||
| (process.on('SIGTERM', () => t('SIGTERM')), | ||
| process.on('SIGINT', () => t('SIGINT')), | ||
| process.on('uncaughtException', s => { | ||
| (o.fatal(s, `\u{1F4A5} \u672A\u6355\u83B7\u7684\u5F02\u5E38: ${s.message}`), process.exit(1)); | ||
| }), | ||
| process.on('unhandledRejection', (r, n) => { | ||
| (o.fatal({reason: r, promise: n}, '\u26A0\uFE0F \u672A\u5904\u7406\u7684 Promise \u62D2\u7EDD'), process.exit(1)); | ||
| process.on('unhandledRejection', (s, n) => { | ||
| (o.fatal({reason: s, promise: n}, '\u26A0\uFE0F \u672A\u5904\u7406\u7684 Promise \u62D2\u7EDD'), process.exit(1)); | ||
| })); | ||
| }, | ||
| L = (t, {port: s, host: o = '0.0.0.0'} = {}) => | ||
| new Promise((e, r) => { | ||
| L = (e, {port: r, host: o = '0.0.0.0'} = {}) => | ||
| new Promise((t, s) => { | ||
| let n = c => { | ||
| (a(), r(c)); | ||
| (a(), s(c)); | ||
| }, | ||
| i = () => { | ||
| (a(), e(t)); | ||
| (a(), t(e)); | ||
| }, | ||
| a = () => { | ||
| (t.off('error', n), t.off('listening', i)); | ||
| (e.off('error', n), e.off('listening', i)); | ||
| }; | ||
| (t.once('error', n), t.once('listening', i), t.listen(s, o)); | ||
| (e.once('error', n), e.once('listening', i), e.listen(r, o)); | ||
| }), | ||
| A = (t, s = 56) => { | ||
| let o = t.length, | ||
| e = s - o, | ||
| r = ~~(e / 2); | ||
| return `${'-'.repeat(r)}${t}${'-'.repeat(e - r)}`; | ||
| A = (e, r = 56) => { | ||
| let o = e.length, | ||
| t = r - o, | ||
| s = ~~(t / 2); | ||
| return `${'-'.repeat(s)}${e}${'-'.repeat(t - s)}`; | ||
| }; | ||
| var F = | ||
| (t = {}) => | ||
| async (s = 'huxy') => { | ||
| let {logLevel: o, transportOpt: e, ...r} = t, | ||
| (e = {}) => | ||
| async (r = 'huxy') => { | ||
| let {logLevel: o, transportOpt: t, ...s} = e, | ||
| n = (await import('pino')).default, | ||
| i = n({ | ||
| name: s, | ||
| name: r, | ||
| level: o ?? 'info', | ||
@@ -126,4 +126,4 @@ formatters: {level: a => ({level: a})}, | ||
| base: null, | ||
| transport: {target: 'pino-pretty', options: {colorize: !0, levelFirst: !0, ...e}, ignore: 'pid,hostname,level,time', translateTime: 'SYS:yyyy-mm-dd HH:MM:ss'}, | ||
| ...r, | ||
| transport: {target: 'pino-pretty', options: {colorize: !0, levelFirst: !0, ...t}, ignore: 'pid,hostname,level,time', translateTime: 'SYS:yyyy-mm-dd HH:MM:ss'}, | ||
| ...s, | ||
| }); | ||
@@ -133,77 +133,77 @@ return ((i.isPino = !0), i); | ||
| var v = F; | ||
| var $ = (t, s) => (o, e, r) => { | ||
| (s.error({message: 'Not Found', timestamp: l(), url: o.originalUrl, method: o.method, ip: o.ip, userAgent: o.get('User-Agent')}, '\u627E\u4E0D\u5230\u8DEF\u5F84'), | ||
| e.status(404).json({success: !1, status: 404, url: o.originalUrl, message: `\u8DEF\u7531 [${o.method} ${o.originalUrl}] \u4E0D\u5B58\u5728`, timestamp: l()})); | ||
| var $ = (e, r) => (o, t, s) => { | ||
| (r.error({message: 'Not Found', timestamp: m(), url: o.originalUrl, method: o.method, ip: o.ip, userAgent: o.get('User-Agent')}, '\u627E\u4E0D\u5230\u8DEF\u5F84'), | ||
| t.status(404).json({success: !1, status: 404, url: o.originalUrl, message: `\u8DEF\u7531 [${o.method} ${o.originalUrl}] \u4E0D\u5B58\u5728`, timestamp: m()})); | ||
| }, | ||
| R = (t, s) => (o, e, r, n) => { | ||
| R = (e, r) => (o, t, s, n) => { | ||
| let i = o.status || 500, | ||
| a = o.message; | ||
| (s.error({message: a, timestamp: l(), stack: o.stack, url: e.originalUrl, method: e.method, ip: e.ip, userAgent: e.get('User-Agent')}, '\u670D\u52A1\u5668\u5185\u90E8\u9519\u8BEF'), | ||
| r.status(i).json({success: !1, message: (t.isDev, a), stack: t.isDev ? o.stack : void 0, timestamp: l()})); | ||
| (r.error({message: a, timestamp: m(), stack: o.stack, url: t.originalUrl, method: t.method, ip: t.ip, userAgent: t.get('User-Agent')}, '\u670D\u52A1\u5668\u5185\u90E8\u9519\u8BEF'), | ||
| s.status(i).json({success: !1, message: (e.isDev, a), stack: e.isDev ? o.stack : void 0, timestamp: m()})); | ||
| }; | ||
| import {Router as V} from 'express'; | ||
| var W = t => { | ||
| let s = V(); | ||
| var W = e => { | ||
| let r = V(); | ||
| return ( | ||
| s.use('/health', (o, e) => { | ||
| e.status(200).json({status: 'OK', timestamp: l(), environment: t.nodeEnv, uptime: process.uptime(), memoryUsage: process.memoryUsage(), pid: process.pid}); | ||
| r.use('/health', (o, t) => { | ||
| t.status(200).json({status: 'OK', timestamp: m(), environment: e.nodeEnv, uptime: process.uptime(), memoryUsage: process.memoryUsage(), pid: process.pid}); | ||
| }), | ||
| s.get('/', (o, e) => { | ||
| e.status(200).json({message: 'Node.js \u670D\u52A1\u5668\u8FD0\u884C\u4E2D', timestamp: l(), environment: t.nodeEnv}); | ||
| r.get('/', (o, t) => { | ||
| t.status(200).json({message: 'Node.js \u670D\u52A1\u5668\u8FD0\u884C\u4E2D', timestamp: m(), environment: e.nodeEnv}); | ||
| }), | ||
| s | ||
| r | ||
| ); | ||
| }, | ||
| b = W; | ||
| var Y = async (t, s = {}, o) => { | ||
| if ((t.disable('x-powered-by'), t.set('trust proxy', s.trustProxy ?? 1), o.isPino)) { | ||
| let e = (await import('pino-http')).default; | ||
| t.use(e({logger: o, quietReqLogger: !0, autoLogging: !1, genReqId: !1})); | ||
| var Y = async (e, r = {}, o) => { | ||
| if ((e.disable('x-powered-by'), e.set('trust proxy', r.trustProxy ?? !0), o.isPino)) { | ||
| let t = (await import('pino-http')).default; | ||
| e.use(t({logger: o, quietReqLogger: !0, autoLogging: !1, genReqId: !1})); | ||
| } else | ||
| t.use((e, r, n) => { | ||
| e.log = o; | ||
| e.use((t, s, n) => { | ||
| t.log = o; | ||
| }); | ||
| (t.use(Q()), | ||
| t.use(K(s.helmet)), | ||
| t.use(z(s.cors)), | ||
| s.isStatic || t.use(s.apiPrefix, B({keyGenerator: e => X(e.ip) || e.headers['x-huxy-auth'] || e.headers['x-api-key'] || e.headers.authorization, ...s.rateLimit})), | ||
| t.use(T.json({limit: '20mb'})), | ||
| t.use(T.urlencoded({extended: !0, limit: '20mb'}))); | ||
| (e.use(Q()), | ||
| e.use(z(r.cors)), | ||
| r.helmet && e.use(K(y(r.helmet) === 'object' ? r.helmet : {})), | ||
| r.isStatic || 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})), | ||
| e.use(E.json({limit: '20mb'})), | ||
| e.use(E.urlencoded({extended: !0, limit: '20mb'}))); | ||
| }, | ||
| Z = (t, s = {}, o) => { | ||
| (t.use(b(s)), t.use($(s, o)), t.use(R(s, o))); | ||
| Z = (e, r = {}, o) => { | ||
| (e.use(b(r)), e.use($(r, o)), e.use(R(r, o))); | ||
| }, | ||
| q = async (t = {}, s) => { | ||
| let {logger: o, ...e} = h(t), | ||
| r = o ?? (await v(e.loggerConfig)('huxy')), | ||
| {port: n, ssl: i} = e; | ||
| (await g(n, e.host)) || ((e.port = Number(n) + 1), r.warn(`\u7AEF\u53E3 ${n} \u5DF2\u88AB\u5360\u7528\uFF0C\u73B0\u5728\u4F7F\u7528\u7AEF\u53E3 ${e.port}`)); | ||
| let c = T(); | ||
| await Y(c, e, r); | ||
| let p; | ||
| q = async (e = {}, r) => { | ||
| let {logger: o, ...t} = h(e), | ||
| s = o ?? (await v(t.loggerConfig)('huxy')), | ||
| {port: n, ssl: i} = t; | ||
| (await g(n, t.host)) || ((t.port = Number(n) + 1), s.warn(`\u7AEF\u53E3 ${n} \u5DF2\u88AB\u5360\u7528\uFF0C\u73B0\u5728\u4F7F\u7528\u7AEF\u53E3 ${t.port}`)); | ||
| let c = E(); | ||
| await Y(c, t, s); | ||
| let l; | ||
| (i | ||
| ? (w(i) === 'object' || | ||
| (r.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)), | ||
| (e.protocol = 'https'), | ||
| (p = J.createServer(i, c)), | ||
| ? (y(i) === 'object' || | ||
| (s.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'), | ||
| (l = J.createServer(i, c)), | ||
| O((u, d) => { | ||
| (d.writeHead(301, {Location: `${e.protocol}://${u.headers.host}${u.url}`}), d.end()); | ||
| (d.writeHead(301, {Location: `${t.protocol}://${u.headers.host}${u.url}`}), d.end()); | ||
| }).listen(80)) | ||
| : (p = O(c)), | ||
| I(p, e, r)); | ||
| : (l = O(c)), | ||
| I(l, t, s)); | ||
| try { | ||
| await L(p, e); | ||
| } catch (m) { | ||
| (r.error({err: m}, '\u26A0\uFE0F \u670D\u52A1\u5668\u542F\u52A8\u5931\u8D25'), process.exit(1)); | ||
| await L(l, t); | ||
| } catch (p) { | ||
| (s.error({err: p}, '\u26A0\uFE0F \u670D\u52A1\u5668\u542F\u52A8\u5931\u8D25'), process.exit(1)); | ||
| } | ||
| try { | ||
| await s?.(e, c, p, r); | ||
| } catch (m) { | ||
| (r.error({err: m}, `\u274C \u56DE\u8C03\u51FD\u6570\u9519\u8BEF\uFF1A${m.message}`), process.exit(1)); | ||
| await r?.(t, c, l, s); | ||
| } catch (p) { | ||
| (s.error({err: p}, `\u274C \u56DE\u8C03\u51FD\u6570\u9519\u8BEF\uFF1A${p.message}`), process.exit(1)); | ||
| } | ||
| return (Z(c, e, r), {app: c, httpServer: p, config: e, logger: r}); | ||
| return (Z(c, t, s), {app: c, httpServer: l, config: t, logger: s}); | ||
| }, | ||
| _ = q; | ||
| import 'dotenv'; | ||
| var ee = { | ||
| var tt = { | ||
| nodeEnv: process.env.NODE_ENV || 'development', | ||
@@ -221,58 +221,46 @@ isDev: process.env.NODE_ENV === 'development', | ||
| }, | ||
| helmet: { | ||
| contentSecurityPolicy: { | ||
| directives: { | ||
| defaultSrc: ["'self'"], | ||
| connectSrc: ['*'], | ||
| styleSrc: ["'self'", "'unsafe-inline'"], | ||
| scriptSrc: ["'self'", "'unsafe-eval'", "'unsafe-inline'"], | ||
| imgSrc: ["'self'", 'data:', 'https:'], | ||
| }, | ||
| }, | ||
| crossOriginEmbedderPolicy: !1, | ||
| }, | ||
| logLevel: process.env.LOG_LEVEL || 30, | ||
| }, | ||
| N = ee; | ||
| var te = (t, s, o) => | ||
| _({...N, ...t}, async (e, r, n, i) => { | ||
| let {port: a, host: c, nodeEnv: p, basepath: m, appName: u = 'HuxyServer', protocol: d} = e; | ||
| N = tt; | ||
| var et = (e, r, o) => | ||
| _({...N, ...e}, async (t, s, n, i) => { | ||
| let {port: a, host: c, nodeEnv: l, basepath: p, appName: u = 'HuxyServer', protocol: d} = t; | ||
| if (!o) { | ||
| let D = f() | ||
| .filter(S => S !== c) | ||
| .map(S => `${d}://${S}:${a}${m}`); | ||
| .map(S => `${d}://${S}:${a}${p}`); | ||
| (i.info(A(u)), | ||
| i.info(`\u{1F680} \u670D\u52A1\u8FD0\u884C\u5728\u3010${p}\u3011\u73AF\u5883: ${d}://${c}:${a}${m}`), | ||
| i.info(`-----------------[${l()}]------------------`), | ||
| i.info(`\u{1F680} \u670D\u52A1\u8FD0\u884C\u5728\u3010${l}\u3011\u73AF\u5883: ${d}://${c}:${a}${p}`), | ||
| i.info(`-----------------[${m()}]------------------`), | ||
| i.info({ips: D}, '\u672C\u5730\u5730\u5740')); | ||
| } | ||
| await s?.(e, r, n, i); | ||
| await r?.(t, s, n, i); | ||
| }), | ||
| x = te; | ||
| import ne from 'express'; | ||
| import {fileURLToPath as oe} from 'node:url'; | ||
| import {dirname as se, resolve as re} from 'node:path'; | ||
| var E = (t = import.meta.url) => se(oe(t)), | ||
| P = (...t) => re(E(), ...t), | ||
| C = P; | ||
| var ie = {port: 9e3, host: 'localhost', basepath: '/', buildPath: './build', isStatic: !0}, | ||
| ae = t => (t ? (t.endsWith('/') ? t : `${t}/`) : '/'), | ||
| ce = (t, s) => | ||
| x({...ie, ...t}, async (o, e, r, n) => { | ||
| await s?.(o, e, r, n); | ||
| x = et; | ||
| import nt from 'express'; | ||
| import {fileURLToPath as ot} from 'node:url'; | ||
| import {dirname as rt, resolve as st} from 'node:path'; | ||
| var P = (e = import.meta.url) => rt(ot(e)), | ||
| w = (...e) => st(P(), ...e), | ||
| C = w; | ||
| var it = {port: 9e3, host: 'localhost', basepath: '/', buildPath: './build', isStatic: !0}, | ||
| at = e => (e ? (e.endsWith('/') ? e : `${e}/`) : '/'), | ||
| ct = (e, r) => | ||
| x({...it, ...e}, async (o, t, s, n) => { | ||
| await r?.(o, t, s, n); | ||
| let {basepath: i, buildPath: a} = o; | ||
| (i !== '/' && | ||
| e.get('/', (m, u, d) => { | ||
| if (m.path === '/') return u.redirect(i); | ||
| t.get('/', (p, u, d) => { | ||
| if (p.path === '/') return u.redirect(i); | ||
| d(); | ||
| }), | ||
| e.use(i, ne.static(a, {...o.staticCache}))); | ||
| let c = ae(i), | ||
| p = new RegExp(`^${c.replace(/\//g, '\\/')}(.*)$`); | ||
| e.get(p, (m, u) => { | ||
| t.use(i, nt.static(a, {...o.staticCache}))); | ||
| let c = at(i), | ||
| l = new RegExp(`^${c.replace(/\//g, '\\/')}(.*)$`); | ||
| t.get(l, (p, u) => { | ||
| u.sendFile(C(a, 'index.html')); | ||
| }); | ||
| }), | ||
| M = ce; | ||
| var Je = {startServer: x, startStatic: M, createLogger: v, dateTime: l, localIPs: f, nodeArgs: y, getEnvConfig: h, checkPort: g, getDirName: E, resolvePath: P}; | ||
| export {g as checkPort, v as createLogger, l as dateTime, Je as default, E as getDirName, h as getEnvConfig, f as localIPs, y as nodeArgs, P as resolvePath, x as startServer, M as startStatic}; | ||
| M = ct; | ||
| var Jt = {startServer: x, startStatic: M, createLogger: v, dateTime: m, localIPs: f, nodeArgs: T, getEnvConfig: h, checkPort: g, getDirName: P, resolvePath: w}; | ||
| export {g as checkPort, v as createLogger, m as dateTime, Jt as default, P as getDirName, h as getEnvConfig, f as localIPs, T as nodeArgs, w as resolvePath, x as startServer, M as startStatic}; |
24826
-1.26%297
-3.88%