@exyconn/common 2.3.4 → 2.3.5

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/index.mjs CHANGED
@@ -1,9 +1,10 @@
1
1
  import winston from 'winston';
2
2
  import DailyRotateFile from 'winston-daily-rotate-file';
3
- import path, { resolve } from 'path';
3
+ import path2, { resolve } from 'path';
4
4
  import mongoose, { Types } from 'mongoose';
5
5
  import jwt from 'jsonwebtoken';
6
- import { existsSync, readFileSync } from 'fs';
6
+ import fs, { existsSync, readFileSync } from 'fs';
7
+ import os from 'os';
7
8
  import rateLimit from 'express-rate-limit';
8
9
  import axios from 'axios';
9
10
  import { createContext, useState, useCallback, useMemo, useRef, useEffect, useContext } from 'react';
@@ -58,12 +59,14 @@ __export(server_exports, {
58
59
  createCorsOptions: () => createCorsOptions,
59
60
  createCrudControllers: () => createCrudControllers,
60
61
  createDdosRateLimiter: () => createDdosRateLimiter,
62
+ createHealthHandler: () => createHealthHandler,
61
63
  createLogger: () => createLogger,
62
64
  createMorganStream: () => createMorganStream,
63
65
  createMultiBrandCorsOptions: () => createMultiBrandCorsOptions,
64
66
  createPaginationMiddleware: () => createPaginationMiddleware,
65
67
  createPrefixedKeyGenerator: () => createPrefixedKeyGenerator,
66
68
  createRateLimiter: () => createRateLimiter,
69
+ createRootHandler: () => createRootHandler,
67
70
  createStandardRateLimiter: () => createStandardRateLimiter,
68
71
  createStrictRateLimiter: () => createStrictRateLimiter,
69
72
  createUserKeyGenerator: () => createUserKeyGenerator,
@@ -77,6 +80,7 @@ __export(server_exports, {
77
80
  extractSchemaMeta: () => extractSchemaMeta,
78
81
  forbiddenResponse: () => forbiddenResponse,
79
82
  formatPackageCheckResult: () => formatPackageCheckResult,
83
+ generateHealthResponse: () => generateHealthResponse,
80
84
  generateNcuCommand: () => generateNcuCommand,
81
85
  getConnectionStatus: () => getConnectionStatus,
82
86
  getDatabaseOptions: () => getDatabaseOptions,
@@ -321,7 +325,7 @@ var createLogger = (config = {}) => {
321
325
  }),
322
326
  // Combined logs (all levels)
323
327
  new DailyRotateFile({
324
- filename: path.join(finalConfig.logsDir, "combined-%DATE%.log"),
328
+ filename: path2.join(finalConfig.logsDir, "combined-%DATE%.log"),
325
329
  datePattern: "YYYY-MM-DD",
326
330
  maxSize: finalConfig.maxSize,
327
331
  maxFiles: finalConfig.maxFiles,
@@ -329,7 +333,7 @@ var createLogger = (config = {}) => {
329
333
  }),
330
334
  // Error logs only
331
335
  new DailyRotateFile({
332
- filename: path.join(finalConfig.logsDir, "error-%DATE%.log"),
336
+ filename: path2.join(finalConfig.logsDir, "error-%DATE%.log"),
333
337
  datePattern: "YYYY-MM-DD",
334
338
  level: "error",
335
339
  maxSize: finalConfig.maxSize,
@@ -1438,6 +1442,150 @@ var packageCheckServer = {
1438
1442
  generateNcuCommand,
1439
1443
  print: printPackageCheckSummary
1440
1444
  };
1445
+ var serverStartTime = Date.now();
1446
+ function getTimezoneOffset() {
1447
+ const offset = (/* @__PURE__ */ new Date()).getTimezoneOffset();
1448
+ const hours = Math.floor(Math.abs(offset) / 60);
1449
+ const minutes = Math.abs(offset) % 60;
1450
+ const sign = offset <= 0 ? "+" : "-";
1451
+ return `${sign}${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
1452
+ }
1453
+ function getTimezoneName() {
1454
+ try {
1455
+ return Intl.DateTimeFormat().resolvedOptions().timeZone;
1456
+ } catch {
1457
+ return "UTC";
1458
+ }
1459
+ }
1460
+ function getPackageInfo(criticalPackages = []) {
1461
+ try {
1462
+ const possiblePaths = [
1463
+ path2.join(process.cwd(), "package.json"),
1464
+ path2.join(__dirname, "..", "..", "..", "..", "package.json"),
1465
+ path2.join(__dirname, "..", "..", "package.json")
1466
+ ];
1467
+ for (const pkgPath of possiblePaths) {
1468
+ if (fs.existsSync(pkgPath)) {
1469
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
1470
+ const deps = pkg.dependencies || {};
1471
+ const devDeps = pkg.devDependencies || {};
1472
+ const total = Object.keys(deps).length + Object.keys(devDeps).length;
1473
+ const critical = {};
1474
+ for (const pkgName of criticalPackages) {
1475
+ if (deps[pkgName]) {
1476
+ critical[pkgName] = deps[pkgName].replace("^", "").replace("~", "");
1477
+ }
1478
+ }
1479
+ return { total, critical };
1480
+ }
1481
+ }
1482
+ } catch {
1483
+ }
1484
+ return { total: 0, critical: {} };
1485
+ }
1486
+ async function generateHealthResponse(config) {
1487
+ const startTime = Date.now();
1488
+ const now = /* @__PURE__ */ new Date();
1489
+ let dependencies = {};
1490
+ if (config.checkDependencies) {
1491
+ try {
1492
+ dependencies = await config.checkDependencies();
1493
+ } catch {
1494
+ dependencies = { error: "DOWN" };
1495
+ }
1496
+ }
1497
+ const hasDownDep = Object.values(dependencies).includes("DOWN");
1498
+ const status = hasDownDep ? "DEGRADED" : "UP";
1499
+ const defaultCriticalPackages = ["express", "mongoose", "cors", "dotenv"];
1500
+ const packageInfo = getPackageInfo(config.criticalPackages || defaultCriticalPackages);
1501
+ const totalMem = os.totalmem();
1502
+ const freeMem = os.freemem();
1503
+ const usedMem = totalMem - freeMem;
1504
+ const isProduction2 = process.env.NODE_ENV === "production";
1505
+ const serverUrl = isProduction2 ? `https://${config.domain}` : `http://localhost:${config.port}`;
1506
+ const response = {
1507
+ status,
1508
+ app: config.name,
1509
+ env: process.env.NODE_ENV || "development",
1510
+ version: config.version,
1511
+ urls: {
1512
+ ...config.uiUrl && { ui: config.uiUrl },
1513
+ server: config.serverUrl || serverUrl,
1514
+ health: `${config.serverUrl || serverUrl}/health`
1515
+ },
1516
+ time: {
1517
+ serverTime: now.toISOString(),
1518
+ timezone: getTimezoneName(),
1519
+ offset: getTimezoneOffset(),
1520
+ epoch: Math.floor(now.getTime() / 1e3)
1521
+ },
1522
+ uptimeSec: Math.floor((Date.now() - serverStartTime) / 1e3),
1523
+ node: {
1524
+ version: process.version,
1525
+ platform: os.platform(),
1526
+ arch: os.arch()
1527
+ },
1528
+ system: {
1529
+ hostname: os.hostname(),
1530
+ memoryUsedMB: Math.round(usedMem / 1024 / 1024),
1531
+ memoryTotalMB: Math.round(totalMem / 1024 / 1024),
1532
+ memoryFreePercent: Math.round(freeMem / totalMem * 100),
1533
+ cpuLoad: os.loadavg().map((l) => Math.round(l * 100) / 100),
1534
+ cpuCount: os.cpus().length
1535
+ },
1536
+ packages: {
1537
+ appVersion: config.version,
1538
+ totalDependencies: packageInfo.total,
1539
+ critical: packageInfo.critical
1540
+ },
1541
+ dependencies,
1542
+ ...config.infra && { infra: config.infra },
1543
+ responseTimeMs: Date.now() - startTime
1544
+ };
1545
+ return response;
1546
+ }
1547
+ function createHealthHandler(config) {
1548
+ return async (_req, res) => {
1549
+ try {
1550
+ const health = await generateHealthResponse(config);
1551
+ const statusCode2 = health.status === "UP" ? 200 : health.status === "DEGRADED" ? 200 : 503;
1552
+ res.status(statusCode2).json(health);
1553
+ } catch (error) {
1554
+ res.status(503).json({
1555
+ status: "DOWN",
1556
+ app: config.name,
1557
+ env: process.env.NODE_ENV || "development",
1558
+ version: config.version,
1559
+ error: error instanceof Error ? error.message : "Unknown error",
1560
+ time: {
1561
+ serverTime: (/* @__PURE__ */ new Date()).toISOString(),
1562
+ timezone: getTimezoneName(),
1563
+ offset: getTimezoneOffset(),
1564
+ epoch: Math.floor(Date.now() / 1e3)
1565
+ }
1566
+ });
1567
+ }
1568
+ };
1569
+ }
1570
+ function createRootHandler(config) {
1571
+ return async (_req, res) => {
1572
+ try {
1573
+ const health = await generateHealthResponse(config);
1574
+ res.json({
1575
+ message: `Welcome to ${config.name}`,
1576
+ description: config.description || `${config.name} API Server`,
1577
+ ...config.endpoints && { endpoints: config.endpoints },
1578
+ ...health
1579
+ });
1580
+ } catch (error) {
1581
+ res.status(503).json({
1582
+ status: "DOWN",
1583
+ app: config.name,
1584
+ error: error instanceof Error ? error.message : "Unknown error"
1585
+ });
1586
+ }
1587
+ };
1588
+ }
1441
1589
 
1442
1590
  // src/server/configs/cors.config.ts
1443
1591
  var DEFAULT_CORS_CONFIG = {
@@ -2496,9 +2644,9 @@ var parsePaginatedResponse = (response) => {
2496
2644
  return { items: [], total: 0, page: 1, limit: 10 };
2497
2645
  }
2498
2646
  };
2499
- var extractNestedData = (response, path2, fallback = null) => {
2647
+ var extractNestedData = (response, path3, fallback = null) => {
2500
2648
  try {
2501
- const keys = path2.split(".");
2649
+ const keys = path3.split(".");
2502
2650
  let current = response;
2503
2651
  for (const key of keys) {
2504
2652
  if (current && typeof current === "object" && key in current) {
@@ -6632,11 +6780,11 @@ function getContrastColor(hex) {
6632
6780
  }
6633
6781
  function flattenToCssVars(obj, prefix = "--ec") {
6634
6782
  const result = {};
6635
- function flatten(current, path2 = []) {
6783
+ function flatten(current, path3 = []) {
6636
6784
  for (const key in current) {
6637
6785
  if (Object.prototype.hasOwnProperty.call(current, key)) {
6638
6786
  const value = current[key];
6639
- const newPath = [...path2, key];
6787
+ const newPath = [...path3, key];
6640
6788
  const varName = `${prefix}-${newPath.join("-")}`;
6641
6789
  if (value && typeof value === "object" && !Array.isArray(value)) {
6642
6790
  flatten(value, newPath);
@@ -6894,8 +7042,8 @@ function ThemeProvider({
6894
7042
  );
6895
7043
  return /* @__PURE__ */ jsx(ThemeContext.Provider, { value: contextValue, children });
6896
7044
  }
6897
- function cssVar(path2, prefix = "--ec") {
6898
- return `var(${prefix}-${path2.replace(/\./g, "-")})`;
7045
+ function cssVar(path3, prefix = "--ec") {
7046
+ return `var(${prefix}-${path3.replace(/\./g, "-")})`;
6899
7047
  }
6900
7048
  function useThemeValue(selector) {
6901
7049
  const { theme } = useTheme();