jinbi-utils 1.0.21 → 1.0.23
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/dist/chunk-optimizer.cjs +703 -0
- package/dist/index.esm.js +3085 -0
- package/dist/index.esm.min.js +15 -0
- package/dist/index.umd.js +3198 -0
- package/dist/index.umd.min.js +16 -0
- package/package.json +36 -3
- package/.babelrc +0 -19
- package/.cz-config.js +0 -55
- package/.dockerignore +0 -3
- package/.editorconfig +0 -12
- package/.eslintignore +0 -8
- package/.eslintrc.js +0 -54
- package/.versionrc.json +0 -9
- package/CHUNK_OPTIMIZER_USAGE.md +0 -132
- package/Dockerfile +0 -3
- package/QUICK_RELEASE.md +0 -85
- package/RELEASE_GUIDE.md +0 -243
- package/api-extractor.json +0 -15
- package/commitlint.config.js +0 -3
- package/jest.config.js +0 -15
- package/rollup.config.chunk-optimizer.js +0 -32
- package/rollup.config.js +0 -73
- package/src/array/index.ts +0 -85
- package/src/build/chunk-optimizer/ARCHITECTURE.md +0 -347
- package/src/build/chunk-optimizer/QUICK_START.md +0 -370
- package/src/build/chunk-optimizer/README.md +0 -240
- package/src/build/chunk-optimizer/core/chunk-generator.ts +0 -166
- package/src/build/chunk-optimizer/core/classifier.ts +0 -148
- package/src/build/chunk-optimizer/core/dependency-reader.ts +0 -138
- package/src/build/chunk-optimizer/examples/basic-usage.ts +0 -234
- package/src/build/chunk-optimizer/index.ts +0 -166
- package/src/build/chunk-optimizer/rules/common-rules.ts +0 -131
- package/src/build/chunk-optimizer/rules/framework-rules.ts +0 -93
- package/src/build/chunk-optimizer/rules/index.ts +0 -27
- package/src/build/chunk-optimizer/test.ts +0 -94
- package/src/build/chunk-optimizer/types.ts +0 -128
- package/src/color/index.ts +0 -58
- package/src/common/index.ts +0 -353
- package/src/constant/common.constant.ts +0 -13
- package/src/date/index.ts +0 -143
- package/src/dom/index.ts +0 -198
- package/src/file/index.ts +0 -319
- package/src/http/apiBuilder/README.md +0 -648
- package/src/http/apiBuilder/api-builder.ts +0 -502
- package/src/http/apiBuilder/example.ts +0 -243
- package/src/http/apiBuilder/index.ts +0 -1
- package/src/http/apiBuilder//345/277/253/351/200/237/345/217/202/350/200/203.md +0 -199
- package/src/http/http.ts +0 -79
- package/src/http/httpEnums.ts +0 -61
- package/src/iam/index.ts +0 -46
- package/src/index.ts +0 -20
- package/src/middleware/requestLogger.middware.ts +0 -371
- package/src/middleware/requestLoggerUnified.ts +0 -371
- package/src/number/index.ts +0 -362
- package/src/object/index.ts +0 -54
- package/src/print/index.ts +0 -102
- package/src/string/index.ts +0 -189
- package/src/utils/curl.ts +0 -108
- package/src/validate/index.ts +0 -100
- package/src/websocket/emitter.ts +0 -39
- package/src/websocket/index.ts +0 -6
- package/src/websocket/manager.ts +0 -151
- package/src/websocket/pinia-store.ts +0 -91
- package/src/websocket/service.ts +0 -34
- package/src/websocket/types.ts +0 -45
- package/test/common/index.test.ts +0 -19
- package/test/date/index.test.ts +0 -107
- package/test/file/index.test.ts +0 -104
- package/test/number/index.test.ts +0 -108
- package/test/object/index.test.ts +0 -20
- package/test/string/index.test.ts +0 -82
- package/tsconfig.json +0 -39
- package/typedoc.json +0 -12
|
@@ -1,371 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 统一请求日志中间件
|
|
3
|
-
* 自动检测框架类型(MidwayJS/HonoJS/KoaJS/Fastify)并使用对应的处理方式
|
|
4
|
-
*/
|
|
5
|
-
import { curl } from "../utils/curl";
|
|
6
|
-
|
|
7
|
-
// ==================== 通用工具函数 ====================
|
|
8
|
-
|
|
9
|
-
function getNowTime(): string {
|
|
10
|
-
const d = new Date();
|
|
11
|
-
const y = String(d.getFullYear());
|
|
12
|
-
const m = String(d.getMonth() + 1);
|
|
13
|
-
const day = String(d.getDate());
|
|
14
|
-
const h = String(d.getHours());
|
|
15
|
-
const min = String(d.getMinutes());
|
|
16
|
-
return `${y}年${m}月${day}日${h}:${min}`;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export async function sendLog(logData: any): Promise<void> {
|
|
20
|
-
try {
|
|
21
|
-
const LOG_HOST = "https://fe-log-producer.jinbizhihui.com";
|
|
22
|
-
// console.log("[RequestLogger] 远程日志发送参数", logData);
|
|
23
|
-
const result = await curl.post(`${LOG_HOST}/log/save`, logData);
|
|
24
|
-
console.log("[RequestLogger] 远程日志发送成功, result", result);
|
|
25
|
-
} catch (err) {
|
|
26
|
-
console.error(`[RequestLogger] 远程日志发送失败:`, err?.message || err);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// ==================== Hono 相关处理 ====================
|
|
31
|
-
|
|
32
|
-
async function readHonoRequestBody(c: any): Promise<any> {
|
|
33
|
-
const ct = c.req.header("content-type") || "";
|
|
34
|
-
try {
|
|
35
|
-
const raw: any = (c.req as any).raw;
|
|
36
|
-
if (raw && typeof raw.clone === "function") {
|
|
37
|
-
const cloned = raw.clone();
|
|
38
|
-
const t = await cloned.text();
|
|
39
|
-
if (!t) return undefined;
|
|
40
|
-
if (ct.includes("application/json")) {
|
|
41
|
-
try {
|
|
42
|
-
return JSON.parse(t);
|
|
43
|
-
} catch {
|
|
44
|
-
return t;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return t;
|
|
48
|
-
}
|
|
49
|
-
} catch {}
|
|
50
|
-
return undefined;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function readHonoRequestHeaders(c: any): Record<string, string> {
|
|
54
|
-
const out: Record<string, string> = {};
|
|
55
|
-
try {
|
|
56
|
-
const raw: any = (c.req as any).raw;
|
|
57
|
-
const hs: Headers | undefined = raw?.headers;
|
|
58
|
-
if (hs) {
|
|
59
|
-
hs.forEach((v: string, k: string) => {
|
|
60
|
-
out[k] = v;
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
} catch {}
|
|
64
|
-
return out;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function readHonoResponseHeaders(c: any): Record<string, string> {
|
|
68
|
-
const out: Record<string, string> = {};
|
|
69
|
-
try {
|
|
70
|
-
c.res.headers.forEach((v: string, k: string) => {
|
|
71
|
-
out[k] = v;
|
|
72
|
-
});
|
|
73
|
-
} catch {}
|
|
74
|
-
return out;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
async function handleHono(
|
|
78
|
-
c: any,
|
|
79
|
-
next: any,
|
|
80
|
-
systemName: string,
|
|
81
|
-
): Promise<void> {
|
|
82
|
-
const ip =
|
|
83
|
-
c.req.header("x-forwarded-for") || c.req.header("x-real-ip") || "unknown";
|
|
84
|
-
const method = c.req.method;
|
|
85
|
-
const url = c.req.url;
|
|
86
|
-
const query = c.req.query();
|
|
87
|
-
const headers = readHonoRequestHeaders(c);
|
|
88
|
-
const body = await readHonoRequestBody(c);
|
|
89
|
-
const timeToString = getNowTime();
|
|
90
|
-
const start = Date.now();
|
|
91
|
-
|
|
92
|
-
await next();
|
|
93
|
-
|
|
94
|
-
const duration = Date.now() - start;
|
|
95
|
-
const result = {
|
|
96
|
-
status: c.res.status,
|
|
97
|
-
headers: readHonoResponseHeaders(c),
|
|
98
|
-
duration,
|
|
99
|
-
};
|
|
100
|
-
const logData = {
|
|
101
|
-
system: systemName,
|
|
102
|
-
ip,
|
|
103
|
-
path: url,
|
|
104
|
-
method,
|
|
105
|
-
time: timeToString,
|
|
106
|
-
params: { method, url, query, body },
|
|
107
|
-
headers,
|
|
108
|
-
result,
|
|
109
|
-
};
|
|
110
|
-
await sendLog(logData);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// ==================== Koa/Midway 相关处理 ====================
|
|
114
|
-
|
|
115
|
-
function readKoaRequestHeaders(ctx: any): Record<string, string> {
|
|
116
|
-
const out: Record<string, string> = {};
|
|
117
|
-
try {
|
|
118
|
-
const headers = ctx.headers || ctx.request?.headers || {};
|
|
119
|
-
for (const [k, v] of Object.entries(headers)) {
|
|
120
|
-
out[k] = String(v);
|
|
121
|
-
}
|
|
122
|
-
} catch {}
|
|
123
|
-
return out;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function readKoaResponseHeaders(ctx: any): Record<string, string> {
|
|
127
|
-
const out: Record<string, string> = {};
|
|
128
|
-
try {
|
|
129
|
-
const headers = ctx.response?.headers || {};
|
|
130
|
-
for (const [k, v] of Object.entries(headers)) {
|
|
131
|
-
out[k] = String(v);
|
|
132
|
-
}
|
|
133
|
-
} catch {}
|
|
134
|
-
return out;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
async function handleKoa(
|
|
138
|
-
ctx: any,
|
|
139
|
-
next: any,
|
|
140
|
-
systemName: string,
|
|
141
|
-
): Promise<void> {
|
|
142
|
-
const ip = ctx.ip || ctx.request?.ip || "unknown";
|
|
143
|
-
const path = ctx.path || ctx.request?.path || "";
|
|
144
|
-
const method = ctx.method || ctx.request?.method || "";
|
|
145
|
-
const url = ctx.url || ctx.request?.url || "";
|
|
146
|
-
const query = ctx.query || ctx.request?.query || {};
|
|
147
|
-
const body = ctx.request?.body || {};
|
|
148
|
-
const headers = readKoaRequestHeaders(ctx);
|
|
149
|
-
const timeToString = getNowTime();
|
|
150
|
-
const start = Date.now();
|
|
151
|
-
|
|
152
|
-
await next();
|
|
153
|
-
|
|
154
|
-
const duration = Date.now() - start;
|
|
155
|
-
const result = {
|
|
156
|
-
status: ctx.status,
|
|
157
|
-
body: ctx.body,
|
|
158
|
-
headers: readKoaResponseHeaders(ctx),
|
|
159
|
-
duration,
|
|
160
|
-
};
|
|
161
|
-
const logData = {
|
|
162
|
-
system: systemName,
|
|
163
|
-
ip,
|
|
164
|
-
path,
|
|
165
|
-
method,
|
|
166
|
-
time: timeToString,
|
|
167
|
-
params: { method, url, query, body },
|
|
168
|
-
headers,
|
|
169
|
-
result,
|
|
170
|
-
};
|
|
171
|
-
await sendLog(logData);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// ==================== Fastify 相关处理 ====================
|
|
175
|
-
|
|
176
|
-
function readFastifyRequestHeaders(request: any): Record<string, string> {
|
|
177
|
-
const out: Record<string, string> = {};
|
|
178
|
-
try {
|
|
179
|
-
const headers = request.headers || {};
|
|
180
|
-
for (const [k, v] of Object.entries(headers)) {
|
|
181
|
-
out[k] = String(v);
|
|
182
|
-
}
|
|
183
|
-
} catch {}
|
|
184
|
-
return out;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
function readFastifyResponseHeaders(reply: any): Record<string, string> {
|
|
188
|
-
const out: Record<string, string> = {};
|
|
189
|
-
try {
|
|
190
|
-
const headers = reply.getHeaders?.() || {};
|
|
191
|
-
for (const [k, v] of Object.entries(headers)) {
|
|
192
|
-
if (v !== undefined) {
|
|
193
|
-
out[k] = String(v);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
} catch {}
|
|
197
|
-
return out;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
async function handleFastify(
|
|
201
|
-
request: any,
|
|
202
|
-
reply: any,
|
|
203
|
-
systemName: string,
|
|
204
|
-
): Promise<void> {
|
|
205
|
-
const ip =
|
|
206
|
-
request.headers["x-forwarded-for"] ||
|
|
207
|
-
request.headers["x-real-ip"] ||
|
|
208
|
-
request.ip ||
|
|
209
|
-
"unknown";
|
|
210
|
-
const path = request.url || "";
|
|
211
|
-
const method = request.method || "";
|
|
212
|
-
const query = request.query || {};
|
|
213
|
-
const body = request.body || {};
|
|
214
|
-
const headers = readFastifyRequestHeaders(request);
|
|
215
|
-
const timeToString = getNowTime();
|
|
216
|
-
const start = Date.now();
|
|
217
|
-
|
|
218
|
-
// Fastify 使用 hook,不需要调用 next
|
|
219
|
-
// 这里记录请求开始时间,响应时通过 onResponse hook 记录
|
|
220
|
-
|
|
221
|
-
const duration = Date.now() - start;
|
|
222
|
-
const result = {
|
|
223
|
-
status: reply.statusCode,
|
|
224
|
-
headers: readFastifyResponseHeaders(reply),
|
|
225
|
-
duration,
|
|
226
|
-
};
|
|
227
|
-
const logData = {
|
|
228
|
-
system: systemName,
|
|
229
|
-
ip,
|
|
230
|
-
path,
|
|
231
|
-
method,
|
|
232
|
-
time: timeToString,
|
|
233
|
-
params: { method, url: path, query, body },
|
|
234
|
-
headers,
|
|
235
|
-
result,
|
|
236
|
-
};
|
|
237
|
-
await sendLog(logData);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// ==================== 框架检测 ====================
|
|
241
|
-
|
|
242
|
-
type FrameworkType = "hono" | "koa" | "midway" | "fastify" | "unknown";
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* 检测 Fastify 请求对象
|
|
246
|
-
* Fastify 的 request 对象有特定的属性如 routerPath, routeOptions 等
|
|
247
|
-
*/
|
|
248
|
-
function isFastifyRequest(obj: any): boolean {
|
|
249
|
-
return (
|
|
250
|
-
obj &&
|
|
251
|
-
typeof obj.method === "string" &&
|
|
252
|
-
typeof obj.url === "string" &&
|
|
253
|
-
obj.headers &&
|
|
254
|
-
(obj.routerPath !== undefined ||
|
|
255
|
-
obj.routeOptions !== undefined ||
|
|
256
|
-
typeof obj.getValidationFunction === "function" ||
|
|
257
|
-
obj.raw?.constructor?.name === "IncomingMessage")
|
|
258
|
-
);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
function detectFramework(context: any, secondArg?: any): FrameworkType {
|
|
262
|
-
// Fastify: 检查第一个参数是否是 Fastify request 对象
|
|
263
|
-
// Fastify hook 签名: (request, reply) => void
|
|
264
|
-
if (isFastifyRequest(context) && secondArg?.statusCode !== undefined) {
|
|
265
|
-
return "fastify";
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
// Hono: 检查是否有 c.req.raw 和 c.res 等 Hono 特有属性
|
|
269
|
-
if (
|
|
270
|
-
context &&
|
|
271
|
-
context.req &&
|
|
272
|
-
typeof context.req.header === "function" &&
|
|
273
|
-
typeof context.req.query === "function" &&
|
|
274
|
-
(context.req as any).raw !== undefined
|
|
275
|
-
) {
|
|
276
|
-
return "hono";
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// Koa/Midway: 检查是否有 ctx.request, ctx.response 等 Koa 特有属性
|
|
280
|
-
if (
|
|
281
|
-
context &&
|
|
282
|
-
context.request &&
|
|
283
|
-
context.response &&
|
|
284
|
-
typeof context.throw === "function"
|
|
285
|
-
) {
|
|
286
|
-
// 进一步区分 Midway 和 Koa
|
|
287
|
-
// Midway 通常会有 requestContext 或特定的装饰器注入
|
|
288
|
-
if (context.requestContext || context.app?.getApplicationContext) {
|
|
289
|
-
return "midway";
|
|
290
|
-
}
|
|
291
|
-
return "koa";
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
return "unknown";
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// ==================== 统一中间件入口 ====================
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* 统一请求日志中间件
|
|
301
|
-
* 自动检测运行时框架类型,支持 Hono、Koa、Midway、Fastify
|
|
302
|
-
*
|
|
303
|
-
* @param systemName 系统名称,用于日志标识
|
|
304
|
-
* @returns 返回适配不同框架的中间件函数
|
|
305
|
-
*/
|
|
306
|
-
export function recordLogMiddleware(systemName: string) {
|
|
307
|
-
return async (contextOrC: any, nextOrReply: any) => {
|
|
308
|
-
const framework = detectFramework(contextOrC, nextOrReply);
|
|
309
|
-
|
|
310
|
-
switch (framework) {
|
|
311
|
-
case "hono":
|
|
312
|
-
return handleHono(contextOrC, nextOrReply, systemName);
|
|
313
|
-
|
|
314
|
-
case "fastify":
|
|
315
|
-
return handleFastify(contextOrC, nextOrReply, systemName);
|
|
316
|
-
|
|
317
|
-
case "koa":
|
|
318
|
-
case "midway":
|
|
319
|
-
return handleKoa(contextOrC, nextOrReply, systemName);
|
|
320
|
-
|
|
321
|
-
default:
|
|
322
|
-
// 未知框架,尝试 Koa 风格作为回退
|
|
323
|
-
console.warn(
|
|
324
|
-
`[requestLoggerUnified] Unknown framework detected, falling back to Koa-style handling`,
|
|
325
|
-
);
|
|
326
|
-
return handleKoa(contextOrC, nextOrReply, systemName);
|
|
327
|
-
}
|
|
328
|
-
};
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
// ==================== 针对特定框架的导出 ====================
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* Hono 专用中间件
|
|
335
|
-
*/
|
|
336
|
-
export function recordLogMiddlewareHono(systemName: string) {
|
|
337
|
-
return async (c: any, next: any) => {
|
|
338
|
-
return handleHono(c, next, systemName);
|
|
339
|
-
};
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* Koa 专用中间件
|
|
344
|
-
*/
|
|
345
|
-
export function recordLogMiddlewareKoa(systemName: string) {
|
|
346
|
-
return async (ctx: any, next: any) => {
|
|
347
|
-
return handleKoa(ctx, next, systemName);
|
|
348
|
-
};
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
/**
|
|
352
|
-
* Midway 专用中间件(本质与 Koa 相同,因为 Midway 基于 Koa)
|
|
353
|
-
*/
|
|
354
|
-
export function recordLogMiddlewareMidway(systemName: string) {
|
|
355
|
-
return async (ctx: any, next: any) => {
|
|
356
|
-
return handleKoa(ctx, next, systemName);
|
|
357
|
-
};
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
/**
|
|
361
|
-
* Fastify 专用插件
|
|
362
|
-
* 使用方式:fastify.addHook('onResponse', recordLogMiddlewareFastify('systemName'))
|
|
363
|
-
*/
|
|
364
|
-
export function recordLogMiddlewareFastify(systemName: string) {
|
|
365
|
-
return async (request: any, reply: any) => {
|
|
366
|
-
return handleFastify(request, reply, systemName);
|
|
367
|
-
};
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
// 默认导出统一中间件
|
|
371
|
-
export default recordLogMiddleware;
|