badmfck-api-server 4.1.58 → 5.0.1

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.
@@ -51,6 +51,7 @@ export interface APIServiceOptions<TInterceptor = unknown> {
51
51
  appVersion?: string;
52
52
  fileTempDir: string;
53
53
  fileLimit: number;
54
+ metricsDir?: string;
54
55
  }
55
56
  type InferInterceptor<T> = T extends IInterceptor<infer U> ? U : unknown;
56
57
  export declare const getDefaultOptions: <I extends IInterceptor<any> | undefined>(overrides?: Omit<Partial<APIServiceOptions<InferInterceptor<NonNullable<I>>>>, "interceptor"> & {
@@ -79,6 +79,7 @@ function defaultOptions() {
79
79
  documentation: []
80
80
  },
81
81
  appVersion: undefined,
82
+ metricsDir: undefined,
82
83
  fileTempDir: "/tmp",
83
84
  fileLimit: 10_000_000,
84
85
  keepAliveTimeout: 25 * 1000,
@@ -165,7 +166,7 @@ class APIService extends BaseService_1.BaseService {
165
166
  new Monitor_1.Monitor(this.options),
166
167
  ];
167
168
  }
168
- this.monitor = new MonitorService_1.MonitorService();
169
+ this.monitor = new MonitorService_1.MonitorService(this.options.metricsDir);
169
170
  this.monitor.init();
170
171
  new DocumentService_1.DocumentGenerator(this.options.endpoints);
171
172
  this.options.endpoints.push(new Liveness_1.Liveness(this.started), new Readiness_1.Readiness(this.started));
@@ -22,6 +22,10 @@ export declare const S_STAT_REGISTRATE_SQL_REQUEST: Signal<{
22
22
  export declare const REQ_STAT: Req<{
23
23
  range: "week" | "day" | "hour";
24
24
  }, IStat[]>;
25
+ export declare const REQ_STAT_WEEKS: Req<void, string[]>;
26
+ export declare const REQ_STAT_WEEK: Req<{
27
+ weekKey: string;
28
+ }, IStat[]>;
25
29
  type IMonitorSlot = {
26
30
  yyyymmddhhii: number;
27
31
  cpu: number;
@@ -43,8 +47,14 @@ export declare class MonitorService extends BaseService {
43
47
  intervalMs: number;
44
48
  lastCpuUsage: NodeJS.CpuUsage | null;
45
49
  lastTimestamp: number | null;
46
- constructor();
50
+ private metricsDir;
51
+ private static MAX_WEEKS;
52
+ private _persistReady;
53
+ private _flushedUpTo;
54
+ private _lastSeenWeekKey;
55
+ constructor(metricsDir?: string | null);
47
56
  init(): Promise<void>;
57
+ finishService(): Promise<void>;
48
58
  getEPStat(req: {
49
59
  range: "week" | "day" | "hour";
50
60
  }): Promise<IStat[]>;
@@ -59,5 +69,17 @@ export declare class MonitorService extends BaseService {
59
69
  private onHttpRequestRegistrate;
60
70
  private onSQLRequestRegistrate;
61
71
  private getSlot;
72
+ private liveFile;
73
+ private archiveFile;
74
+ private weekKey;
75
+ private atomicWrite;
76
+ private readJsonl;
77
+ private persistTick;
78
+ private rotate;
79
+ private downsampleWeek;
80
+ private mergeSlots;
81
+ private hydrate;
82
+ private listPersistedWeeks;
83
+ private readPersistedWeek;
62
84
  }
63
85
  export {};
@@ -36,32 +36,65 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.MonitorService = exports.REQ_STAT = exports.S_STAT_REGISTRATE_SQL_REQUEST = exports.S_STAT_REGISTRATE_HTTP_REQUEST = exports.S_STAT_REGISTRATE_SERVICE = exports.S_STAT_REGISTRATE_CUSTOM_EVENT = exports.S_STAT_REGISTRATE_REQUEST = void 0;
39
+ exports.MonitorService = exports.REQ_STAT_WEEK = exports.REQ_STAT_WEEKS = exports.REQ_STAT = exports.S_STAT_REGISTRATE_SQL_REQUEST = exports.S_STAT_REGISTRATE_HTTP_REQUEST = exports.S_STAT_REGISTRATE_SERVICE = exports.S_STAT_REGISTRATE_CUSTOM_EVENT = exports.S_STAT_REGISTRATE_REQUEST = void 0;
40
40
  const badmfck_signal_1 = __importStar(require("badmfck-signal"));
41
41
  const BaseService_1 = require("./BaseService");
42
42
  const YYYYMMDDHH_1 = require("./helper/YYYYMMDDHH");
43
+ const LogService_1 = require("./LogService");
43
44
  const os_1 = __importDefault(require("os"));
45
+ const promises_1 = __importDefault(require("fs/promises"));
46
+ const path_1 = __importDefault(require("path"));
44
47
  exports.S_STAT_REGISTRATE_REQUEST = new badmfck_signal_1.default();
45
48
  exports.S_STAT_REGISTRATE_CUSTOM_EVENT = new badmfck_signal_1.default();
46
49
  exports.S_STAT_REGISTRATE_SERVICE = new badmfck_signal_1.default();
47
50
  exports.S_STAT_REGISTRATE_HTTP_REQUEST = new badmfck_signal_1.default();
48
51
  exports.S_STAT_REGISTRATE_SQL_REQUEST = new badmfck_signal_1.default();
49
52
  exports.REQ_STAT = new badmfck_signal_1.Req(undefined, "REQ_STAT");
53
+ exports.REQ_STAT_WEEKS = new badmfck_signal_1.Req(undefined, "REQ_STAT_WEEKS");
54
+ exports.REQ_STAT_WEEK = new badmfck_signal_1.Req(undefined, "REQ_STAT_WEEK");
50
55
  class MonitorService extends BaseService_1.BaseService {
51
56
  slots = new Map();
52
57
  intervalMs = 59_000;
53
58
  lastCpuUsage = null;
54
59
  lastTimestamp = null;
55
- constructor() {
60
+ metricsDir;
61
+ static MAX_WEEKS = 10;
62
+ _persistReady = false;
63
+ _flushedUpTo = 0;
64
+ _lastSeenWeekKey = null;
65
+ constructor(metricsDir) {
56
66
  super("MonitorService");
67
+ this.metricsDir = metricsDir && metricsDir.length > 0 ? metricsDir : null;
57
68
  setInterval(() => this.collectUsage(), this.intervalMs);
58
69
  }
59
70
  async init() {
60
71
  super.init();
61
72
  exports.REQ_STAT.listener = async (req) => this.getEPStat(req);
73
+ exports.REQ_STAT_WEEKS.listener = async () => this.listPersistedWeeks();
74
+ exports.REQ_STAT_WEEK.listener = async (req) => this.readPersistedWeek(req.weekKey);
62
75
  exports.S_STAT_REGISTRATE_HTTP_REQUEST.subscribe((data) => this.onHttpRequestRegistrate(data));
63
76
  exports.S_STAT_REGISTRATE_SQL_REQUEST.subscribe((data) => this.onSQLRequestRegistrate(data));
64
77
  exports.S_STAT_REGISTRATE_REQUEST.subscribe((data) => this.onStatRegistrate(data));
78
+ if (this.metricsDir) {
79
+ try {
80
+ await promises_1.default.mkdir(this.metricsDir, { recursive: true });
81
+ }
82
+ catch (e) {
83
+ (0, LogService_1.logWarn)("metrics: cannot create metricsDir, disk persistence disabled: " + (e?.message ?? e));
84
+ this.metricsDir = null;
85
+ }
86
+ }
87
+ if (this.metricsDir) {
88
+ await this.hydrate();
89
+ await this.rotate();
90
+ this._lastSeenWeekKey = this.weekKey(new Date());
91
+ this._persistReady = true;
92
+ }
93
+ }
94
+ async finishService() {
95
+ await super.finishService();
96
+ if (this.metricsDir && this._persistReady)
97
+ await this.persistTick(true).catch(() => { });
65
98
  }
66
99
  async getEPStat(req) {
67
100
  const allSlots = [];
@@ -98,6 +131,8 @@ class MonitorService extends BaseService_1.BaseService {
98
131
  agg.cpu += s.cpu;
99
132
  agg.memory.rss += s.memory.rss;
100
133
  agg.memory.heapUsed += s.memory.heapUsed;
134
+ agg.memory.heapTotal += s.memory.heapTotal;
135
+ agg.memory.external += s.memory.external;
101
136
  for (const [path, count] of Object.entries(s.successEp)) {
102
137
  agg.successEp[path] = (agg.successEp[path] || 0) + count;
103
138
  }
@@ -118,6 +153,8 @@ class MonitorService extends BaseService_1.BaseService {
118
153
  agg.cpu = Number((agg.cpu / len).toFixed(2));
119
154
  agg.memory.rss = Math.round(agg.memory.rss / len);
120
155
  agg.memory.heapUsed = Math.round(agg.memory.heapUsed / len);
156
+ agg.memory.heapTotal = Math.round(agg.memory.heapTotal / len);
157
+ agg.memory.external = Math.round(agg.memory.external / len);
121
158
  result.push({
122
159
  timestamp: this.slotToTimestamp(agg.yyyymmddhhii),
123
160
  slot: agg
@@ -160,6 +197,8 @@ class MonitorService extends BaseService_1.BaseService {
160
197
  heapTotal: Math.round(mem.heapTotal / 1024 / 1024),
161
198
  external: Math.round(mem.external / 1024 / 1024),
162
199
  };
200
+ if (this.metricsDir && this._persistReady)
201
+ await this.persistTick().catch(() => { });
163
202
  }
164
203
  static MAX_SLOT_KEYS = 100;
165
204
  static normalizeQuery(query) {
@@ -240,5 +279,242 @@ class MonitorService extends BaseService_1.BaseService {
240
279
  }
241
280
  return slot;
242
281
  }
282
+ liveFile(weekKey) {
283
+ return path_1.default.join(this.metricsDir, `metrics_${weekKey}.jsonl`);
284
+ }
285
+ archiveFile(weekKey) {
286
+ return path_1.default.join(this.metricsDir, `metrics_${weekKey}.json`);
287
+ }
288
+ weekKey(date) {
289
+ const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
290
+ const dayNum = (d.getUTCDay() + 6) % 7;
291
+ d.setUTCDate(d.getUTCDate() - dayNum + 3);
292
+ const firstThursday = new Date(Date.UTC(d.getUTCFullYear(), 0, 4));
293
+ const firstDayNum = (firstThursday.getUTCDay() + 6) % 7;
294
+ firstThursday.setUTCDate(firstThursday.getUTCDate() - firstDayNum + 3);
295
+ const week = 1 + Math.round((d.getTime() - firstThursday.getTime()) / (7 * 24 * 3600 * 1000));
296
+ return `${d.getUTCFullYear()}-W${String(week).padStart(2, "0")}`;
297
+ }
298
+ async atomicWrite(file, content) {
299
+ const tmp = file + ".tmp";
300
+ await promises_1.default.writeFile(tmp, content, "utf-8");
301
+ await promises_1.default.rename(tmp, file);
302
+ }
303
+ async readJsonl(file) {
304
+ const txt = await promises_1.default.readFile(file, "utf-8");
305
+ const out = [];
306
+ for (const line of txt.split("\n")) {
307
+ const t = line.trim();
308
+ if (!t)
309
+ continue;
310
+ try {
311
+ out.push(JSON.parse(t));
312
+ }
313
+ catch { }
314
+ }
315
+ return out;
316
+ }
317
+ async persistTick(includeCurrentMinute = false) {
318
+ if (!this.metricsDir)
319
+ return;
320
+ const nowKey = parseInt((0, YYYYMMDDHH_1.YYYYMMDDHH)(new Date(), "yyyymmddhhmm"));
321
+ const pending = [];
322
+ for (const dayMap of this.slots.values()) {
323
+ for (const slot of dayMap.values()) {
324
+ const k = slot.yyyymmddhhii;
325
+ if (k <= this._flushedUpTo)
326
+ continue;
327
+ if (!includeCurrentMinute && k >= nowKey)
328
+ continue;
329
+ pending.push(slot);
330
+ }
331
+ }
332
+ pending.sort((a, b) => a.yyyymmddhhii - b.yyyymmddhhii);
333
+ if (pending.length) {
334
+ try {
335
+ const byWeek = new Map();
336
+ for (const s of pending) {
337
+ const wk = this.weekKey(new Date(this.slotToTimestamp(s.yyyymmddhhii)));
338
+ byWeek.set(wk, (byWeek.get(wk) ?? "") + JSON.stringify(s) + "\n");
339
+ }
340
+ for (const [wk, text] of byWeek)
341
+ await promises_1.default.appendFile(this.liveFile(wk), text, "utf-8");
342
+ this._flushedUpTo = pending[pending.length - 1].yyyymmddhhii;
343
+ }
344
+ catch (e) {
345
+ (0, LogService_1.logWarn)("metrics: persist append failed: " + (e?.message ?? e));
346
+ }
347
+ }
348
+ const curWeek = this.weekKey(new Date());
349
+ if (this._lastSeenWeekKey && this._lastSeenWeekKey !== curWeek)
350
+ await this.rotate().catch(() => { });
351
+ this._lastSeenWeekKey = curWeek;
352
+ }
353
+ async rotate() {
354
+ if (!this.metricsDir)
355
+ return;
356
+ try {
357
+ const curWeek = this.weekKey(new Date());
358
+ const files = await promises_1.default.readdir(this.metricsDir);
359
+ for (const f of files) {
360
+ const m = f.match(/^metrics_(\d{4}-W\d{2})\.jsonl$/);
361
+ if (m && m[1] !== curWeek)
362
+ await this.downsampleWeek(m[1]);
363
+ }
364
+ const after = await promises_1.default.readdir(this.metricsDir);
365
+ const byWeek = new Map();
366
+ for (const f of after) {
367
+ const m = f.match(/^metrics_(\d{4}-W\d{2})\.(jsonl|json)$/);
368
+ if (!m)
369
+ continue;
370
+ const arr = byWeek.get(m[1]) ?? [];
371
+ arr.push(f);
372
+ byWeek.set(m[1], arr);
373
+ }
374
+ const weeks = Array.from(byWeek.keys()).sort();
375
+ const excess = weeks.slice(0, Math.max(0, weeks.length - MonitorService.MAX_WEEKS));
376
+ for (const wk of excess)
377
+ for (const f of byWeek.get(wk))
378
+ await promises_1.default.unlink(path_1.default.join(this.metricsDir, f)).catch(() => { });
379
+ }
380
+ catch (e) {
381
+ (0, LogService_1.logWarn)("metrics: rotate failed: " + (e?.message ?? e));
382
+ }
383
+ }
384
+ async downsampleWeek(weekKey) {
385
+ const live = this.liveFile(weekKey);
386
+ let slots;
387
+ try {
388
+ slots = await this.readJsonl(live);
389
+ }
390
+ catch {
391
+ return;
392
+ }
393
+ if (!slots.length) {
394
+ await promises_1.default.unlink(live).catch(() => { });
395
+ return;
396
+ }
397
+ const byHour = new Map();
398
+ for (const s of slots) {
399
+ const hourKey = Math.floor(s.yyyymmddhhii / 100) * 100;
400
+ const arr = byHour.get(hourKey) ?? [];
401
+ arr.push(s);
402
+ byHour.set(hourKey, arr);
403
+ }
404
+ const hourly = Array.from(byHour.entries())
405
+ .sort((a, b) => a[0] - b[0])
406
+ .map(([hourKey, arr]) => this.mergeSlots(hourKey, arr));
407
+ await this.atomicWrite(this.archiveFile(weekKey), JSON.stringify({ version: 1, weekKey, resolution: "hour", slots: hourly }));
408
+ await promises_1.default.unlink(live).catch(() => { });
409
+ }
410
+ mergeSlots(key, arr) {
411
+ const out = {
412
+ yyyymmddhhii: key, cpu: 0,
413
+ memory: { rss: 0, heapUsed: 0, heapTotal: 0, external: 0 },
414
+ successEp: {}, failEp: {}, http: {}, success_sql: {}, fail_sql: {},
415
+ };
416
+ const add = (dst, src) => {
417
+ for (const [k, v] of Object.entries(src))
418
+ dst[k] = (dst[k] || 0) + v;
419
+ };
420
+ for (const s of arr) {
421
+ out.cpu += s.cpu;
422
+ out.memory.rss += s.memory.rss;
423
+ out.memory.heapUsed += s.memory.heapUsed;
424
+ out.memory.heapTotal += s.memory.heapTotal;
425
+ out.memory.external += s.memory.external;
426
+ add(out.successEp, s.successEp);
427
+ add(out.failEp, s.failEp);
428
+ add(out.http, s.http);
429
+ add(out.success_sql, s.success_sql);
430
+ add(out.fail_sql, s.fail_sql);
431
+ }
432
+ const n = arr.length || 1;
433
+ out.cpu = Number((out.cpu / n).toFixed(2));
434
+ out.memory.rss = Math.round(out.memory.rss / n);
435
+ out.memory.heapUsed = Math.round(out.memory.heapUsed / n);
436
+ out.memory.heapTotal = Math.round(out.memory.heapTotal / n);
437
+ out.memory.external = Math.round(out.memory.external / n);
438
+ return out;
439
+ }
440
+ async hydrate() {
441
+ if (!this.metricsDir)
442
+ return;
443
+ try {
444
+ const cutoff = parseInt((0, YYYYMMDDHH_1.YYYYMMDDHH)(new Date(Date.now() - 7 * 24 * 3600 * 1000), "yyyymmddhhmm"));
445
+ const weeks = new Set([
446
+ this.weekKey(new Date()),
447
+ this.weekKey(new Date(Date.now() - 7 * 24 * 3600 * 1000)),
448
+ ]);
449
+ let maxKey = 0;
450
+ for (const wk of weeks) {
451
+ let slots;
452
+ try {
453
+ slots = await this.readJsonl(this.liveFile(wk));
454
+ }
455
+ catch {
456
+ continue;
457
+ }
458
+ for (const s of slots) {
459
+ if (s.yyyymmddhhii < cutoff)
460
+ continue;
461
+ const dayKey = Math.floor(s.yyyymmddhhii / 100);
462
+ let dayMap = this.slots.get(dayKey);
463
+ if (!dayMap) {
464
+ dayMap = new Map();
465
+ this.slots.set(dayKey, dayMap);
466
+ }
467
+ dayMap.set(s.yyyymmddhhii, s);
468
+ if (s.yyyymmddhhii > maxKey)
469
+ maxKey = s.yyyymmddhhii;
470
+ }
471
+ }
472
+ this._flushedUpTo = maxKey;
473
+ while (this.slots.size > 7) {
474
+ const oldest = Array.from(this.slots.keys()).sort((a, b) => a - b)[0];
475
+ this.slots.delete(oldest);
476
+ }
477
+ }
478
+ catch (e) {
479
+ (0, LogService_1.logWarn)("metrics: hydrate failed: " + (e?.message ?? e));
480
+ }
481
+ }
482
+ async listPersistedWeeks() {
483
+ if (!this.metricsDir)
484
+ return [];
485
+ try {
486
+ const files = await promises_1.default.readdir(this.metricsDir);
487
+ const weeks = new Set();
488
+ for (const f of files) {
489
+ const m = f.match(/^metrics_(\d{4}-W\d{2})\.(jsonl|json)$/);
490
+ if (m)
491
+ weeks.add(m[1]);
492
+ }
493
+ return Array.from(weeks).sort();
494
+ }
495
+ catch {
496
+ return [];
497
+ }
498
+ }
499
+ async readPersistedWeek(weekKey) {
500
+ if (!this.metricsDir || !/^\d{4}-W\d{2}$/.test(weekKey))
501
+ return [];
502
+ let slots = [];
503
+ try {
504
+ try {
505
+ slots = await this.readJsonl(this.liveFile(weekKey));
506
+ }
507
+ catch {
508
+ const txt = await promises_1.default.readFile(this.archiveFile(weekKey), "utf-8");
509
+ slots = (JSON.parse(txt)?.slots ?? []);
510
+ }
511
+ }
512
+ catch {
513
+ return [];
514
+ }
515
+ return slots
516
+ .sort((a, b) => a.yyyymmddhhii - b.yyyymmddhhii)
517
+ .map(s => ({ timestamp: this.slotToTimestamp(s.yyyymmddhhii), slot: s }));
518
+ }
243
519
  }
244
520
  exports.MonitorService = MonitorService;
@@ -401,6 +401,20 @@ class Validator {
401
401
  else if (Array.isArray(tmpl) && Array.isArray(item)) {
402
402
  out[i] = this.syncStructure(tmpl, item);
403
403
  }
404
+ else if (!this.isPlainObject(tmpl) && !Array.isArray(tmpl)) {
405
+ const wantType = typeof tmpl;
406
+ if (typeof item === wantType) {
407
+ out[i] = item;
408
+ }
409
+ else if (wantType === "string" || wantType === "number" || wantType === "boolean") {
410
+ const converted = this.convertToType(item, wantType);
411
+ const bad = converted === null || (wantType === "number" && Number.isNaN(converted));
412
+ out[i] = bad ? this.clone(tmpl) : converted;
413
+ }
414
+ else {
415
+ out[i] = item;
416
+ }
417
+ }
404
418
  else {
405
419
  out[i] = this.syncStructure(tmpl, this.clone(tmpl));
406
420
  }
@@ -34,6 +34,8 @@ export declare class Monitor extends BaseEndpoint {
34
34
  httpstats(req: HTTPRequestVO): Promise<TransferPacketVO>;
35
35
  inventory(req: HTTPRequestVO): Promise<TransferPacketVO>;
36
36
  metrics(req: HTTPRequestVO): Promise<TransferPacketVO>;
37
+ metricsWeeks(req: HTTPRequestVO): Promise<TransferPacketVO>;
38
+ metricsWeek(req: HTTPRequestVO): Promise<TransferPacketVO>;
37
39
  connections(req: HTTPRequestVO): Promise<TransferPacketVO>;
38
40
  db(req: HTTPRequestVO): Promise<TransferPacketVO>;
39
41
  checkAuthentication(req: HTTPRequestVO): Promise<string>;
@@ -56,6 +56,10 @@ class Monitor extends BaseEndpoint_1.BaseEndpoint {
56
56
  range: "",
57
57
  $__range_values: ["week", "day", "hour"]
58
58
  } },
59
+ { ignoreInterceptor: true, endpoint: "metricsWeeks", handler: this.metricsWeeks },
60
+ { ignoreInterceptor: true, endpoint: "metricsWeek", handler: this.metricsWeek, validationModel: {
61
+ weekKey: ""
62
+ } },
59
63
  { ignoreInterceptor: true, endpoint: "connections", handler: this.connections },
60
64
  { ignoreInterceptor: true, endpoint: "db", handler: this.db, validationModel: {
61
65
  range: "",
@@ -201,6 +205,14 @@ class Monitor extends BaseEndpoint_1.BaseEndpoint {
201
205
  const result = await MonitorService_1.REQ_STAT.request(req.data);
202
206
  return { data: result };
203
207
  }
208
+ async metricsWeeks(req) {
209
+ await this.checkAuthentication(req);
210
+ return { data: await MonitorService_1.REQ_STAT_WEEKS.request() };
211
+ }
212
+ async metricsWeek(req) {
213
+ await this.checkAuthentication(req);
214
+ return { data: await MonitorService_1.REQ_STAT_WEEK.request({ weekKey: req.data.weekKey }) };
215
+ }
204
216
  async connections(req) {
205
217
  await this.checkAuthentication(req);
206
218
  return { data: Http_1.Http.getActiveConnectionsSnapshot() };
@@ -1,8 +1,8 @@
1
1
  <!doctype html>
2
2
  <html lang="en">
3
3
  <head>
4
- <!-- Build: 2026-08-31T16:07:38.488Z | Version: 1.0.6 -->
5
- <script>var __ver = "1.0.6";</script>
4
+ <!-- Build: 2026-09-09T16:39:44.398Z | Version: 1.0.8 -->
5
+ <script>var __ver = "1.0.8";</script>
6
6
  <meta charset="UTF-8" />
7
7
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
8
8
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
@@ -127,7 +127,7 @@ Error generating stack: `+i.message+`
127
127
  &div:nth-child(3) {
128
128
  animation-delay: -0.15s;
129
129
  }
130
- `,sm=({color:e,size:t=40})=>a.jsxs(M5,{$size:t,$color:e||"#665374",children:[a.jsx("div",{}),a.jsx("div",{}),a.jsx("div",{}),a.jsx("div",{})]}),qt=({children:e,onClose:t,label:r,scrollable:n,decorator:o,busy:i,sx:s,contentPadding:l})=>{o==="absolute"&&n&&(e=a.jsx(W,{sx:{display:o==="absolute"?"flex":void 0,flexDirection:o==="absolute"?"column":void 0,maxHeight:o==="absolute"?"80vh":void 0,zIndex:o==="absolute"?100:void 0,overflow:"auto"},children:e}));const c=r?a.jsx(W,{sx:{padding:l??"30px",boxSizing:"border-box",overflowX:"hidden",overflowY:"auto",flexGrow:1},children:e}):e,u=a.jsxs(W,{sx:{border:"1px solid rgba(255, 255, 255, 0.05)",padding:r?void 0:"30px",borderRadius:"6px",boxShadow:"0px 0px 100px rgba(0,0,0,.1)",pointerEvents:i?"none":"auto",userSelect:i?"none":"auto",display:"flex",position:"relative",flexDirection:"column",backgroundColor:"panelBackgroundPrimary",...s},children:[i&&a.jsxs(W,{sx:{position:"absolute",top:"0px",left:"0px",width:"100%",height:"100%",backgroundColor:"rgba(255,255,255,.5)",zIndex:1e5,display:"flex",flexDirection:"column",gap:"10px",justifyContent:"center",alignItems:"center"},children:[a.jsx(sm,{color:"#ad1bf1"}),a.jsx(O5,{children:"Please wait..."})]}),r&&a.jsxs(a.Fragment,{children:[a.jsx(W,{sx:{backgroundColor:o==="absolute"?"panelHeadBackgroundColor":void 0,padding:"20px",boxSizing:"border-box",width:"100%"},children:a.jsx(M,{variant:"head",sx:{display:"flex",paddingRight:"30px",overflowWrap:"break-word",wordBreak:"break-all",width:"100%",fontWeight:o==="absolute"?"200":"500",fontSize:o==="absolute"?"1.4rem":"1.2rem"},children:r})}),a.jsx(W,{sx:{boxSizing:"border-box",background:"panelDividerBackgroundColor",height:"2px",maxHeight:"2px"}})]}),t&&a.jsx(im,{icon:a.jsx(I5,{}),sx:{position:"absolute",top:"20px",right:"20px"},onClick:t}),c,i&&a.jsx(W,{sx:{position:"absolute",top:"0px",left:"0px",width:"100%",height:"100%",backdropFilter:"saturate(0.2)",zIndex:100001}})]});let d=a.jsx(a.Fragment,{children:u});return o==="absolute"&&(d=a.jsx(W,{sx:{position:"fixed",top:"0",left:"0",width:"100%",height:"100%",display:"flex",justifyContent:"center",alignItems:"center",zIndex:10,backgroundColor:"rgba(0,0,0,.6)"},children:u})),d},H5="#9a96ad",P=({children:e,sx:t})=>a.jsx(M,{variant:"caption",sx:{opacity:1,color:H5,letterSpacing:".02em",...t},children:e}),U5=new tt.Req(e=>m4(e)),W5=new tt.Req(e=>F1(e)),q5=new tt.Req(()=>g4()),V5=new tt.Req(e=>A4(e)),Q5=new tt.Req(()=>v4()),G5=new tt.Req(e=>y4(e)),K5=new tt.Req(()=>C4()),X5=new tt.Req(()=>E4()),am=new tt.Req(()=>w4()),Y5=new tt.Req(()=>B4()),J5=new tt.Req(()=>k4()),Z5=new tt.Req(()=>S4()),e8=new tt.Req(e=>b4(e.confirm)),Pt=(e,t,r=!0)=>{const n=V.useRef(e);n.current=e,V.useEffect(()=>{if(!r)return;n.current();const o=setInterval(()=>n.current(),t);return()=>clearInterval(o)},[t,r])},gi=ge.input`
130
+ `,sm=({color:e,size:t=40})=>a.jsxs(M5,{$size:t,$color:e||"#665374",children:[a.jsx("div",{}),a.jsx("div",{}),a.jsx("div",{}),a.jsx("div",{})]}),qt=({children:e,onClose:t,label:r,scrollable:n,decorator:o,busy:i,sx:s,contentPadding:l})=>{o==="absolute"&&n&&(e=a.jsx(W,{sx:{display:o==="absolute"?"flex":void 0,flexDirection:o==="absolute"?"column":void 0,maxHeight:o==="absolute"?"80vh":void 0,zIndex:o==="absolute"?100:void 0,overflow:"auto"},children:e}));const c=r?a.jsx(W,{sx:{padding:l??"30px",boxSizing:"border-box",overflowX:"hidden",overflowY:"auto",flexGrow:1},children:e}):e,u=a.jsxs(W,{sx:{border:"1px solid rgba(255, 255, 255, 0.05)",padding:r?void 0:"30px",borderRadius:"6px",boxShadow:"0px 0px 100px rgba(0,0,0,.1)",pointerEvents:i?"none":"auto",userSelect:i?"none":"auto",display:"flex",position:"relative",flexDirection:"column",backgroundColor:"panelBackgroundPrimary",...s},children:[i&&a.jsxs(W,{sx:{position:"absolute",top:"0px",left:"0px",width:"100%",height:"100%",backgroundColor:"rgba(255,255,255,.5)",zIndex:1e5,display:"flex",flexDirection:"column",gap:"10px",justifyContent:"center",alignItems:"center"},children:[a.jsx(sm,{color:"#ad1bf1"}),a.jsx(O5,{children:"Please wait..."})]}),r&&a.jsxs(a.Fragment,{children:[a.jsx(W,{sx:{backgroundColor:o==="absolute"?"panelHeadBackgroundColor":void 0,padding:"20px",boxSizing:"border-box",width:"100%"},children:a.jsx(M,{variant:"head",sx:{display:"flex",paddingRight:"30px",overflowWrap:"break-word",wordBreak:"break-all",width:"100%",fontWeight:o==="absolute"?"200":"500",fontSize:o==="absolute"?"1.4rem":"1.2rem"},children:r})}),a.jsx(W,{sx:{boxSizing:"border-box",background:"panelDividerBackgroundColor",height:"2px",maxHeight:"2px"}})]}),t&&a.jsx(im,{icon:a.jsx(I5,{}),sx:{position:"absolute",top:"20px",right:"20px"},onClick:t}),c,i&&a.jsx(W,{sx:{position:"absolute",top:"0px",left:"0px",width:"100%",height:"100%",backdropFilter:"saturate(0.2)",zIndex:100001}})]});let d=a.jsx(a.Fragment,{children:u});return o==="absolute"&&(d=a.jsx(W,{sx:{position:"fixed",top:"0",left:"0",width:"100%",height:"100%",display:"flex",justifyContent:"center",alignItems:"center",zIndex:10,backgroundColor:"rgba(0,0,0,.6)"},children:u})),d},H5="#9a96ad",P=({children:e,sx:t})=>a.jsx(M,{variant:"caption",sx:{opacity:1,color:H5,letterSpacing:".02em",...t},children:e}),U5=new tt.Req(e=>m4(e)),W5=new tt.Req(e=>F1(e)),q5=new tt.Req(()=>g4()),V5=new tt.Req(e=>A4(e)),Q5=new tt.Req(()=>v4()),G5=new tt.Req(e=>y4(e)),K5=new tt.Req(()=>C4()),X5=new tt.Req(()=>E4()),am=new tt.Req(()=>w4()),Y5=new tt.Req(()=>B4()),J5=new tt.Req(()=>k4()),Z5=new tt.Req(()=>S4()),e8=new tt.Req(e=>e!=null&&e.confirm?b4(e.confirm):Promise.resolve({httpStatus:0})),Pt=(e,t,r=!0)=>{const n=V.useRef(e);n.current=e,V.useEffect(()=>{if(!r)return;n.current();const o=setInterval(()=>n.current(),t);return()=>clearInterval(o)},[t,r])},gi=ge.input`
131
131
  width: 100%;
132
132
  box-sizing: border-box;
133
133
  padding: 13px 14px;
@@ -447,4 +447,4 @@ const j6={background:"#a7a7a7",backgroundSelected:"#66bb6a",toggle:"#FFFFFF"},D6
447
447
  <body>
448
448
  <div id="root"></div>
449
449
  </body>
450
- </html>
450
+ </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "badmfck-api-server",
3
- "version": "4.1.58",
3
+ "version": "5.0.1",
4
4
  "description": "Simple API http server based on express",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -20,23 +20,23 @@
20
20
  "express"
21
21
  ],
22
22
  "dependencies": {
23
- "@types/express-fileupload": "^1.5.0",
24
- "@types/mysql": "^2.15.21",
25
- "@types/node": "^25.0.3",
26
- "@types/pg": "^8.15.5",
27
- "@types/ws": "^8.5.9",
23
+ "@types/express-fileupload": "^1.5.1",
24
+ "@types/mysql": "^2.15.27",
25
+ "@types/node": "^26.5.0",
26
+ "@types/pg": "^8.23.1",
27
+ "@types/ws": "^8.18.1",
28
28
  "badmfck-signal": "^1.4.9",
29
- "cors": "^2.8.5",
30
- "express": "^4.22.1",
29
+ "cors": "^2.8.6",
30
+ "express": "^5.2.1",
31
31
  "express-fileupload": "^1.5.2",
32
- "mysql2": "^3.16.0",
33
- "pg": "^8.16.3",
34
- "undici": "^7.18.2",
35
- "ws": "^8.19.0"
32
+ "mysql2": "^3.24.4",
33
+ "pg": "^8.23.0",
34
+ "undici": "^7.29.1",
35
+ "ws": "^8.21.3"
36
36
  },
37
37
  "devDependencies": {
38
- "@types/cors": "^2.8.13",
39
- "@types/express": "^4.17.21"
38
+ "@types/cors": "^2.8.19",
39
+ "@types/express": "^5.0.6"
40
40
  },
41
41
  "author": "Igor Bloom",
42
42
  "license": "MIT"