@exyconn/common 2.3.4 → 2.3.6
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/client/http/index.js +1 -3
- package/dist/client/http/index.js.map +1 -1
- package/dist/client/http/index.mjs +1 -3
- package/dist/client/http/index.mjs.map +1 -1
- package/dist/client/index.js +4 -4
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +4 -4
- package/dist/client/index.mjs.map +1 -1
- package/dist/client/logger/index.js +3 -1
- package/dist/client/logger/index.js.map +1 -1
- package/dist/client/logger/index.mjs +3 -1
- package/dist/client/logger/index.mjs.map +1 -1
- package/dist/client/utils/index.js +3 -3
- package/dist/client/utils/index.js.map +1 -1
- package/dist/client/utils/index.mjs +3 -3
- package/dist/client/utils/index.mjs.map +1 -1
- package/dist/{index-Ckhm_HaX.d.mts → index-B8O4iu6q.d.mts} +7 -2
- package/dist/{index-br6POSyA.d.ts → index-MpV0UNTq.d.ts} +7 -2
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +171 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +168 -17
- package/dist/index.mjs.map +1 -1
- package/dist/server/configs/index.js +3 -0
- package/dist/server/configs/index.js.map +1 -1
- package/dist/server/configs/index.mjs +3 -0
- package/dist/server/configs/index.mjs.map +1 -1
- package/dist/server/index.d.mts +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +161 -8
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +156 -8
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/middleware/index.js +3 -3
- package/dist/server/middleware/index.js.map +1 -1
- package/dist/server/middleware/index.mjs +3 -3
- package/dist/server/middleware/index.mjs.map +1 -1
- package/dist/server/utils/index.d.mts +99 -1
- package/dist/server/utils/index.d.ts +99 -1
- package/dist/server/utils/index.js +154 -0
- package/dist/server/utils/index.js.map +1 -1
- package/dist/server/utils/index.mjs +148 -3
- package/dist/server/utils/index.mjs.map +1 -1
- package/package.json +25 -25
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
var fs = require('fs');
|
|
4
4
|
var path = require('path');
|
|
5
|
+
var os = require('os');
|
|
6
|
+
|
|
7
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
|
|
9
|
+
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
10
|
+
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
11
|
+
var os__default = /*#__PURE__*/_interopDefault(os);
|
|
5
12
|
|
|
6
13
|
// src/server/utils/filter-builder.ts
|
|
7
14
|
var buildFilter = (options) => {
|
|
@@ -296,12 +303,159 @@ var packageCheckServer = {
|
|
|
296
303
|
generateNcuCommand,
|
|
297
304
|
print: printPackageCheckSummary
|
|
298
305
|
};
|
|
306
|
+
var serverStartTime = Date.now();
|
|
307
|
+
function getTimezoneOffset() {
|
|
308
|
+
const offset = (/* @__PURE__ */ new Date()).getTimezoneOffset();
|
|
309
|
+
const hours = Math.floor(Math.abs(offset) / 60);
|
|
310
|
+
const minutes = Math.abs(offset) % 60;
|
|
311
|
+
const sign = offset <= 0 ? "+" : "-";
|
|
312
|
+
return `${sign}${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
313
|
+
}
|
|
314
|
+
function getTimezoneName() {
|
|
315
|
+
try {
|
|
316
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
317
|
+
} catch {
|
|
318
|
+
return "UTC";
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
function getPackageInfo(criticalPackages = []) {
|
|
322
|
+
try {
|
|
323
|
+
const possiblePaths = [
|
|
324
|
+
path__default.default.join(process.cwd(), "package.json"),
|
|
325
|
+
path__default.default.join(__dirname, "..", "..", "..", "..", "package.json"),
|
|
326
|
+
path__default.default.join(__dirname, "..", "..", "package.json")
|
|
327
|
+
];
|
|
328
|
+
for (const pkgPath of possiblePaths) {
|
|
329
|
+
if (fs__default.default.existsSync(pkgPath)) {
|
|
330
|
+
const pkg = JSON.parse(fs__default.default.readFileSync(pkgPath, "utf-8"));
|
|
331
|
+
const deps = pkg.dependencies || {};
|
|
332
|
+
const devDeps = pkg.devDependencies || {};
|
|
333
|
+
const total = Object.keys(deps).length + Object.keys(devDeps).length;
|
|
334
|
+
const critical = {};
|
|
335
|
+
for (const pkgName of criticalPackages) {
|
|
336
|
+
if (deps[pkgName]) {
|
|
337
|
+
critical[pkgName] = deps[pkgName].replace("^", "").replace("~", "");
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return { total, critical };
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
} catch {
|
|
344
|
+
}
|
|
345
|
+
return { total: 0, critical: {} };
|
|
346
|
+
}
|
|
347
|
+
async function generateHealthResponse(config) {
|
|
348
|
+
const startTime = Date.now();
|
|
349
|
+
const now = /* @__PURE__ */ new Date();
|
|
350
|
+
let dependencies = {};
|
|
351
|
+
if (config.checkDependencies) {
|
|
352
|
+
try {
|
|
353
|
+
dependencies = await config.checkDependencies();
|
|
354
|
+
} catch {
|
|
355
|
+
dependencies = { error: "DOWN" };
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
const hasDownDep = Object.values(dependencies).includes("DOWN");
|
|
359
|
+
const status = hasDownDep ? "DEGRADED" : "UP";
|
|
360
|
+
const defaultCriticalPackages = ["express", "mongoose", "cors", "dotenv"];
|
|
361
|
+
const packageInfo = getPackageInfo(config.criticalPackages || defaultCriticalPackages);
|
|
362
|
+
const totalMem = os__default.default.totalmem();
|
|
363
|
+
const freeMem = os__default.default.freemem();
|
|
364
|
+
const usedMem = totalMem - freeMem;
|
|
365
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
366
|
+
const serverUrl = isProduction ? `https://${config.domain}` : `http://localhost:${config.port}`;
|
|
367
|
+
const response = {
|
|
368
|
+
status,
|
|
369
|
+
app: config.name,
|
|
370
|
+
env: process.env.NODE_ENV || "development",
|
|
371
|
+
version: config.version,
|
|
372
|
+
urls: {
|
|
373
|
+
...config.uiUrl && { ui: config.uiUrl },
|
|
374
|
+
server: config.serverUrl || serverUrl,
|
|
375
|
+
health: `${config.serverUrl || serverUrl}/health`
|
|
376
|
+
},
|
|
377
|
+
time: {
|
|
378
|
+
serverTime: now.toISOString(),
|
|
379
|
+
timezone: getTimezoneName(),
|
|
380
|
+
offset: getTimezoneOffset(),
|
|
381
|
+
epoch: Math.floor(now.getTime() / 1e3)
|
|
382
|
+
},
|
|
383
|
+
uptimeSec: Math.floor((Date.now() - serverStartTime) / 1e3),
|
|
384
|
+
node: {
|
|
385
|
+
version: process.version,
|
|
386
|
+
platform: os__default.default.platform(),
|
|
387
|
+
arch: os__default.default.arch()
|
|
388
|
+
},
|
|
389
|
+
system: {
|
|
390
|
+
hostname: os__default.default.hostname(),
|
|
391
|
+
memoryUsedMB: Math.round(usedMem / 1024 / 1024),
|
|
392
|
+
memoryTotalMB: Math.round(totalMem / 1024 / 1024),
|
|
393
|
+
memoryFreePercent: Math.round(freeMem / totalMem * 100),
|
|
394
|
+
cpuLoad: os__default.default.loadavg().map((l) => Math.round(l * 100) / 100),
|
|
395
|
+
cpuCount: os__default.default.cpus().length
|
|
396
|
+
},
|
|
397
|
+
packages: {
|
|
398
|
+
appVersion: config.version,
|
|
399
|
+
totalDependencies: packageInfo.total,
|
|
400
|
+
critical: packageInfo.critical
|
|
401
|
+
},
|
|
402
|
+
dependencies,
|
|
403
|
+
...config.infra && { infra: config.infra },
|
|
404
|
+
responseTimeMs: Date.now() - startTime
|
|
405
|
+
};
|
|
406
|
+
return response;
|
|
407
|
+
}
|
|
408
|
+
function createHealthHandler(config) {
|
|
409
|
+
return async (_req, res) => {
|
|
410
|
+
try {
|
|
411
|
+
const health = await generateHealthResponse(config);
|
|
412
|
+
const statusCode = health.status === "UP" ? 200 : health.status === "DEGRADED" ? 200 : 503;
|
|
413
|
+
res.status(statusCode).json(health);
|
|
414
|
+
} catch (error) {
|
|
415
|
+
res.status(503).json({
|
|
416
|
+
status: "DOWN",
|
|
417
|
+
app: config.name,
|
|
418
|
+
env: process.env.NODE_ENV || "development",
|
|
419
|
+
version: config.version,
|
|
420
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
421
|
+
time: {
|
|
422
|
+
serverTime: (/* @__PURE__ */ new Date()).toISOString(),
|
|
423
|
+
timezone: getTimezoneName(),
|
|
424
|
+
offset: getTimezoneOffset(),
|
|
425
|
+
epoch: Math.floor(Date.now() / 1e3)
|
|
426
|
+
}
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
function createRootHandler(config) {
|
|
432
|
+
return async (_req, res) => {
|
|
433
|
+
try {
|
|
434
|
+
const health = await generateHealthResponse(config);
|
|
435
|
+
res.json({
|
|
436
|
+
message: `Welcome to ${config.name}`,
|
|
437
|
+
description: config.description || `${config.name} API Server`,
|
|
438
|
+
...config.endpoints && { endpoints: config.endpoints },
|
|
439
|
+
...health
|
|
440
|
+
});
|
|
441
|
+
} catch (error) {
|
|
442
|
+
res.status(503).json({
|
|
443
|
+
status: "DOWN",
|
|
444
|
+
app: config.name,
|
|
445
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
}
|
|
299
450
|
|
|
300
451
|
exports.buildFilter = buildFilter;
|
|
301
452
|
exports.buildPagination = buildPagination;
|
|
302
453
|
exports.buildPaginationMeta = buildPaginationMeta;
|
|
303
454
|
exports.checkPackageServer = checkPackageServer;
|
|
455
|
+
exports.createHealthHandler = createHealthHandler;
|
|
456
|
+
exports.createRootHandler = createRootHandler;
|
|
304
457
|
exports.formatPackageCheckResult = formatPackageCheckResult;
|
|
458
|
+
exports.generateHealthResponse = generateHealthResponse;
|
|
305
459
|
exports.generateNcuCommand = generateNcuCommand;
|
|
306
460
|
exports.omitFields = omitFields;
|
|
307
461
|
exports.packageCheckServer = packageCheckServer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/server/utils/filter-builder.ts","../../../src/server/utils/sanitize.ts","../../../src/server/utils/packageCheck.ts"],"names":["resolve","existsSync","readFileSync"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Filter Builder Options\r\n */\r\nexport interface FilterOptions {\r\n organizationId?: string;\r\n search?: string;\r\n searchFields?: string[];\r\n dateField?: string;\r\n startDate?: string;\r\n endDate?: string;\r\n status?: string;\r\n isActive?: boolean;\r\n [key: string]: unknown;\r\n}\r\n\r\n/**\r\n * Pagination Options\r\n */\r\nexport interface PaginationOptions {\r\n page?: number;\r\n limit?: number;\r\n defaultLimit?: number;\r\n maxLimit?: number;\r\n}\r\n\r\n/**\r\n * Pagination Result\r\n */\r\nexport interface PaginationResult {\r\n skip: number;\r\n limit: number;\r\n page: number;\r\n}\r\n\r\n/**\r\n * Build MongoDB filter query dynamically\r\n */\r\nexport const buildFilter = (options: FilterOptions): Record<string, unknown> => {\r\n const {\r\n organizationId,\r\n search,\r\n searchFields = [],\r\n dateField = 'createdAt',\r\n startDate,\r\n endDate,\r\n status,\r\n isActive,\r\n ...additionalFilters\r\n } = options;\r\n\r\n const filter: Record<string, unknown> = {};\r\n\r\n // Add organizationId if provided\r\n if (organizationId) {\r\n filter.organizationId = organizationId;\r\n }\r\n\r\n // Handle text search with regex (min 2 characters)\r\n if (search && search.trim().length >= 2 && searchFields.length > 0) {\r\n const searchRegex = new RegExp(search.trim(), 'i');\r\n filter.$or = searchFields.map((field) => ({ [field]: searchRegex }));\r\n }\r\n\r\n // Handle date range filtering\r\n if (startDate || endDate) {\r\n filter[dateField] = {};\r\n if (startDate) {\r\n (filter[dateField] as Record<string, unknown>).$gte = new Date(startDate);\r\n }\r\n if (endDate) {\r\n (filter[dateField] as Record<string, unknown>).$lte = new Date(endDate);\r\n }\r\n }\r\n\r\n // Handle status filter\r\n if (status !== undefined) {\r\n filter.status = status;\r\n }\r\n\r\n // Handle isActive filter\r\n if (isActive !== undefined) {\r\n filter.isActive = isActive;\r\n }\r\n\r\n // Add any additional filters\r\n Object.entries(additionalFilters).forEach(([key, value]) => {\r\n if (value !== undefined && value !== null && value !== '') {\r\n filter[key] = value;\r\n }\r\n });\r\n\r\n return filter;\r\n};\r\n\r\n/**\r\n * Calculate pagination values\r\n */\r\nexport const buildPagination = (options: PaginationOptions): PaginationResult => {\r\n const { page = 1, limit, defaultLimit = 10, maxLimit = 100 } = options;\r\n\r\n const finalPage = Math.max(1, page);\r\n const finalLimit = Math.min(maxLimit, Math.max(1, limit || defaultLimit));\r\n const skip = (finalPage - 1) * finalLimit;\r\n\r\n return {\r\n skip,\r\n limit: finalLimit,\r\n page: finalPage,\r\n };\r\n};\r\n\r\n/**\r\n * Calculate pagination metadata for response\r\n */\r\nexport const buildPaginationMeta = (\r\n total: number,\r\n page: number,\r\n limit: number\r\n): {\r\n total: number;\r\n page: number;\r\n limit: number;\r\n totalPages: number;\r\n hasNextPage: boolean;\r\n hasPrevPage: boolean;\r\n} => {\r\n const totalPages = Math.ceil(total / limit);\r\n\r\n return {\r\n total,\r\n page,\r\n limit,\r\n totalPages,\r\n hasNextPage: page < totalPages,\r\n hasPrevPage: page > 1,\r\n };\r\n};\r\n\r\nexport default {\r\n buildFilter,\r\n buildPagination,\r\n buildPaginationMeta,\r\n};\r\n","/**\r\n * Sanitize user object by removing sensitive fields\r\n */\r\nexport const sanitizeUser = <T extends Record<string, unknown>>(\r\n user: T | null | undefined,\r\n additionalFieldsToRemove: string[] = []\r\n): Omit<T, 'password' | '__v' | '_id'> | null => {\r\n if (!user) return null;\r\n\r\n const fieldsToRemove = ['password', '__v', '_id', ...additionalFieldsToRemove];\r\n\r\n // Handle mongoose documents\r\n const obj = typeof (user as any).toObject === 'function' \r\n ? (user as any).toObject() \r\n : { ...user };\r\n\r\n fieldsToRemove.forEach((field) => {\r\n delete obj[field];\r\n });\r\n\r\n return obj;\r\n};\r\n\r\n/**\r\n * Sanitize document by removing specified fields\r\n */\r\nexport const sanitizeDocument = <T extends Record<string, unknown>>(\r\n doc: T | null | undefined,\r\n fieldsToRemove: string[]\r\n): Partial<T> | null => {\r\n if (!doc) return null;\r\n\r\n // Handle mongoose documents\r\n const obj = typeof (doc as any).toObject === 'function' \r\n ? (doc as any).toObject() \r\n : { ...doc };\r\n\r\n fieldsToRemove.forEach((field) => {\r\n delete obj[field];\r\n });\r\n\r\n return obj;\r\n};\r\n\r\n/**\r\n * Pick specific fields from an object\r\n */\r\nexport const pickFields = <T extends Record<string, unknown>>(\r\n obj: T | null | undefined,\r\n fieldsToPick: (keyof T)[]\r\n): Partial<T> | null => {\r\n if (!obj) return null;\r\n\r\n const result: Partial<T> = {};\r\n\r\n fieldsToPick.forEach((field) => {\r\n if (field in obj) {\r\n result[field] = obj[field];\r\n }\r\n });\r\n\r\n return result;\r\n};\r\n\r\n/**\r\n * Omit specific fields from an object\r\n */\r\nexport const omitFields = <T extends Record<string, unknown>, K extends keyof T>(\r\n obj: T | null | undefined,\r\n fieldsToOmit: K[]\r\n): Omit<T, K> | null => {\r\n if (!obj) return null;\r\n\r\n const result = { ...obj };\r\n\r\n fieldsToOmit.forEach((field) => {\r\n delete result[field];\r\n });\r\n\r\n return result as Omit<T, K>;\r\n};\r\n\r\nexport default {\r\n sanitizeUser,\r\n sanitizeDocument,\r\n pickFields,\r\n omitFields,\r\n};\r\n","/**\r\n * Package Check Utility - Server/Node.js Version\r\n * Analyzes package.json dependencies and checks for updates\r\n * \r\n * This version supports reading from file paths using Node.js fs\r\n */\r\nimport { readFileSync, existsSync } from 'fs';\r\nimport { resolve } from 'path';\r\n\r\nexport interface PackageVersion {\r\n name: string;\r\n current: string;\r\n latest: string;\r\n hasUpdate: boolean;\r\n updateType: 'major' | 'minor' | 'patch' | 'prerelease' | 'none';\r\n dependencyType: 'dependencies' | 'devDependencies' | 'peerDependencies' | 'optionalDependencies';\r\n}\r\n\r\nexport interface PackageCheckResult {\r\n packageName: string;\r\n packageVersion: string;\r\n totalDependencies: number;\r\n outdatedCount: number;\r\n dependencies: PackageVersion[];\r\n byType: {\r\n dependencies: PackageVersion[];\r\n devDependencies: PackageVersion[];\r\n peerDependencies: PackageVersion[];\r\n optionalDependencies: PackageVersion[];\r\n };\r\n byUpdateType: {\r\n major: PackageVersion[];\r\n minor: PackageVersion[];\r\n patch: PackageVersion[];\r\n prerelease: PackageVersion[];\r\n };\r\n checkedAt: Date;\r\n errors: string[];\r\n}\r\n\r\nexport interface PackageJson {\r\n name?: string;\r\n version?: string;\r\n dependencies?: Record<string, string>;\r\n devDependencies?: Record<string, string>;\r\n peerDependencies?: Record<string, string>;\r\n optionalDependencies?: Record<string, string>;\r\n}\r\n\r\n/**\r\n * Parse version string, removing range operators\r\n */\r\nfunction parseVersion(version: string): string {\r\n return version.replace(/[\\^~>=<|*x\\s]/g, '').split(' ')[0] || '0.0.0';\r\n}\r\n\r\n/**\r\n * Compare two semver versions\r\n */\r\nfunction compareVersions(current: string, latest: string): 'major' | 'minor' | 'patch' | 'prerelease' | 'none' {\r\n const currentClean = parseVersion(current);\r\n const latestClean = parseVersion(latest);\r\n\r\n if (currentClean === latestClean) return 'none';\r\n\r\n const [curMajor, curMinor, curPatch] = currentClean.split('.').map(Number);\r\n const [latMajor, latMinor, latPatch] = latestClean.split('.').map(Number);\r\n\r\n if (latest.includes('-')) return 'prerelease';\r\n if (latMajor > curMajor) return 'major';\r\n if (latMinor > curMinor) return 'minor';\r\n if (latPatch > curPatch) return 'patch';\r\n\r\n return 'none';\r\n}\r\n\r\n/**\r\n * Fetch latest version from npm registry\r\n */\r\nasync function fetchLatestVersion(packageName: string): Promise<string | null> {\r\n try {\r\n const encodedName = packageName.startsWith('@')\r\n ? `@${encodeURIComponent(packageName.slice(1))}`\r\n : encodeURIComponent(packageName);\r\n\r\n const response = await fetch(`https://registry.npmjs.org/${encodedName}`);\r\n\r\n if (!response.ok) return null;\r\n\r\n const data = await response.json();\r\n return data['dist-tags']?.latest || null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Load package.json from file path, URL, or object\r\n */\r\nasync function loadPackageJson(source: string | PackageJson): Promise<PackageJson> {\r\n if (typeof source === 'object') {\r\n return source;\r\n }\r\n\r\n // URL\r\n if (source.startsWith('http://') || source.startsWith('https://')) {\r\n const response = await fetch(source);\r\n if (!response.ok) {\r\n throw new Error(`Failed to fetch: ${response.status}`);\r\n }\r\n return response.json() as Promise<PackageJson>;\r\n }\r\n\r\n // File path\r\n const filePath = resolve(source);\r\n if (!existsSync(filePath)) {\r\n throw new Error(`File not found: ${filePath}`);\r\n }\r\n\r\n const content = readFileSync(filePath, 'utf-8');\r\n return JSON.parse(content) as PackageJson;\r\n}\r\n\r\n/**\r\n * Check dependencies\r\n */\r\nasync function checkDeps(\r\n deps: Record<string, string> | undefined,\r\n type: PackageVersion['dependencyType'],\r\n errors: string[]\r\n): Promise<PackageVersion[]> {\r\n if (!deps) return [];\r\n\r\n const results: PackageVersion[] = [];\r\n const entries = Object.entries(deps);\r\n\r\n const concurrencyLimit = 10;\r\n for (let i = 0; i < entries.length; i += concurrencyLimit) {\r\n const batch = entries.slice(i, i + concurrencyLimit);\r\n const batchResults = await Promise.all(\r\n batch.map(async ([name, currentVersion]) => {\r\n try {\r\n const latest = await fetchLatestVersion(name);\r\n\r\n if (!latest) {\r\n errors.push(`Could not fetch: ${name}`);\r\n return {\r\n name,\r\n current: currentVersion,\r\n latest: 'unknown',\r\n hasUpdate: false,\r\n updateType: 'none' as const,\r\n dependencyType: type,\r\n };\r\n }\r\n\r\n const updateType = compareVersions(currentVersion, latest);\r\n\r\n return {\r\n name,\r\n current: currentVersion,\r\n latest,\r\n hasUpdate: updateType !== 'none',\r\n updateType,\r\n dependencyType: type,\r\n };\r\n } catch (err) {\r\n errors.push(`Error: ${name} - ${err}`);\r\n return {\r\n name,\r\n current: currentVersion,\r\n latest: 'error',\r\n hasUpdate: false,\r\n updateType: 'none' as const,\r\n dependencyType: type,\r\n };\r\n }\r\n })\r\n );\r\n results.push(...batchResults);\r\n }\r\n\r\n return results;\r\n}\r\n\r\n/**\r\n * Check package.json for outdated dependencies\r\n * \r\n * @example\r\n * // From file path\r\n * const result = await checkPackageServer('./package.json');\r\n * \r\n * @example\r\n * // From URL\r\n * const result = await checkPackageServer('https://raw.githubusercontent.com/user/repo/main/package.json');\r\n */\r\nexport async function checkPackageServer(\r\n source: string | PackageJson\r\n): Promise<PackageCheckResult> {\r\n const errors: string[] = [];\r\n const pkg = await loadPackageJson(source);\r\n\r\n const [dependencies, devDependencies, peerDependencies, optionalDependencies] =\r\n await Promise.all([\r\n checkDeps(pkg.dependencies, 'dependencies', errors),\r\n checkDeps(pkg.devDependencies, 'devDependencies', errors),\r\n checkDeps(pkg.peerDependencies, 'peerDependencies', errors),\r\n checkDeps(pkg.optionalDependencies, 'optionalDependencies', errors),\r\n ]);\r\n\r\n const allDeps = [...dependencies, ...devDependencies, ...peerDependencies, ...optionalDependencies];\r\n\r\n return {\r\n packageName: pkg.name || 'unknown',\r\n packageVersion: pkg.version || '0.0.0',\r\n totalDependencies: allDeps.length,\r\n outdatedCount: allDeps.filter((d) => d.hasUpdate).length,\r\n dependencies: allDeps,\r\n byType: { dependencies, devDependencies, peerDependencies, optionalDependencies },\r\n byUpdateType: {\r\n major: allDeps.filter((d) => d.updateType === 'major'),\r\n minor: allDeps.filter((d) => d.updateType === 'minor'),\r\n patch: allDeps.filter((d) => d.updateType === 'patch'),\r\n prerelease: allDeps.filter((d) => d.updateType === 'prerelease'),\r\n },\r\n checkedAt: new Date(),\r\n errors,\r\n };\r\n}\r\n\r\n/**\r\n * Format result as colored console output\r\n */\r\nexport function formatPackageCheckResult(result: PackageCheckResult): string {\r\n const lines: string[] = [];\r\n\r\n lines.push(`\\n📦 Package: ${result.packageName}@${result.packageVersion}`);\r\n lines.push(`📅 Checked: ${result.checkedAt.toISOString()}`);\r\n lines.push(`📊 Total: ${result.totalDependencies} | Outdated: ${result.outdatedCount}\\n`);\r\n\r\n const formatDep = (d: PackageVersion) => ` ${d.name.padEnd(35)} ${d.current.padEnd(15)} → ${d.latest}`;\r\n\r\n if (result.byUpdateType.major.length > 0) {\r\n lines.push('🔴 MAJOR Updates:');\r\n result.byUpdateType.major.forEach((d) => lines.push(formatDep(d)));\r\n lines.push('');\r\n }\r\n\r\n if (result.byUpdateType.minor.length > 0) {\r\n lines.push('🟡 MINOR Updates:');\r\n result.byUpdateType.minor.forEach((d) => lines.push(formatDep(d)));\r\n lines.push('');\r\n }\r\n\r\n if (result.byUpdateType.patch.length > 0) {\r\n lines.push('🟢 PATCH Updates:');\r\n result.byUpdateType.patch.forEach((d) => lines.push(formatDep(d)));\r\n lines.push('');\r\n }\r\n\r\n if (result.errors.length > 0) {\r\n lines.push('⚠️ Errors:');\r\n result.errors.forEach((e) => lines.push(` ${e}`));\r\n }\r\n\r\n return lines.join('\\n');\r\n}\r\n\r\n/**\r\n * Generate ncu command\r\n */\r\nexport function generateNcuCommand(\r\n result: PackageCheckResult,\r\n options: { updateType?: 'major' | 'minor' | 'patch' | 'all'; interactive?: boolean; upgrade?: boolean } = {}\r\n): string {\r\n const { updateType = 'all', interactive = false, upgrade = false } = options;\r\n\r\n let packages: string[] = [];\r\n\r\n switch (updateType) {\r\n case 'major':\r\n packages = result.byUpdateType.major.map((d) => d.name);\r\n break;\r\n case 'minor':\r\n packages = result.byUpdateType.minor.map((d) => d.name);\r\n break;\r\n case 'patch':\r\n packages = result.byUpdateType.patch.map((d) => d.name);\r\n break;\r\n default:\r\n packages = result.dependencies.filter((d) => d.hasUpdate).map((d) => d.name);\r\n }\r\n\r\n if (packages.length === 0) return '# No updates available';\r\n\r\n let cmd = 'npx npm-check-updates';\r\n\r\n if (packages.length < result.dependencies.length) {\r\n cmd += ` --filter \"${packages.join(',')}\"`;\r\n }\r\n\r\n if (interactive) cmd += ' --interactive';\r\n if (upgrade) cmd += ' --upgrade';\r\n\r\n return cmd;\r\n}\r\n\r\n/**\r\n * Print summary to console\r\n */\r\nexport function printPackageCheckSummary(result: PackageCheckResult): void {\r\n console.log(formatPackageCheckResult(result));\r\n\r\n if (result.outdatedCount > 0) {\r\n console.log('\\n📝 Quick Commands:');\r\n console.log(' Check all: npx npm-check-updates');\r\n console.log(' Interactive: npx npm-check-updates --interactive');\r\n console.log(' Update all: npx npm-check-updates --upgrade && npm install');\r\n\r\n if (result.byUpdateType.patch.length > 0) {\r\n console.log(` Patch only: ${generateNcuCommand(result, { updateType: 'patch', upgrade: true })}`);\r\n }\r\n }\r\n}\r\n\r\nexport const packageCheckServer = {\r\n check: checkPackageServer,\r\n format: formatPackageCheckResult,\r\n generateNcuCommand,\r\n print: printPackageCheckSummary,\r\n} as const;\r\n\r\nexport default packageCheckServer;\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/server/utils/filter-builder.ts","../../../src/server/utils/sanitize.ts","../../../src/server/utils/packageCheck.ts","../../../src/server/utils/health.ts"],"names":["resolve","existsSync","readFileSync","path","fs","os"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Filter Builder Options\r\n */\r\nexport interface FilterOptions {\r\n organizationId?: string;\r\n search?: string;\r\n searchFields?: string[];\r\n dateField?: string;\r\n startDate?: string;\r\n endDate?: string;\r\n status?: string;\r\n isActive?: boolean;\r\n [key: string]: unknown;\r\n}\r\n\r\n/**\r\n * Pagination Options\r\n */\r\nexport interface PaginationOptions {\r\n page?: number;\r\n limit?: number;\r\n defaultLimit?: number;\r\n maxLimit?: number;\r\n}\r\n\r\n/**\r\n * Pagination Result\r\n */\r\nexport interface PaginationResult {\r\n skip: number;\r\n limit: number;\r\n page: number;\r\n}\r\n\r\n/**\r\n * Build MongoDB filter query dynamically\r\n */\r\nexport const buildFilter = (options: FilterOptions): Record<string, unknown> => {\r\n const {\r\n organizationId,\r\n search,\r\n searchFields = [],\r\n dateField = 'createdAt',\r\n startDate,\r\n endDate,\r\n status,\r\n isActive,\r\n ...additionalFilters\r\n } = options;\r\n\r\n const filter: Record<string, unknown> = {};\r\n\r\n // Add organizationId if provided\r\n if (organizationId) {\r\n filter.organizationId = organizationId;\r\n }\r\n\r\n // Handle text search with regex (min 2 characters)\r\n if (search && search.trim().length >= 2 && searchFields.length > 0) {\r\n const searchRegex = new RegExp(search.trim(), 'i');\r\n filter.$or = searchFields.map((field) => ({ [field]: searchRegex }));\r\n }\r\n\r\n // Handle date range filtering\r\n if (startDate || endDate) {\r\n filter[dateField] = {};\r\n if (startDate) {\r\n (filter[dateField] as Record<string, unknown>).$gte = new Date(startDate);\r\n }\r\n if (endDate) {\r\n (filter[dateField] as Record<string, unknown>).$lte = new Date(endDate);\r\n }\r\n }\r\n\r\n // Handle status filter\r\n if (status !== undefined) {\r\n filter.status = status;\r\n }\r\n\r\n // Handle isActive filter\r\n if (isActive !== undefined) {\r\n filter.isActive = isActive;\r\n }\r\n\r\n // Add any additional filters\r\n Object.entries(additionalFilters).forEach(([key, value]) => {\r\n if (value !== undefined && value !== null && value !== '') {\r\n filter[key] = value;\r\n }\r\n });\r\n\r\n return filter;\r\n};\r\n\r\n/**\r\n * Calculate pagination values\r\n */\r\nexport const buildPagination = (options: PaginationOptions): PaginationResult => {\r\n const { page = 1, limit, defaultLimit = 10, maxLimit = 100 } = options;\r\n\r\n const finalPage = Math.max(1, page);\r\n const finalLimit = Math.min(maxLimit, Math.max(1, limit || defaultLimit));\r\n const skip = (finalPage - 1) * finalLimit;\r\n\r\n return {\r\n skip,\r\n limit: finalLimit,\r\n page: finalPage,\r\n };\r\n};\r\n\r\n/**\r\n * Calculate pagination metadata for response\r\n */\r\nexport const buildPaginationMeta = (\r\n total: number,\r\n page: number,\r\n limit: number\r\n): {\r\n total: number;\r\n page: number;\r\n limit: number;\r\n totalPages: number;\r\n hasNextPage: boolean;\r\n hasPrevPage: boolean;\r\n} => {\r\n const totalPages = Math.ceil(total / limit);\r\n\r\n return {\r\n total,\r\n page,\r\n limit,\r\n totalPages,\r\n hasNextPage: page < totalPages,\r\n hasPrevPage: page > 1,\r\n };\r\n};\r\n\r\nexport default {\r\n buildFilter,\r\n buildPagination,\r\n buildPaginationMeta,\r\n};\r\n","/**\r\n * Sanitize user object by removing sensitive fields\r\n */\r\nexport const sanitizeUser = <T extends Record<string, unknown>>(\r\n user: T | null | undefined,\r\n additionalFieldsToRemove: string[] = []\r\n): Omit<T, 'password' | '__v' | '_id'> | null => {\r\n if (!user) return null;\r\n\r\n const fieldsToRemove = ['password', '__v', '_id', ...additionalFieldsToRemove];\r\n\r\n // Handle mongoose documents\r\n const obj = typeof (user as any).toObject === 'function' \r\n ? (user as any).toObject() \r\n : { ...user };\r\n\r\n fieldsToRemove.forEach((field) => {\r\n delete obj[field];\r\n });\r\n\r\n return obj;\r\n};\r\n\r\n/**\r\n * Sanitize document by removing specified fields\r\n */\r\nexport const sanitizeDocument = <T extends Record<string, unknown>>(\r\n doc: T | null | undefined,\r\n fieldsToRemove: string[]\r\n): Partial<T> | null => {\r\n if (!doc) return null;\r\n\r\n // Handle mongoose documents\r\n const obj = typeof (doc as any).toObject === 'function' \r\n ? (doc as any).toObject() \r\n : { ...doc };\r\n\r\n fieldsToRemove.forEach((field) => {\r\n delete obj[field];\r\n });\r\n\r\n return obj;\r\n};\r\n\r\n/**\r\n * Pick specific fields from an object\r\n */\r\nexport const pickFields = <T extends Record<string, unknown>>(\r\n obj: T | null | undefined,\r\n fieldsToPick: (keyof T)[]\r\n): Partial<T> | null => {\r\n if (!obj) return null;\r\n\r\n const result: Partial<T> = {};\r\n\r\n fieldsToPick.forEach((field) => {\r\n if (field in obj) {\r\n result[field] = obj[field];\r\n }\r\n });\r\n\r\n return result;\r\n};\r\n\r\n/**\r\n * Omit specific fields from an object\r\n */\r\nexport const omitFields = <T extends Record<string, unknown>, K extends keyof T>(\r\n obj: T | null | undefined,\r\n fieldsToOmit: K[]\r\n): Omit<T, K> | null => {\r\n if (!obj) return null;\r\n\r\n const result = { ...obj };\r\n\r\n fieldsToOmit.forEach((field) => {\r\n delete result[field];\r\n });\r\n\r\n return result as Omit<T, K>;\r\n};\r\n\r\nexport default {\r\n sanitizeUser,\r\n sanitizeDocument,\r\n pickFields,\r\n omitFields,\r\n};\r\n","/**\r\n * Package Check Utility - Server/Node.js Version\r\n * Analyzes package.json dependencies and checks for updates\r\n * \r\n * This version supports reading from file paths using Node.js fs\r\n */\r\nimport { readFileSync, existsSync } from 'fs';\r\nimport { resolve } from 'path';\r\n\r\nexport interface PackageVersion {\r\n name: string;\r\n current: string;\r\n latest: string;\r\n hasUpdate: boolean;\r\n updateType: 'major' | 'minor' | 'patch' | 'prerelease' | 'none';\r\n dependencyType: 'dependencies' | 'devDependencies' | 'peerDependencies' | 'optionalDependencies';\r\n}\r\n\r\nexport interface PackageCheckResult {\r\n packageName: string;\r\n packageVersion: string;\r\n totalDependencies: number;\r\n outdatedCount: number;\r\n dependencies: PackageVersion[];\r\n byType: {\r\n dependencies: PackageVersion[];\r\n devDependencies: PackageVersion[];\r\n peerDependencies: PackageVersion[];\r\n optionalDependencies: PackageVersion[];\r\n };\r\n byUpdateType: {\r\n major: PackageVersion[];\r\n minor: PackageVersion[];\r\n patch: PackageVersion[];\r\n prerelease: PackageVersion[];\r\n };\r\n checkedAt: Date;\r\n errors: string[];\r\n}\r\n\r\nexport interface PackageJson {\r\n name?: string;\r\n version?: string;\r\n dependencies?: Record<string, string>;\r\n devDependencies?: Record<string, string>;\r\n peerDependencies?: Record<string, string>;\r\n optionalDependencies?: Record<string, string>;\r\n}\r\n\r\n/**\r\n * Parse version string, removing range operators\r\n */\r\nfunction parseVersion(version: string): string {\r\n return version.replace(/[\\^~>=<|*x\\s]/g, '').split(' ')[0] || '0.0.0';\r\n}\r\n\r\n/**\r\n * Compare two semver versions\r\n */\r\nfunction compareVersions(current: string, latest: string): 'major' | 'minor' | 'patch' | 'prerelease' | 'none' {\r\n const currentClean = parseVersion(current);\r\n const latestClean = parseVersion(latest);\r\n\r\n if (currentClean === latestClean) return 'none';\r\n\r\n const [curMajor, curMinor, curPatch] = currentClean.split('.').map(Number);\r\n const [latMajor, latMinor, latPatch] = latestClean.split('.').map(Number);\r\n\r\n if (latest.includes('-')) return 'prerelease';\r\n if (latMajor > curMajor) return 'major';\r\n if (latMinor > curMinor) return 'minor';\r\n if (latPatch > curPatch) return 'patch';\r\n\r\n return 'none';\r\n}\r\n\r\n/**\r\n * Fetch latest version from npm registry\r\n */\r\nasync function fetchLatestVersion(packageName: string): Promise<string | null> {\r\n try {\r\n const encodedName = packageName.startsWith('@')\r\n ? `@${encodeURIComponent(packageName.slice(1))}`\r\n : encodeURIComponent(packageName);\r\n\r\n const response = await fetch(`https://registry.npmjs.org/${encodedName}`);\r\n\r\n if (!response.ok) return null;\r\n\r\n const data = await response.json();\r\n return data['dist-tags']?.latest || null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Load package.json from file path, URL, or object\r\n */\r\nasync function loadPackageJson(source: string | PackageJson): Promise<PackageJson> {\r\n if (typeof source === 'object') {\r\n return source;\r\n }\r\n\r\n // URL\r\n if (source.startsWith('http://') || source.startsWith('https://')) {\r\n const response = await fetch(source);\r\n if (!response.ok) {\r\n throw new Error(`Failed to fetch: ${response.status}`);\r\n }\r\n return response.json() as Promise<PackageJson>;\r\n }\r\n\r\n // File path\r\n const filePath = resolve(source);\r\n if (!existsSync(filePath)) {\r\n throw new Error(`File not found: ${filePath}`);\r\n }\r\n\r\n const content = readFileSync(filePath, 'utf-8');\r\n return JSON.parse(content) as PackageJson;\r\n}\r\n\r\n/**\r\n * Check dependencies\r\n */\r\nasync function checkDeps(\r\n deps: Record<string, string> | undefined,\r\n type: PackageVersion['dependencyType'],\r\n errors: string[]\r\n): Promise<PackageVersion[]> {\r\n if (!deps) return [];\r\n\r\n const results: PackageVersion[] = [];\r\n const entries = Object.entries(deps);\r\n\r\n const concurrencyLimit = 10;\r\n for (let i = 0; i < entries.length; i += concurrencyLimit) {\r\n const batch = entries.slice(i, i + concurrencyLimit);\r\n const batchResults = await Promise.all(\r\n batch.map(async ([name, currentVersion]) => {\r\n try {\r\n const latest = await fetchLatestVersion(name);\r\n\r\n if (!latest) {\r\n errors.push(`Could not fetch: ${name}`);\r\n return {\r\n name,\r\n current: currentVersion,\r\n latest: 'unknown',\r\n hasUpdate: false,\r\n updateType: 'none' as const,\r\n dependencyType: type,\r\n };\r\n }\r\n\r\n const updateType = compareVersions(currentVersion, latest);\r\n\r\n return {\r\n name,\r\n current: currentVersion,\r\n latest,\r\n hasUpdate: updateType !== 'none',\r\n updateType,\r\n dependencyType: type,\r\n };\r\n } catch (err) {\r\n errors.push(`Error: ${name} - ${err}`);\r\n return {\r\n name,\r\n current: currentVersion,\r\n latest: 'error',\r\n hasUpdate: false,\r\n updateType: 'none' as const,\r\n dependencyType: type,\r\n };\r\n }\r\n })\r\n );\r\n results.push(...batchResults);\r\n }\r\n\r\n return results;\r\n}\r\n\r\n/**\r\n * Check package.json for outdated dependencies\r\n * \r\n * @example\r\n * // From file path\r\n * const result = await checkPackageServer('./package.json');\r\n * \r\n * @example\r\n * // From URL\r\n * const result = await checkPackageServer('https://raw.githubusercontent.com/user/repo/main/package.json');\r\n */\r\nexport async function checkPackageServer(\r\n source: string | PackageJson\r\n): Promise<PackageCheckResult> {\r\n const errors: string[] = [];\r\n const pkg = await loadPackageJson(source);\r\n\r\n const [dependencies, devDependencies, peerDependencies, optionalDependencies] =\r\n await Promise.all([\r\n checkDeps(pkg.dependencies, 'dependencies', errors),\r\n checkDeps(pkg.devDependencies, 'devDependencies', errors),\r\n checkDeps(pkg.peerDependencies, 'peerDependencies', errors),\r\n checkDeps(pkg.optionalDependencies, 'optionalDependencies', errors),\r\n ]);\r\n\r\n const allDeps = [...dependencies, ...devDependencies, ...peerDependencies, ...optionalDependencies];\r\n\r\n return {\r\n packageName: pkg.name || 'unknown',\r\n packageVersion: pkg.version || '0.0.0',\r\n totalDependencies: allDeps.length,\r\n outdatedCount: allDeps.filter((d) => d.hasUpdate).length,\r\n dependencies: allDeps,\r\n byType: { dependencies, devDependencies, peerDependencies, optionalDependencies },\r\n byUpdateType: {\r\n major: allDeps.filter((d) => d.updateType === 'major'),\r\n minor: allDeps.filter((d) => d.updateType === 'minor'),\r\n patch: allDeps.filter((d) => d.updateType === 'patch'),\r\n prerelease: allDeps.filter((d) => d.updateType === 'prerelease'),\r\n },\r\n checkedAt: new Date(),\r\n errors,\r\n };\r\n}\r\n\r\n/**\r\n * Format result as colored console output\r\n */\r\nexport function formatPackageCheckResult(result: PackageCheckResult): string {\r\n const lines: string[] = [];\r\n\r\n lines.push(`\\n📦 Package: ${result.packageName}@${result.packageVersion}`);\r\n lines.push(`📅 Checked: ${result.checkedAt.toISOString()}`);\r\n lines.push(`📊 Total: ${result.totalDependencies} | Outdated: ${result.outdatedCount}\\n`);\r\n\r\n const formatDep = (d: PackageVersion) => ` ${d.name.padEnd(35)} ${d.current.padEnd(15)} → ${d.latest}`;\r\n\r\n if (result.byUpdateType.major.length > 0) {\r\n lines.push('🔴 MAJOR Updates:');\r\n result.byUpdateType.major.forEach((d) => lines.push(formatDep(d)));\r\n lines.push('');\r\n }\r\n\r\n if (result.byUpdateType.minor.length > 0) {\r\n lines.push('🟡 MINOR Updates:');\r\n result.byUpdateType.minor.forEach((d) => lines.push(formatDep(d)));\r\n lines.push('');\r\n }\r\n\r\n if (result.byUpdateType.patch.length > 0) {\r\n lines.push('🟢 PATCH Updates:');\r\n result.byUpdateType.patch.forEach((d) => lines.push(formatDep(d)));\r\n lines.push('');\r\n }\r\n\r\n if (result.errors.length > 0) {\r\n lines.push('⚠️ Errors:');\r\n result.errors.forEach((e) => lines.push(` ${e}`));\r\n }\r\n\r\n return lines.join('\\n');\r\n}\r\n\r\n/**\r\n * Generate ncu command\r\n */\r\nexport function generateNcuCommand(\r\n result: PackageCheckResult,\r\n options: { updateType?: 'major' | 'minor' | 'patch' | 'all'; interactive?: boolean; upgrade?: boolean } = {}\r\n): string {\r\n const { updateType = 'all', interactive = false, upgrade = false } = options;\r\n\r\n let packages: string[] = [];\r\n\r\n switch (updateType) {\r\n case 'major':\r\n packages = result.byUpdateType.major.map((d) => d.name);\r\n break;\r\n case 'minor':\r\n packages = result.byUpdateType.minor.map((d) => d.name);\r\n break;\r\n case 'patch':\r\n packages = result.byUpdateType.patch.map((d) => d.name);\r\n break;\r\n default:\r\n packages = result.dependencies.filter((d) => d.hasUpdate).map((d) => d.name);\r\n }\r\n\r\n if (packages.length === 0) return '# No updates available';\r\n\r\n let cmd = 'npx npm-check-updates';\r\n\r\n if (packages.length < result.dependencies.length) {\r\n cmd += ` --filter \"${packages.join(',')}\"`;\r\n }\r\n\r\n if (interactive) cmd += ' --interactive';\r\n if (upgrade) cmd += ' --upgrade';\r\n\r\n return cmd;\r\n}\r\n\r\n/**\r\n * Print summary to console\r\n */\r\nexport function printPackageCheckSummary(result: PackageCheckResult): void {\r\n console.log(formatPackageCheckResult(result));\r\n\r\n if (result.outdatedCount > 0) {\r\n console.log('\\n📝 Quick Commands:');\r\n console.log(' Check all: npx npm-check-updates');\r\n console.log(' Interactive: npx npm-check-updates --interactive');\r\n console.log(' Update all: npx npm-check-updates --upgrade && npm install');\r\n\r\n if (result.byUpdateType.patch.length > 0) {\r\n console.log(` Patch only: ${generateNcuCommand(result, { updateType: 'patch', upgrade: true })}`);\r\n }\r\n }\r\n}\r\n\r\nexport const packageCheckServer = {\r\n check: checkPackageServer,\r\n format: formatPackageCheckResult,\r\n generateNcuCommand,\r\n print: printPackageCheckSummary,\r\n} as const;\r\n\r\nexport default packageCheckServer;\r\n","/**\r\n * Standardized Health Check Response Generator\r\n * \r\n * Provides consistent health check responses across all Exyconn microservices\r\n */\r\n\r\nimport os from 'os';\r\nimport { Request, Response } from 'express';\r\nimport fs from 'fs';\r\nimport path from 'path';\r\n\r\n/**\r\n * Service configuration for health check\r\n */\r\nexport interface HealthConfig {\r\n /** Service name (e.g., 'exyconn-auth-server') */\r\n name: string;\r\n /** App version from package.json */\r\n version: string;\r\n /** Port the service runs on */\r\n port: number | string;\r\n /** Production domain (e.g., 'exyconn-auth-server.exyconn.com') */\r\n domain: string;\r\n /** Description of the service */\r\n description?: string;\r\n /** UI URL if applicable */\r\n uiUrl?: string;\r\n /** Server/API URL */\r\n serverUrl?: string;\r\n /** Dependencies status check function */\r\n checkDependencies?: () => Promise<Record<string, 'UP' | 'DOWN' | 'UNKNOWN'>>;\r\n /** List of critical packages to show in response */\r\n criticalPackages?: string[];\r\n /** Cloud infrastructure info */\r\n infra?: {\r\n cloud: string;\r\n region: string;\r\n zone?: string;\r\n };\r\n}\r\n\r\n/**\r\n * Standardized health response structure\r\n */\r\nexport interface HealthResponse {\r\n status: 'UP' | 'DOWN' | 'DEGRADED';\r\n app: string;\r\n env: string;\r\n version: string;\r\n \r\n urls: {\r\n ui?: string;\r\n server: string;\r\n health: string;\r\n };\r\n\r\n time: {\r\n serverTime: string;\r\n timezone: string;\r\n offset: string;\r\n epoch: number;\r\n };\r\n\r\n uptimeSec: number;\r\n\r\n node: {\r\n version: string;\r\n platform: string;\r\n arch: string;\r\n };\r\n\r\n system: {\r\n hostname: string;\r\n memoryUsedMB: number;\r\n memoryTotalMB: number;\r\n memoryFreePercent: number;\r\n cpuLoad: number[];\r\n cpuCount: number;\r\n };\r\n\r\n packages: {\r\n appVersion: string;\r\n totalDependencies: number;\r\n critical: Record<string, string>;\r\n };\r\n\r\n dependencies: Record<string, 'UP' | 'DOWN' | 'UNKNOWN'>;\r\n\r\n infra?: {\r\n cloud: string;\r\n region: string;\r\n zone?: string;\r\n };\r\n\r\n responseTimeMs: number;\r\n}\r\n\r\n// Store server start time\r\nconst serverStartTime = Date.now();\r\n\r\n/**\r\n * Get timezone offset string (e.g., '+05:30')\r\n */\r\nfunction getTimezoneOffset(): string {\r\n const offset = new Date().getTimezoneOffset();\r\n const hours = Math.floor(Math.abs(offset) / 60);\r\n const minutes = Math.abs(offset) % 60;\r\n const sign = offset <= 0 ? '+' : '-';\r\n return `${sign}${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;\r\n}\r\n\r\n/**\r\n * Get timezone name\r\n */\r\nfunction getTimezoneName(): string {\r\n try {\r\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\r\n } catch {\r\n return 'UTC';\r\n }\r\n}\r\n\r\n/**\r\n * Read package.json to get dependencies info\r\n */\r\nfunction getPackageInfo(criticalPackages: string[] = []): { total: number; critical: Record<string, string> } {\r\n try {\r\n // Try multiple paths to find package.json\r\n const possiblePaths = [\r\n path.join(process.cwd(), 'package.json'),\r\n path.join(__dirname, '..', '..', '..', '..', 'package.json'),\r\n path.join(__dirname, '..', '..', 'package.json'),\r\n ];\r\n \r\n for (const pkgPath of possiblePaths) {\r\n if (fs.existsSync(pkgPath)) {\r\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));\r\n const deps = pkg.dependencies || {};\r\n const devDeps = pkg.devDependencies || {};\r\n const total = Object.keys(deps).length + Object.keys(devDeps).length;\r\n \r\n const critical: Record<string, string> = {};\r\n for (const pkgName of criticalPackages) {\r\n if (deps[pkgName]) {\r\n critical[pkgName] = deps[pkgName].replace('^', '').replace('~', '');\r\n }\r\n }\r\n \r\n return { total, critical };\r\n }\r\n }\r\n } catch {\r\n // Ignore errors\r\n }\r\n \r\n return { total: 0, critical: {} };\r\n}\r\n\r\n/**\r\n * Generate standardized health response\r\n */\r\nexport async function generateHealthResponse(config: HealthConfig): Promise<HealthResponse> {\r\n const startTime = Date.now();\r\n const now = new Date();\r\n \r\n // Get dependencies status\r\n let dependencies: Record<string, 'UP' | 'DOWN' | 'UNKNOWN'> = {};\r\n if (config.checkDependencies) {\r\n try {\r\n dependencies = await config.checkDependencies();\r\n } catch {\r\n dependencies = { error: 'DOWN' };\r\n }\r\n }\r\n \r\n // Determine overall status\r\n const hasDownDep = Object.values(dependencies).includes('DOWN');\r\n const status: 'UP' | 'DOWN' | 'DEGRADED' = hasDownDep ? 'DEGRADED' : 'UP';\r\n \r\n // Get package info\r\n const defaultCriticalPackages = ['express', 'mongoose', 'cors', 'dotenv'];\r\n const packageInfo = getPackageInfo(config.criticalPackages || defaultCriticalPackages);\r\n \r\n // Memory info\r\n const totalMem = os.totalmem();\r\n const freeMem = os.freemem();\r\n const usedMem = totalMem - freeMem;\r\n \r\n // Build server URL\r\n const isProduction = process.env.NODE_ENV === 'production';\r\n const serverUrl = isProduction \r\n ? `https://${config.domain}`\r\n : `http://localhost:${config.port}`;\r\n \r\n const response: HealthResponse = {\r\n status,\r\n app: config.name,\r\n env: process.env.NODE_ENV || 'development',\r\n version: config.version,\r\n \r\n urls: {\r\n ...(config.uiUrl && { ui: config.uiUrl }),\r\n server: config.serverUrl || serverUrl,\r\n health: `${config.serverUrl || serverUrl}/health`,\r\n },\r\n \r\n time: {\r\n serverTime: now.toISOString(),\r\n timezone: getTimezoneName(),\r\n offset: getTimezoneOffset(),\r\n epoch: Math.floor(now.getTime() / 1000),\r\n },\r\n \r\n uptimeSec: Math.floor((Date.now() - serverStartTime) / 1000),\r\n \r\n node: {\r\n version: process.version,\r\n platform: os.platform(),\r\n arch: os.arch(),\r\n },\r\n \r\n system: {\r\n hostname: os.hostname(),\r\n memoryUsedMB: Math.round(usedMem / 1024 / 1024),\r\n memoryTotalMB: Math.round(totalMem / 1024 / 1024),\r\n memoryFreePercent: Math.round((freeMem / totalMem) * 100),\r\n cpuLoad: os.loadavg().map(l => Math.round(l * 100) / 100),\r\n cpuCount: os.cpus().length,\r\n },\r\n \r\n packages: {\r\n appVersion: config.version,\r\n totalDependencies: packageInfo.total,\r\n critical: packageInfo.critical,\r\n },\r\n \r\n dependencies,\r\n \r\n ...(config.infra && { infra: config.infra }),\r\n \r\n responseTimeMs: Date.now() - startTime,\r\n };\r\n \r\n return response;\r\n}\r\n\r\n/**\r\n * Create Express health check handler\r\n */\r\nexport function createHealthHandler(config: HealthConfig) {\r\n return async (_req: Request, res: Response) => {\r\n try {\r\n const health = await generateHealthResponse(config);\r\n const statusCode = health.status === 'UP' ? 200 : health.status === 'DEGRADED' ? 200 : 503;\r\n res.status(statusCode).json(health);\r\n } catch (error) {\r\n res.status(503).json({\r\n status: 'DOWN',\r\n app: config.name,\r\n env: process.env.NODE_ENV || 'development',\r\n version: config.version,\r\n error: error instanceof Error ? error.message : 'Unknown error',\r\n time: {\r\n serverTime: new Date().toISOString(),\r\n timezone: getTimezoneName(),\r\n offset: getTimezoneOffset(),\r\n epoch: Math.floor(Date.now() / 1000),\r\n },\r\n });\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Create Express root handler (same as health but with welcome message)\r\n */\r\nexport function createRootHandler(config: HealthConfig & { endpoints?: Record<string, string> }) {\r\n return async (_req: Request, res: Response) => {\r\n try {\r\n const health = await generateHealthResponse(config);\r\n res.json({\r\n message: `Welcome to ${config.name}`,\r\n description: config.description || `${config.name} API Server`,\r\n ...(config.endpoints && { endpoints: config.endpoints }),\r\n ...health,\r\n });\r\n } catch (error) {\r\n res.status(503).json({\r\n status: 'DOWN',\r\n app: config.name,\r\n error: error instanceof Error ? error.message : 'Unknown error',\r\n });\r\n }\r\n };\r\n}\r\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from 'fs';
|
|
2
|
-
import { resolve } from 'path';
|
|
1
|
+
import fs, { existsSync, readFileSync } from 'fs';
|
|
2
|
+
import path, { resolve } from 'path';
|
|
3
|
+
import os from 'os';
|
|
3
4
|
|
|
4
5
|
// src/server/utils/filter-builder.ts
|
|
5
6
|
var buildFilter = (options) => {
|
|
@@ -294,7 +295,151 @@ var packageCheckServer = {
|
|
|
294
295
|
generateNcuCommand,
|
|
295
296
|
print: printPackageCheckSummary
|
|
296
297
|
};
|
|
298
|
+
var serverStartTime = Date.now();
|
|
299
|
+
function getTimezoneOffset() {
|
|
300
|
+
const offset = (/* @__PURE__ */ new Date()).getTimezoneOffset();
|
|
301
|
+
const hours = Math.floor(Math.abs(offset) / 60);
|
|
302
|
+
const minutes = Math.abs(offset) % 60;
|
|
303
|
+
const sign = offset <= 0 ? "+" : "-";
|
|
304
|
+
return `${sign}${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
305
|
+
}
|
|
306
|
+
function getTimezoneName() {
|
|
307
|
+
try {
|
|
308
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
309
|
+
} catch {
|
|
310
|
+
return "UTC";
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
function getPackageInfo(criticalPackages = []) {
|
|
314
|
+
try {
|
|
315
|
+
const possiblePaths = [
|
|
316
|
+
path.join(process.cwd(), "package.json"),
|
|
317
|
+
path.join(__dirname, "..", "..", "..", "..", "package.json"),
|
|
318
|
+
path.join(__dirname, "..", "..", "package.json")
|
|
319
|
+
];
|
|
320
|
+
for (const pkgPath of possiblePaths) {
|
|
321
|
+
if (fs.existsSync(pkgPath)) {
|
|
322
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
323
|
+
const deps = pkg.dependencies || {};
|
|
324
|
+
const devDeps = pkg.devDependencies || {};
|
|
325
|
+
const total = Object.keys(deps).length + Object.keys(devDeps).length;
|
|
326
|
+
const critical = {};
|
|
327
|
+
for (const pkgName of criticalPackages) {
|
|
328
|
+
if (deps[pkgName]) {
|
|
329
|
+
critical[pkgName] = deps[pkgName].replace("^", "").replace("~", "");
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return { total, critical };
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
} catch {
|
|
336
|
+
}
|
|
337
|
+
return { total: 0, critical: {} };
|
|
338
|
+
}
|
|
339
|
+
async function generateHealthResponse(config) {
|
|
340
|
+
const startTime = Date.now();
|
|
341
|
+
const now = /* @__PURE__ */ new Date();
|
|
342
|
+
let dependencies = {};
|
|
343
|
+
if (config.checkDependencies) {
|
|
344
|
+
try {
|
|
345
|
+
dependencies = await config.checkDependencies();
|
|
346
|
+
} catch {
|
|
347
|
+
dependencies = { error: "DOWN" };
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
const hasDownDep = Object.values(dependencies).includes("DOWN");
|
|
351
|
+
const status = hasDownDep ? "DEGRADED" : "UP";
|
|
352
|
+
const defaultCriticalPackages = ["express", "mongoose", "cors", "dotenv"];
|
|
353
|
+
const packageInfo = getPackageInfo(config.criticalPackages || defaultCriticalPackages);
|
|
354
|
+
const totalMem = os.totalmem();
|
|
355
|
+
const freeMem = os.freemem();
|
|
356
|
+
const usedMem = totalMem - freeMem;
|
|
357
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
358
|
+
const serverUrl = isProduction ? `https://${config.domain}` : `http://localhost:${config.port}`;
|
|
359
|
+
const response = {
|
|
360
|
+
status,
|
|
361
|
+
app: config.name,
|
|
362
|
+
env: process.env.NODE_ENV || "development",
|
|
363
|
+
version: config.version,
|
|
364
|
+
urls: {
|
|
365
|
+
...config.uiUrl && { ui: config.uiUrl },
|
|
366
|
+
server: config.serverUrl || serverUrl,
|
|
367
|
+
health: `${config.serverUrl || serverUrl}/health`
|
|
368
|
+
},
|
|
369
|
+
time: {
|
|
370
|
+
serverTime: now.toISOString(),
|
|
371
|
+
timezone: getTimezoneName(),
|
|
372
|
+
offset: getTimezoneOffset(),
|
|
373
|
+
epoch: Math.floor(now.getTime() / 1e3)
|
|
374
|
+
},
|
|
375
|
+
uptimeSec: Math.floor((Date.now() - serverStartTime) / 1e3),
|
|
376
|
+
node: {
|
|
377
|
+
version: process.version,
|
|
378
|
+
platform: os.platform(),
|
|
379
|
+
arch: os.arch()
|
|
380
|
+
},
|
|
381
|
+
system: {
|
|
382
|
+
hostname: os.hostname(),
|
|
383
|
+
memoryUsedMB: Math.round(usedMem / 1024 / 1024),
|
|
384
|
+
memoryTotalMB: Math.round(totalMem / 1024 / 1024),
|
|
385
|
+
memoryFreePercent: Math.round(freeMem / totalMem * 100),
|
|
386
|
+
cpuLoad: os.loadavg().map((l) => Math.round(l * 100) / 100),
|
|
387
|
+
cpuCount: os.cpus().length
|
|
388
|
+
},
|
|
389
|
+
packages: {
|
|
390
|
+
appVersion: config.version,
|
|
391
|
+
totalDependencies: packageInfo.total,
|
|
392
|
+
critical: packageInfo.critical
|
|
393
|
+
},
|
|
394
|
+
dependencies,
|
|
395
|
+
...config.infra && { infra: config.infra },
|
|
396
|
+
responseTimeMs: Date.now() - startTime
|
|
397
|
+
};
|
|
398
|
+
return response;
|
|
399
|
+
}
|
|
400
|
+
function createHealthHandler(config) {
|
|
401
|
+
return async (_req, res) => {
|
|
402
|
+
try {
|
|
403
|
+
const health = await generateHealthResponse(config);
|
|
404
|
+
const statusCode = health.status === "UP" ? 200 : health.status === "DEGRADED" ? 200 : 503;
|
|
405
|
+
res.status(statusCode).json(health);
|
|
406
|
+
} catch (error) {
|
|
407
|
+
res.status(503).json({
|
|
408
|
+
status: "DOWN",
|
|
409
|
+
app: config.name,
|
|
410
|
+
env: process.env.NODE_ENV || "development",
|
|
411
|
+
version: config.version,
|
|
412
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
413
|
+
time: {
|
|
414
|
+
serverTime: (/* @__PURE__ */ new Date()).toISOString(),
|
|
415
|
+
timezone: getTimezoneName(),
|
|
416
|
+
offset: getTimezoneOffset(),
|
|
417
|
+
epoch: Math.floor(Date.now() / 1e3)
|
|
418
|
+
}
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
function createRootHandler(config) {
|
|
424
|
+
return async (_req, res) => {
|
|
425
|
+
try {
|
|
426
|
+
const health = await generateHealthResponse(config);
|
|
427
|
+
res.json({
|
|
428
|
+
message: `Welcome to ${config.name}`,
|
|
429
|
+
description: config.description || `${config.name} API Server`,
|
|
430
|
+
...config.endpoints && { endpoints: config.endpoints },
|
|
431
|
+
...health
|
|
432
|
+
});
|
|
433
|
+
} catch (error) {
|
|
434
|
+
res.status(503).json({
|
|
435
|
+
status: "DOWN",
|
|
436
|
+
app: config.name,
|
|
437
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
}
|
|
297
442
|
|
|
298
|
-
export { buildFilter, buildPagination, buildPaginationMeta, checkPackageServer, formatPackageCheckResult, generateNcuCommand, omitFields, packageCheckServer, pickFields, printPackageCheckSummary, sanitizeDocument, sanitizeUser };
|
|
443
|
+
export { buildFilter, buildPagination, buildPaginationMeta, checkPackageServer, createHealthHandler, createRootHandler, formatPackageCheckResult, generateHealthResponse, generateNcuCommand, omitFields, packageCheckServer, pickFields, printPackageCheckSummary, sanitizeDocument, sanitizeUser };
|
|
299
444
|
//# sourceMappingURL=index.mjs.map
|
|
300
445
|
//# sourceMappingURL=index.mjs.map
|