@adalo/metrics 0.1.134 → 0.1.136

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.
@@ -1 +1 @@
1
- {"version":3,"file":"databaseChecker.d.ts","sourceRoot":"","sources":["../../src/health/databaseChecker.js"],"names":[],"mappings":"AAKA;;;GAGG;AACH,qCAHW,MAAM,GACJ,MAAM,CAYlB;AAED;;;;GAIG;AACH,wCAJW,MAAM,8BAEJ;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAiBnG;AAED;;;;;GAKG;AACH,wCALW,MAAM,OACN,MAAM,uBACN,MAAM;UACI,GAAG;UAAQ,MAAM;EA+BrC;AAED;;;;GAIG;AACH,qCAJW,GAAG,QACH,MAAM,GACJ,QAAQ,IAAI,CAAC,CAQzB;AAED;;;GAGG;AACH,gCAHW,GAAG,GACD,QAAQ,IAAI,CAAC,CAQzB;AArGD,0CAAmC;AACnC,oCAA6B"}
1
+ {"version":3,"file":"databaseChecker.d.ts","sourceRoot":"","sources":["../../src/health/databaseChecker.js"],"names":[],"mappings":"AAMA;;;GAGG;AACH,qCAHW,MAAM,GACJ,MAAM,CAYlB;AAED;;;;GAIG;AACH,wCAJW,MAAM,8BAEJ;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAiBnG;AAED;;;;;GAKG;AACH,wCALW,MAAM,OACN,MAAM,uBACN,MAAM;UACI,GAAG;UAAQ,MAAM;EA8BrC;AAED;;;;GAIG;AACH,qCAJW,GAAG,QACH,MAAM,GACJ,QAAQ,IAAI,CAAC,CAQzB;AAED;;;GAGG;AACH,gCAHW,GAAG,GACD,QAAQ,IAAI,CAAC,CAQzB;AApGD,0CAAmC;AACnC,oCAA6B"}
@@ -3,6 +3,7 @@
3
3
  const {
4
4
  Pool
5
5
  } = require('pg');
6
+ const mysql = require('mysql2/promise');
6
7
  const DB_TYPE_POSTGRES = 'postgres';
7
8
  const DB_TYPE_MYSQL = 'mysql';
8
9
 
@@ -53,7 +54,6 @@ function parseConnectionUrl(url, type) {
53
54
  function createDatabasePool(env, url, connectionTimeoutMs) {
54
55
  const type = getDatabaseType(url);
55
56
  if (type === DB_TYPE_MYSQL) {
56
- const mysql = require('mysql2/promise');
57
57
  const config = parseConnectionUrl(url, DB_TYPE_MYSQL);
58
58
  if (!config) {
59
59
  throw new Error(`Invalid MySQL URL for ${env}`);
@@ -92,7 +92,7 @@ function createDatabasePool(env, url, connectionTimeoutMs) {
92
92
  */
93
93
  async function runHealthCheck(pool, type) {
94
94
  if (type === DB_TYPE_MYSQL) {
95
- const [rows] = await pool.execute('SELECT 1');
95
+ await pool.execute('SELECT 1');
96
96
  return;
97
97
  }
98
98
  await pool.query('SELECT 1');
@@ -1 +1 @@
1
- {"version":3,"file":"databaseChecker.js","names":["Pool","require","DB_TYPE_POSTGRES","DB_TYPE_MYSQL","getDatabaseType","url","lower","toLowerCase","startsWith","parseConnectionUrl","type","parsed","URL","defaultPort","defaultDb","host","hostname","port","parseInt","String","user","username","password","database","pathname","replace","createDatabasePool","env","connectionTimeoutMs","mysql","config","Error","pool","createPool","connectionLimit","connectTimeout","waitForConnections","connectionString","max","idleTimeoutMillis","connectionTimeoutMillis","runHealthCheck","rows","execute","query","closePool","end","module","exports"],"sources":["../../src/health/databaseChecker.js"],"sourcesContent":["const { Pool } = require('pg')\n\nconst DB_TYPE_POSTGRES = 'postgres'\nconst DB_TYPE_MYSQL = 'mysql'\n\n/**\n * @param {string} url\n * @returns {string} postgres | mysql\n */\nfunction getDatabaseType(url) {\n if (!url || typeof url !== 'string') return DB_TYPE_POSTGRES\n const lower = url.toLowerCase()\n if (lower.startsWith('mysql://') || lower.startsWith('mysql2://')) {\n return DB_TYPE_MYSQL\n }\n if (lower.startsWith('mariadb://')) {\n return DB_TYPE_MYSQL\n }\n return DB_TYPE_POSTGRES\n}\n\n/**\n * @param {string} url\n * @param {string} [type]\n * @returns {{ host: string, port: number, user: string, password: string, database: string } | null}\n */\nfunction parseConnectionUrl(url, type) {\n try {\n const parsed = new URL(url)\n const defaultPort = type === DB_TYPE_MYSQL ? 3306 : 5432\n const defaultDb = type === DB_TYPE_MYSQL ? 'mysql' : 'postgres'\n return {\n host: parsed.hostname || 'localhost',\n port: parseInt(parsed.port || String(defaultPort), 10),\n user: parsed.username || '',\n password: parsed.password || '',\n database: (parsed.pathname || '/').replace(/^\\//, '') || defaultDb,\n }\n } catch {\n return null\n }\n}\n\n/**\n * @param {string} env\n * @param {string} url\n * @param {number} connectionTimeoutMs\n * @returns {{ pool: any, type: string }}\n */\nfunction createDatabasePool(env, url, connectionTimeoutMs) {\n const type = getDatabaseType(url)\n\n if (type === DB_TYPE_MYSQL) {\n const mysql = require('mysql2/promise')\n const config = parseConnectionUrl(url, DB_TYPE_MYSQL)\n if (!config) {\n throw new Error(`Invalid MySQL URL for ${env}`)\n }\n const pool = mysql.createPool({\n host: config.host,\n port: config.port,\n user: config.user,\n password: config.password,\n database: config.database,\n connectionLimit: 1,\n connectTimeout: connectionTimeoutMs,\n waitForConnections: false,\n })\n return { pool, type: DB_TYPE_MYSQL }\n }\n\n const pool = new Pool({\n connectionString: url,\n max: 1,\n idleTimeoutMillis: 30000,\n connectionTimeoutMillis: connectionTimeoutMs,\n })\n return { pool, type: DB_TYPE_POSTGRES }\n}\n\n/**\n * @param {any} pool\n * @param {string} type\n * @returns {Promise<void>}\n */\nasync function runHealthCheck(pool, type) {\n if (type === DB_TYPE_MYSQL) {\n const [rows] = await pool.execute('SELECT 1')\n return\n }\n await pool.query('SELECT 1')\n}\n\n/**\n * @param {any} pool\n * @returns {Promise<void>}\n */\nasync function closePool(pool) {\n try {\n await pool.end()\n } catch {\n // ignore\n }\n}\n\nmodule.exports = {\n getDatabaseType,\n parseConnectionUrl,\n createDatabasePool,\n runHealthCheck,\n closePool,\n DB_TYPE_POSTGRES,\n DB_TYPE_MYSQL,\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"databaseChecker.js","names":["Pool","require","mysql","DB_TYPE_POSTGRES","DB_TYPE_MYSQL","getDatabaseType","url","lower","toLowerCase","startsWith","parseConnectionUrl","type","parsed","URL","defaultPort","defaultDb","host","hostname","port","parseInt","String","user","username","password","database","pathname","replace","createDatabasePool","env","connectionTimeoutMs","config","Error","pool","createPool","connectionLimit","connectTimeout","waitForConnections","connectionString","max","idleTimeoutMillis","connectionTimeoutMillis","runHealthCheck","execute","query","closePool","end","module","exports"],"sources":["../../src/health/databaseChecker.js"],"sourcesContent":["const { Pool } = require('pg')\nconst mysql = require('mysql2/promise')\n\nconst DB_TYPE_POSTGRES = 'postgres'\nconst DB_TYPE_MYSQL = 'mysql'\n\n/**\n * @param {string} url\n * @returns {string} postgres | mysql\n */\nfunction getDatabaseType(url) {\n if (!url || typeof url !== 'string') return DB_TYPE_POSTGRES\n const lower = url.toLowerCase()\n if (lower.startsWith('mysql://') || lower.startsWith('mysql2://')) {\n return DB_TYPE_MYSQL\n }\n if (lower.startsWith('mariadb://')) {\n return DB_TYPE_MYSQL\n }\n return DB_TYPE_POSTGRES\n}\n\n/**\n * @param {string} url\n * @param {string} [type]\n * @returns {{ host: string, port: number, user: string, password: string, database: string } | null}\n */\nfunction parseConnectionUrl(url, type) {\n try {\n const parsed = new URL(url)\n const defaultPort = type === DB_TYPE_MYSQL ? 3306 : 5432\n const defaultDb = type === DB_TYPE_MYSQL ? 'mysql' : 'postgres'\n return {\n host: parsed.hostname || 'localhost',\n port: parseInt(parsed.port || String(defaultPort), 10),\n user: parsed.username || '',\n password: parsed.password || '',\n database: (parsed.pathname || '/').replace(/^\\//, '') || defaultDb,\n }\n } catch {\n return null\n }\n}\n\n/**\n * @param {string} env\n * @param {string} url\n * @param {number} connectionTimeoutMs\n * @returns {{ pool: any, type: string }}\n */\nfunction createDatabasePool(env, url, connectionTimeoutMs) {\n const type = getDatabaseType(url)\n\n if (type === DB_TYPE_MYSQL) {\n const config = parseConnectionUrl(url, DB_TYPE_MYSQL)\n if (!config) {\n throw new Error(`Invalid MySQL URL for ${env}`)\n }\n const pool = mysql.createPool({\n host: config.host,\n port: config.port,\n user: config.user,\n password: config.password,\n database: config.database,\n connectionLimit: 1,\n connectTimeout: connectionTimeoutMs,\n waitForConnections: false,\n })\n return { pool, type: DB_TYPE_MYSQL }\n }\n\n const pool = new Pool({\n connectionString: url,\n max: 1,\n idleTimeoutMillis: 30000,\n connectionTimeoutMillis: connectionTimeoutMs,\n })\n return { pool, type: DB_TYPE_POSTGRES }\n}\n\n/**\n * @param {any} pool\n * @param {string} type\n * @returns {Promise<void>}\n */\nasync function runHealthCheck(pool, type) {\n if (type === DB_TYPE_MYSQL) {\n await pool.execute('SELECT 1')\n return\n }\n await pool.query('SELECT 1')\n}\n\n/**\n * @param {any} pool\n * @returns {Promise<void>}\n */\nasync function closePool(pool) {\n try {\n await pool.end()\n } catch {\n // ignore\n }\n}\n\nmodule.exports = {\n getDatabaseType,\n parseConnectionUrl,\n createDatabasePool,\n runHealthCheck,\n closePool,\n DB_TYPE_POSTGRES,\n DB_TYPE_MYSQL,\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"healthCheckCache.d.ts","sourceRoot":"","sources":["../../src/health/healthCheckCache.js"],"names":[],"mappings":"AAOA;;;;GAIG;AACH;IACE;;;;;;OAMG;IACH;QALyB,WAAW,GAAzB,GAAG;QACc,QAAQ;QACR,OAAO;QACP,gBAAgB;OAuB3C;IApBC,iBAA8C;IAC9C,gBACgE;IAChE,yBAA2D;IAC3D,iBACmD;IAEnD,+BAA+B;IAC/B,kBAAwB;IACxB,2BAAiC;IAG/B,qCAA4D;IAC5D,yBAA2B;IAS/B;;;;OAIG;IACH,6BAgCC;IAED;;;;;OAKG;IACH,OAHa,QAAQ,MAAM,GAAG,IAAI,CAAC,CAgDlC;IAED;;;;OAIG;IACH,YAHW,MAAM,GACJ,QAAQ,IAAI,CAAC,CAqCzB;IAED;;;OAGG;IACH,SAFa,QAAQ,IAAI,CAAC,CAyBzB;IAED;;;OAGG;IACH,oBAFa,OAAO,CAInB;CACF"}
1
+ {"version":3,"file":"healthCheckCache.d.ts","sourceRoot":"","sources":["../../src/health/healthCheckCache.js"],"names":[],"mappings":"AAOA;;;;GAIG;AACH;IACE;;;;;;OAMG;IACH;QALyB,WAAW,GAAzB,GAAG;QACc,QAAQ;QACR,OAAO;QACP,gBAAgB;OAsB3C;IAnBC,iBAA8C;IAC9C,gBACgE;IAChE,yBAA2D;IAC3D,iBAAiE;IAEjE,+BAA+B;IAC/B,kBAAwB;IACxB,2BAAiC;IAG/B,qCAA4D;IAC5D,yBAA2B;IAS/B;;;;OAIG;IACH,6BAgCC;IAED;;;;;OAKG;IACH,OAHa,QAAQ,MAAM,GAAG,IAAI,CAAC,CAgDlC;IAED;;;;OAIG;IACH,YAHW,MAAM,GACJ,QAAQ,IAAI,CAAC,CAqCzB;IAED;;;OAGG;IACH,SAFa,QAAQ,IAAI,CAAC,CAyBzB;IAED;;;OAGG;IACH,oBAFa,OAAO,CAInB;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"healthCheckCache.js","names":["getRedisClientType","REDIS_V4","IOREDIS","REDIS_V3","require","HealthCheckCache","constructor","options","redisClient","appName","process","env","BUILD_APP_NAME","staleThresholdMs","cacheKey","_memoryCache","_memoryCacheTimestamp","_redisClientType","_redisAvailable","console","warn","_checkRedisAvailable","pong","Promise","resolve","reject","ping","err","result","message","get","cachedStr","cached","JSON","parse","timestamp","parseErr","redisErr","Error","set","cacheData","Date","now","cacheStr","stringify","ttlSeconds","Math","ceil","setex","clear","del","isRedisAvailable","module","exports"],"sources":["../../src/health/healthCheckCache.js"],"sourcesContent":["const {\n getRedisClientType,\n REDIS_V4,\n IOREDIS,\n REDIS_V3,\n} = require('../redisUtils')\n\n/**\n * HealthCheckCache provides a shared cache layer for health check results.\n * It uses Redis if available for cross-process sharing, with graceful fallback\n * to in-memory cache if Redis is not configured or unavailable.\n */\nclass HealthCheckCache {\n /**\n * @param {Object} options\n * @param {any} [options.redisClient]\n * @param {string} [options.cacheKey] - Redis key (e.g. 'health:database:status')\n * @param {string} [options.appName] - Used when cacheKey not set: healthcheck:${appName}\n * @param {number} [options.staleThresholdMs]\n */\n constructor(options = {}) {\n this.redisClient = options.redisClient || null\n this.appName =\n options.appName || process.env.BUILD_APP_NAME || 'unknown-app'\n this.staleThresholdMs = options.staleThresholdMs ?? 180_000\n this.cacheKey =\n options.cacheKey || `healthcheck:${this.appName}`\n\n /** In-memory fallback cache */\n this._memoryCache = null\n this._memoryCacheTimestamp = null\n\n if (this.redisClient) {\n this._redisClientType = getRedisClientType(this.redisClient)\n this._redisAvailable = true\n } else {\n this._redisAvailable = false\n console.warn(\n `[HealthCheckCache] Redis not configured for ${this.appName}, using in-memory cache only (not shared across processes)`\n )\n }\n }\n\n /**\n * Checks if Redis is available and working.\n * @returns {Promise<boolean>}\n * @private\n */\n async _checkRedisAvailable() {\n if (!this.redisClient || !this._redisAvailable) {\n return false\n }\n\n try {\n let pong\n if (this._redisClientType === REDIS_V3) {\n pong = await new Promise((resolve, reject) => {\n this.redisClient.ping((err, result) => {\n if (err) reject(err)\n else resolve(result)\n })\n })\n } else if (\n this._redisClientType === REDIS_V4 ||\n this._redisClientType === IOREDIS\n ) {\n pong = await this.redisClient.ping()\n } else {\n return false\n }\n return pong === 'PONG'\n } catch (err) {\n if (this._redisAvailable) {\n console.warn(\n `[HealthCheckCache] Redis became unavailable: ${err.message}`\n )\n this._redisAvailable = false\n }\n return false\n }\n }\n\n /**\n * Gets cached health check result from Redis (if available) or in-memory cache.\n * Throws error if Redis is configured but read fails (so caller can return proper error format).\n * @returns {Promise<Object | null>} Cached result or null\n * @throws {Error} If Redis is configured but read fails\n */\n async get() {\n if (this.redisClient) {\n try {\n let cachedStr\n if (this._redisClientType === REDIS_V3) {\n cachedStr = await new Promise((resolve, reject) => {\n this.redisClient.get(this.cacheKey, (err, result) => {\n if (err) reject(err)\n else resolve(result)\n })\n })\n } else if (\n this._redisClientType === REDIS_V4 ||\n this._redisClientType === IOREDIS\n ) {\n cachedStr = await this.redisClient.get(this.cacheKey)\n }\n\n if (cachedStr) {\n try {\n const cached = JSON.parse(cachedStr)\n if (cached.result && cached.timestamp) {\n this._memoryCache = cached.result\n this._memoryCacheTimestamp = cached.timestamp\n return cached.result\n }\n } catch (parseErr) {\n console.warn(\n `[HealthCheckCache] Failed to parse Redis cache:`,\n parseErr.message\n )\n }\n }\n return null\n } catch (redisErr) {\n this._redisAvailable = false\n throw new Error(`Redis cache read failed: ${redisErr.message}`)\n }\n }\n\n if (this._memoryCache && this._memoryCacheTimestamp) {\n return this._memoryCache\n }\n\n return null\n }\n\n /**\n * Sets cached health check result in Redis (if available) and in-memory.\n * @param {Object} result - Health check result to cache\n * @returns {Promise<void>}\n */\n async set(result) {\n const cacheData = {\n result,\n timestamp: Date.now(),\n }\n\n this._memoryCache = result\n this._memoryCacheTimestamp = cacheData.timestamp\n\n if (await this._checkRedisAvailable()) {\n try {\n const cacheStr = JSON.stringify(cacheData)\n const ttlSeconds = Math.ceil(this.staleThresholdMs / 1000) + 60\n\n if (this._redisClientType === REDIS_V3) {\n await new Promise((resolve, reject) => {\n this.redisClient.setex(this.cacheKey, ttlSeconds, cacheStr, err => {\n if (err) reject(err)\n else resolve()\n })\n })\n } else if (\n this._redisClientType === REDIS_V4 ||\n this._redisClientType === IOREDIS\n ) {\n await this.redisClient.setex(this.cacheKey, ttlSeconds, cacheStr)\n }\n } catch (redisErr) {\n console.warn(\n `[HealthCheckCache] Redis write failed (in-memory cache updated):`,\n redisErr.message\n )\n this._redisAvailable = false\n }\n }\n }\n\n /**\n * Clears the cache (both Redis and in-memory).\n * @returns {Promise<void>}\n */\n async clear() {\n this._memoryCache = null\n this._memoryCacheTimestamp = null\n\n if (await this._checkRedisAvailable()) {\n try {\n if (this._redisClientType === REDIS_V3) {\n await new Promise((resolve, reject) => {\n this.redisClient.del(this.cacheKey, err => {\n if (err) reject(err)\n else resolve()\n })\n })\n } else if (\n this._redisClientType === REDIS_V4 ||\n this._redisClientType === IOREDIS\n ) {\n await this.redisClient.del(this.cacheKey)\n }\n } catch (redisErr) {\n console.warn(`[HealthCheckCache] Redis clear failed:`, redisErr.message)\n }\n }\n }\n\n /**\n * Checks if Redis is configured and available.\n * @returns {boolean}\n */\n isRedisAvailable() {\n return this._redisAvailable && this.redisClient !== null\n }\n}\n\nmodule.exports = { HealthCheckCache }\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"healthCheckCache.js","names":["getRedisClientType","REDIS_V4","IOREDIS","REDIS_V3","require","HealthCheckCache","constructor","options","redisClient","appName","process","env","BUILD_APP_NAME","staleThresholdMs","cacheKey","_memoryCache","_memoryCacheTimestamp","_redisClientType","_redisAvailable","console","warn","_checkRedisAvailable","pong","Promise","resolve","reject","ping","err","result","message","get","cachedStr","cached","JSON","parse","timestamp","parseErr","redisErr","Error","set","cacheData","Date","now","cacheStr","stringify","ttlSeconds","Math","ceil","setex","clear","del","isRedisAvailable","module","exports"],"sources":["../../src/health/healthCheckCache.js"],"sourcesContent":["const {\n getRedisClientType,\n REDIS_V4,\n IOREDIS,\n REDIS_V3,\n} = require('../redisUtils')\n\n/**\n * HealthCheckCache provides a shared cache layer for health check results.\n * It uses Redis if available for cross-process sharing, with graceful fallback\n * to in-memory cache if Redis is not configured or unavailable.\n */\nclass HealthCheckCache {\n /**\n * @param {Object} options\n * @param {any} [options.redisClient]\n * @param {string} [options.cacheKey] - Redis key (e.g. 'health:database:status')\n * @param {string} [options.appName] - Used when cacheKey not set: healthcheck:${appName}\n * @param {number} [options.staleThresholdMs]\n */\n constructor(options = {}) {\n this.redisClient = options.redisClient || null\n this.appName =\n options.appName || process.env.BUILD_APP_NAME || 'unknown-app'\n this.staleThresholdMs = options.staleThresholdMs ?? 180_000\n this.cacheKey = options.cacheKey || `healthcheck:${this.appName}`\n\n /** In-memory fallback cache */\n this._memoryCache = null\n this._memoryCacheTimestamp = null\n\n if (this.redisClient) {\n this._redisClientType = getRedisClientType(this.redisClient)\n this._redisAvailable = true\n } else {\n this._redisAvailable = false\n console.warn(\n `[HealthCheckCache] Redis not configured for ${this.appName}, using in-memory cache only (not shared across processes)`\n )\n }\n }\n\n /**\n * Checks if Redis is available and working.\n * @returns {Promise<boolean>}\n * @private\n */\n async _checkRedisAvailable() {\n if (!this.redisClient || !this._redisAvailable) {\n return false\n }\n\n try {\n let pong\n if (this._redisClientType === REDIS_V3) {\n pong = await new Promise((resolve, reject) => {\n this.redisClient.ping((err, result) => {\n if (err) reject(err)\n else resolve(result)\n })\n })\n } else if (\n this._redisClientType === REDIS_V4 ||\n this._redisClientType === IOREDIS\n ) {\n pong = await this.redisClient.ping()\n } else {\n return false\n }\n return pong === 'PONG'\n } catch (err) {\n if (this._redisAvailable) {\n console.warn(\n `[HealthCheckCache] Redis became unavailable: ${err.message}`\n )\n this._redisAvailable = false\n }\n return false\n }\n }\n\n /**\n * Gets cached health check result from Redis (if available) or in-memory cache.\n * Throws error if Redis is configured but read fails (so caller can return proper error format).\n * @returns {Promise<Object | null>} Cached result or null\n * @throws {Error} If Redis is configured but read fails\n */\n async get() {\n if (this.redisClient) {\n try {\n let cachedStr\n if (this._redisClientType === REDIS_V3) {\n cachedStr = await new Promise((resolve, reject) => {\n this.redisClient.get(this.cacheKey, (err, result) => {\n if (err) reject(err)\n else resolve(result)\n })\n })\n } else if (\n this._redisClientType === REDIS_V4 ||\n this._redisClientType === IOREDIS\n ) {\n cachedStr = await this.redisClient.get(this.cacheKey)\n }\n\n if (cachedStr) {\n try {\n const cached = JSON.parse(cachedStr)\n if (cached.result && cached.timestamp) {\n this._memoryCache = cached.result\n this._memoryCacheTimestamp = cached.timestamp\n return cached.result\n }\n } catch (parseErr) {\n console.warn(\n `[HealthCheckCache] Failed to parse Redis cache:`,\n parseErr.message\n )\n }\n }\n return null\n } catch (redisErr) {\n this._redisAvailable = false\n throw new Error(`Redis cache read failed: ${redisErr.message}`)\n }\n }\n\n if (this._memoryCache && this._memoryCacheTimestamp) {\n return this._memoryCache\n }\n\n return null\n }\n\n /**\n * Sets cached health check result in Redis (if available) and in-memory.\n * @param {Object} result - Health check result to cache\n * @returns {Promise<void>}\n */\n async set(result) {\n const cacheData = {\n result,\n timestamp: Date.now(),\n }\n\n this._memoryCache = result\n this._memoryCacheTimestamp = cacheData.timestamp\n\n if (await this._checkRedisAvailable()) {\n try {\n const cacheStr = JSON.stringify(cacheData)\n const ttlSeconds = Math.ceil(this.staleThresholdMs / 1000) + 60\n\n if (this._redisClientType === REDIS_V3) {\n await new Promise((resolve, reject) => {\n this.redisClient.setex(this.cacheKey, ttlSeconds, cacheStr, err => {\n if (err) reject(err)\n else resolve()\n })\n })\n } else if (\n this._redisClientType === REDIS_V4 ||\n this._redisClientType === IOREDIS\n ) {\n await this.redisClient.setex(this.cacheKey, ttlSeconds, cacheStr)\n }\n } catch (redisErr) {\n console.warn(\n `[HealthCheckCache] Redis write failed (in-memory cache updated):`,\n redisErr.message\n )\n this._redisAvailable = false\n }\n }\n }\n\n /**\n * Clears the cache (both Redis and in-memory).\n * @returns {Promise<void>}\n */\n async clear() {\n this._memoryCache = null\n this._memoryCacheTimestamp = null\n\n if (await this._checkRedisAvailable()) {\n try {\n if (this._redisClientType === REDIS_V3) {\n await new Promise((resolve, reject) => {\n this.redisClient.del(this.cacheKey, err => {\n if (err) reject(err)\n else resolve()\n })\n })\n } else if (\n this._redisClientType === REDIS_V4 ||\n this._redisClientType === IOREDIS\n ) {\n await this.redisClient.del(this.cacheKey)\n }\n } catch (redisErr) {\n console.warn(`[HealthCheckCache] Redis clear failed:`, redisErr.message)\n }\n }\n }\n\n /**\n * Checks if Redis is configured and available.\n * @returns {boolean}\n */\n isRedisAvailable() {\n return this._redisAvailable && this.redisClient !== null\n }\n}\n\nmodule.exports = { HealthCheckCache }\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"healthCheckClient.d.ts","sourceRoot":"","sources":["../../src/health/healthCheckClient.js"],"names":[],"mappings":"6BAgEa;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,GAAG,CAAA;CAAE;AAD1E;;GAEG;AACH;IACE;;;;;;OAMG;IACH;QALqC,SAAS,EAAnC,cAAc,EAAE;QACC,MAAM;QACN,OAAO;QACP,QAAQ;OA2BnC;IAxBC;;;;;;;;;;;MAAmE;IACnE,gBACgE;IAEhE,mBAAmD;IAEnD,qBAA2B;IAC3B,uDAAuD;IACvD;cAD+B,GAAG;cAAQ,MAAM;OACjB;IAE/B,+BAA+B;IAC/B,YADW,cAAc,EAAE,CACc;IAIvC,qCAAuD;IAGzD,yBAKE;IAGJ,4BAEC;IAED,+BAGC;IAED;cA5BiC,GAAG;cAAQ,MAAM;kBAsCjD;IAED;;;;;;OAiBC;IAED;;;;;;OA0BC;IAED;;;;;;;;;;;;;;;;;OA8BC;IAED,kDAeC;IAED,mCAgBC;IAED,gCAiBC;IAED;;;;;;;;;;;;;;;;;OAIC;IAED,mBAEC;IAED,uDAiCC;IAED,yBASC;CACF;AAzSD,4FAA4F;AAC5F,oCADW;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAKvF"}
1
+ {"version":3,"file":"healthCheckClient.d.ts","sourceRoot":"","sources":["../../src/health/healthCheckClient.js"],"names":[],"mappings":"6BA6Da;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,GAAG,CAAA;CAAE;AAD1E;;GAEG;AACH;IACE;;;;;;OAMG;IACH;QALqC,SAAS,EAAnC,cAAc,EAAE;QACC,MAAM;QACN,OAAO;QACP,QAAQ;OA2BnC;IAxBC;;;;;;;;;;;MAAmE;IACnE,gBACgE;IAEhE,mBAAmD;IAEnD,qBAA2B;IAC3B,uDAAuD;IACvD;cAD+B,GAAG;cAAQ,MAAM;OACjB;IAE/B,+BAA+B;IAC/B,YADW,cAAc,EAAE,CACc;IAIvC,qCAAuD;IAGzD,yBAKE;IAGJ,4BAEC;IAED,+BAGC;IAED;cA5BiC,GAAG;cAAQ,MAAM;kBAsCjD;IAED;;;;;;OAiBC;IAED;;;;;;OA4BC;IAED;;;;;;;;;;;;;;;;;OA8BC;IAED,kDAeC;IAED,mCAgBC;IAED,gCAiBC;IAED;;;;;;;;;;;;;;;;;OAIC;IAED,mBAEC;IAED,uDAiCC;IAED,yBASC;CACF;AA3SD,4FAA4F;AAC5F,oCADW;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAKvF"}
@@ -4,7 +4,7 @@ const {
4
4
  createDatabasePool,
5
5
  runHealthCheck,
6
6
  closePool
7
- } = require('./databaseChecker');
7
+ } = require('./databaseChecker').default;
8
8
  const {
9
9
  getRedisClientType,
10
10
  REDIS_V4,
@@ -281,8 +281,7 @@ class HealthCheckClient {
281
281
  }
282
282
  async cleanup() {
283
283
  for (const [, {
284
- pool,
285
- type
284
+ pool
286
285
  }] of this._databasePools) {
287
286
  try {
288
287
  await closePool(pool);
@@ -1 +1 @@
1
- {"version":3,"file":"healthCheckClient.js","names":["createDatabasePool","runHealthCheck","closePool","require","getRedisClientType","REDIS_V4","IOREDIS","REDIS_V3","HealthCheckCache","DEFAULT_HEALTH_CONFIG","checkIntervalMs","staleThresholdMs","checkTimeoutMs","SENSITIVE_PATTERNS","pattern","replacement","maskSensitiveData","text","masked","replace","HealthCheckClient","constructor","options","healthConfig","config","appName","process","env","BUILD_APP_NAME","prefixLogs","_refreshPromise","_databasePools","Map","_resources","resources","redisClient","_getRedisClientForCache","_redisClientType","_cache","cacheKey","_getEnv","resource","name","redisResource","find","r","client","_getPool","url","has","pool","type","set","get","_checkDatabase","status","error","err","message","_checkRedis","pong","Promise","resolve","reject","ping","result","_performHealthCheckInternal","sortedResources","Object","keys","sort","reduce","acc","key","hasError","values","some","lastCheckAt","Date","now","isStale","_formatResult","cached","performHealthCheck","then","catch","getCachedResult","console","refreshCache","clearCache","healthHandler","req","res","json","statusCode","cleanup","clear","module","exports"],"sources":["../../src/health/healthCheckClient.js"],"sourcesContent":["const {\n createDatabasePool,\n runHealthCheck,\n closePool,\n} = require('./databaseChecker')\nconst {\n getRedisClientType,\n REDIS_V4,\n IOREDIS,\n REDIS_V3,\n} = require('../redisUtils')\nconst { HealthCheckCache } = require('./healthCheckCache')\n\n/** @type {{ checkIntervalMs: number, staleThresholdMs: number, checkTimeoutMs: number }} */\nconst DEFAULT_HEALTH_CONFIG = {\n checkIntervalMs: 30_000,\n staleThresholdMs: 180_000,\n checkTimeoutMs: 15_000,\n}\n\nconst SENSITIVE_PATTERNS = [\n {\n pattern:\n /(postgres(?:ql)?|mysql|mongodb|redis|amqp):\\/\\/([^:]+):([^@]+)@([^:/]+)(:\\d+)?\\/([^\\s?]+)/gi,\n replacement: '$1://***:***@***$5/***',\n },\n {\n pattern: /(\\w+):\\/\\/([^:]+):([^@]+)@([^\\s/]+)/gi,\n replacement: '$1://***:***@***',\n },\n {\n pattern:\n /(password|passwd|pwd|secret|token|api[_-]?key|auth[_-]?token)[\"\\s]*[:=][\"\\s]*([^\\s,}\"]+)/gi,\n replacement: '$1=***',\n },\n {\n pattern:\n /(database|table|schema|role|user|relation|column|index)\\s*[\"']([^\"']+)[\"']/gi,\n replacement: '$1 \"***\"',\n },\n {\n pattern: /\\b(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})(:\\d+)?\\b/g,\n replacement: '***$2',\n },\n {\n pattern: /\\b(host|hostname|server)[\"\\s]*[:=][\"\\s]*([^\\s,}\"]+)/gi,\n replacement: '$1=***',\n },\n]\n\n/**\n * @param {string} text\n * @returns {string}\n */\nfunction maskSensitiveData(text) {\n if (!text || typeof text !== 'string') return text\n let masked = text\n for (const { pattern, replacement } of SENSITIVE_PATTERNS) {\n masked = masked.replace(pattern, replacement)\n }\n return masked\n}\n\n/**\n * @typedef {{ env: string, url?: string } | { env: string, client?: any }} HealthResource\n */\nclass HealthCheckClient {\n /**\n * @param {Object} options\n * @param {HealthResource[]} options.resources - Must include Redis resource with client\n * @param {Object} [options.config]\n * @param {string} [options.appName] - For cache key: healthcheck:${appName}\n * @param {string} [options.cacheKey] - Redis key (overrides appName)\n */\n constructor(options = {}) {\n this.healthConfig = { ...DEFAULT_HEALTH_CONFIG, ...options.config }\n this.appName =\n options.appName || process.env.BUILD_APP_NAME || 'unknown-app'\n\n this.prefixLogs = `[${this.appName}] [HealthCheck]`\n\n this._refreshPromise = null\n /** @type {Map<string, { pool: any, type: string }>} */\n this._databasePools = new Map()\n\n /** @type {HealthResource[]} */\n this._resources = options.resources || []\n\n const redisClient = this._getRedisClientForCache()\n if (redisClient) {\n this._redisClientType = getRedisClientType(redisClient)\n }\n\n this._cache = new HealthCheckCache({\n redisClient: redisClient || null,\n cacheKey: options.cacheKey,\n appName: this.appName,\n staleThresholdMs: this.healthConfig.staleThresholdMs,\n })\n }\n\n _getEnv(resource) {\n return resource.env ?? resource.name\n }\n\n _getRedisClientForCache() {\n const redisResource = this._resources.find(r => 'client' in r && r.client)\n return redisResource?.client || null\n }\n\n _getPool(env, url) {\n if (!this._databasePools.has(env)) {\n const { pool, type } = createDatabasePool(\n env,\n url,\n this.healthConfig.checkTimeoutMs\n )\n this._databasePools.set(env, { pool, type })\n }\n return this._databasePools.get(env)\n }\n\n async _checkDatabase(resource) {\n const env = this._getEnv(resource)\n const url = 'url' in resource ? resource.url : process.env[env]\n if (!url) {\n return { status: 'error', error: `Env ${env} not set` }\n }\n\n try {\n const { pool, type } = this._getPool(env, url)\n await runHealthCheck(pool, type)\n return { status: 'ok' }\n } catch (err) {\n return {\n status: 'error',\n error: maskSensitiveData(err.message),\n }\n }\n }\n\n async _checkRedis(resource) {\n const { client } = resource\n if (!client) return { status: 'ok' }\n\n try {\n let pong\n if (this._redisClientType === REDIS_V3) {\n pong = await new Promise((resolve, reject) => {\n client.ping((err, result) => {\n if (err) reject(err)\n else resolve(result)\n })\n })\n } else if (\n this._redisClientType === REDIS_V4 ||\n this._redisClientType === IOREDIS\n ) {\n pong = await client.ping()\n } else {\n return { status: 'error', error: 'Unknown Redis client type' }\n }\n\n return pong === 'PONG' ? { status: 'ok' } : { status: 'error', error: `Unexpected: ${pong}` }\n } catch (err) {\n return { status: 'error', error: maskSensitiveData(err.message) }\n }\n }\n\n async _performHealthCheckInternal() {\n const resources = {}\n\n for (const resource of this._resources) {\n const env = this._getEnv(resource)\n\n if ('client' in resource && resource.client) {\n resources[env] = await this._checkRedis(resource)\n } else {\n resources[env] = await this._checkDatabase(resource)\n }\n }\n\n const sortedResources = Object.keys(resources)\n .sort()\n .reduce((acc, key) => {\n acc[key] = resources[key]\n return acc\n }, {})\n\n const hasError = Object.values(resources).some(r => r.status === 'error')\n const lastCheckAt = Date.now()\n\n return {\n status: hasError ? 'error' : 'ok',\n lastCheckAt,\n resources: sortedResources,\n isStale: false,\n config: this.healthConfig,\n }\n }\n\n _formatResult(result, cached = false) {\n const isStale =\n !result.lastCheckAt ||\n Date.now() - result.lastCheckAt > this.healthConfig.staleThresholdMs\n\n return {\n ...result,\n isStale,\n status: isStale ? 'stale' : result.status,\n ...(isStale && {\n error:\n 'Health check data is stale, health-check worker may not be running. Resource statuses are unknown.',\n }),\n ...(cached && { cached: true }),\n }\n }\n\n async performHealthCheck() {\n if (this._refreshPromise) {\n return this._refreshPromise\n }\n\n this._refreshPromise = this._performHealthCheckInternal()\n .then(result => {\n this._refreshPromise = null\n return this._formatResult(result)\n })\n .catch(err => {\n this._refreshPromise = null\n throw err\n })\n\n return this._refreshPromise\n }\n\n async getCachedResult() {\n try {\n const cached = await this._cache.get()\n if (cached) return this._formatResult(cached)\n return null\n } catch (err) {\n console.error(`${this.prefixLogs} Failed to read from cache:`, err)\n return {\n status: 'error',\n lastCheckAt: null,\n resources: {},\n isStale: true,\n error:\n 'Redis unavailable, unable to read health status of other resources',\n config: this.healthConfig,\n }\n }\n }\n\n async refreshCache() {\n const result = await this._performHealthCheckInternal()\n await this._cache.set(result)\n return result\n }\n\n clearCache() {\n this._refreshPromise = null\n }\n\n healthHandler() {\n return async (req, res) => {\n try {\n const result = await this.getCachedResult()\n\n if (!result) {\n res.status(503).json({\n status: 'error',\n lastCheckAt: null,\n resources: {},\n isStale: true,\n error:\n 'No health check data yet, health-check worker may not be running',\n config: this.healthConfig,\n })\n return\n }\n\n const statusCode = result.status === 'ok' ? 200 : 503\n res.status(statusCode).json(result)\n } catch (err) {\n console.error(`${this.prefixLogs} Health check failed:`, err)\n res.status(503).json({\n status: 'error',\n lastCheckAt: null,\n resources: {},\n isStale: true,\n error:\n 'Redis unavailable, unable to read health status of other resources',\n config: this.healthConfig,\n })\n }\n }\n }\n\n async cleanup() {\n for (const [, { pool, type }] of this._databasePools) {\n try {\n await closePool(pool)\n } catch (err) {\n console.error(`${this.prefixLogs} Error closing database pool:`, err)\n }\n }\n this._databasePools.clear()\n }\n}\n\nmodule.exports = { HealthCheckClient, DEFAULT_HEALTH_CONFIG }\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"healthCheckClient.js","names":["createDatabasePool","runHealthCheck","closePool","require","default","getRedisClientType","REDIS_V4","IOREDIS","REDIS_V3","HealthCheckCache","DEFAULT_HEALTH_CONFIG","checkIntervalMs","staleThresholdMs","checkTimeoutMs","SENSITIVE_PATTERNS","pattern","replacement","maskSensitiveData","text","masked","replace","HealthCheckClient","constructor","options","healthConfig","config","appName","process","env","BUILD_APP_NAME","prefixLogs","_refreshPromise","_databasePools","Map","_resources","resources","redisClient","_getRedisClientForCache","_redisClientType","_cache","cacheKey","_getEnv","resource","name","redisResource","find","r","client","_getPool","url","has","pool","type","set","get","_checkDatabase","status","error","err","message","_checkRedis","pong","Promise","resolve","reject","ping","result","_performHealthCheckInternal","sortedResources","Object","keys","sort","reduce","acc","key","hasError","values","some","lastCheckAt","Date","now","isStale","_formatResult","cached","performHealthCheck","then","catch","getCachedResult","console","refreshCache","clearCache","healthHandler","req","res","json","statusCode","cleanup","clear","module","exports"],"sources":["../../src/health/healthCheckClient.js"],"sourcesContent":["const { createDatabasePool, runHealthCheck, closePool } =\n require('./databaseChecker').default\nconst {\n getRedisClientType,\n REDIS_V4,\n IOREDIS,\n REDIS_V3,\n} = require('../redisUtils')\nconst { HealthCheckCache } = require('./healthCheckCache')\n\n/** @type {{ checkIntervalMs: number, staleThresholdMs: number, checkTimeoutMs: number }} */\nconst DEFAULT_HEALTH_CONFIG = {\n checkIntervalMs: 30_000,\n staleThresholdMs: 180_000,\n checkTimeoutMs: 15_000,\n}\n\nconst SENSITIVE_PATTERNS = [\n {\n pattern:\n /(postgres(?:ql)?|mysql|mongodb|redis|amqp):\\/\\/([^:]+):([^@]+)@([^:/]+)(:\\d+)?\\/([^\\s?]+)/gi,\n replacement: '$1://***:***@***$5/***',\n },\n {\n pattern: /(\\w+):\\/\\/([^:]+):([^@]+)@([^\\s/]+)/gi,\n replacement: '$1://***:***@***',\n },\n {\n pattern:\n /(password|passwd|pwd|secret|token|api[_-]?key|auth[_-]?token)[\"\\s]*[:=][\"\\s]*([^\\s,}\"]+)/gi,\n replacement: '$1=***',\n },\n {\n pattern:\n /(database|table|schema|role|user|relation|column|index)\\s*[\"']([^\"']+)[\"']/gi,\n replacement: '$1 \"***\"',\n },\n {\n pattern: /\\b(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})(:\\d+)?\\b/g,\n replacement: '***$2',\n },\n {\n pattern: /\\b(host|hostname|server)[\"\\s]*[:=][\"\\s]*([^\\s,}\"]+)/gi,\n replacement: '$1=***',\n },\n]\n\n/**\n * @param {string} text\n * @returns {string}\n */\nfunction maskSensitiveData(text) {\n if (!text || typeof text !== 'string') return text\n let masked = text\n for (const { pattern, replacement } of SENSITIVE_PATTERNS) {\n masked = masked.replace(pattern, replacement)\n }\n return masked\n}\n\n/**\n * @typedef {{ env: string, url?: string } | { env: string, client?: any }} HealthResource\n */\nclass HealthCheckClient {\n /**\n * @param {Object} options\n * @param {HealthResource[]} options.resources - Must include Redis resource with client\n * @param {Object} [options.config]\n * @param {string} [options.appName] - For cache key: healthcheck:${appName}\n * @param {string} [options.cacheKey] - Redis key (overrides appName)\n */\n constructor(options = {}) {\n this.healthConfig = { ...DEFAULT_HEALTH_CONFIG, ...options.config }\n this.appName =\n options.appName || process.env.BUILD_APP_NAME || 'unknown-app'\n\n this.prefixLogs = `[${this.appName}] [HealthCheck]`\n\n this._refreshPromise = null\n /** @type {Map<string, { pool: any, type: string }>} */\n this._databasePools = new Map()\n\n /** @type {HealthResource[]} */\n this._resources = options.resources || []\n\n const redisClient = this._getRedisClientForCache()\n if (redisClient) {\n this._redisClientType = getRedisClientType(redisClient)\n }\n\n this._cache = new HealthCheckCache({\n redisClient: redisClient || null,\n cacheKey: options.cacheKey,\n appName: this.appName,\n staleThresholdMs: this.healthConfig.staleThresholdMs,\n })\n }\n\n _getEnv(resource) {\n return resource.env ?? resource.name\n }\n\n _getRedisClientForCache() {\n const redisResource = this._resources.find(r => 'client' in r && r.client)\n return redisResource?.client || null\n }\n\n _getPool(env, url) {\n if (!this._databasePools.has(env)) {\n const { pool, type } = createDatabasePool(\n env,\n url,\n this.healthConfig.checkTimeoutMs\n )\n this._databasePools.set(env, { pool, type })\n }\n return this._databasePools.get(env)\n }\n\n async _checkDatabase(resource) {\n const env = this._getEnv(resource)\n const url = 'url' in resource ? resource.url : process.env[env]\n if (!url) {\n return { status: 'error', error: `Env ${env} not set` }\n }\n\n try {\n const { pool, type } = this._getPool(env, url)\n await runHealthCheck(pool, type)\n return { status: 'ok' }\n } catch (err) {\n return {\n status: 'error',\n error: maskSensitiveData(err.message),\n }\n }\n }\n\n async _checkRedis(resource) {\n const { client } = resource\n if (!client) return { status: 'ok' }\n\n try {\n let pong\n if (this._redisClientType === REDIS_V3) {\n pong = await new Promise((resolve, reject) => {\n client.ping((err, result) => {\n if (err) reject(err)\n else resolve(result)\n })\n })\n } else if (\n this._redisClientType === REDIS_V4 ||\n this._redisClientType === IOREDIS\n ) {\n pong = await client.ping()\n } else {\n return { status: 'error', error: 'Unknown Redis client type' }\n }\n\n return pong === 'PONG'\n ? { status: 'ok' }\n : { status: 'error', error: `Unexpected: ${pong}` }\n } catch (err) {\n return { status: 'error', error: maskSensitiveData(err.message) }\n }\n }\n\n async _performHealthCheckInternal() {\n const resources = {}\n\n for (const resource of this._resources) {\n const env = this._getEnv(resource)\n\n if ('client' in resource && resource.client) {\n resources[env] = await this._checkRedis(resource)\n } else {\n resources[env] = await this._checkDatabase(resource)\n }\n }\n\n const sortedResources = Object.keys(resources)\n .sort()\n .reduce((acc, key) => {\n acc[key] = resources[key]\n return acc\n }, {})\n\n const hasError = Object.values(resources).some(r => r.status === 'error')\n const lastCheckAt = Date.now()\n\n return {\n status: hasError ? 'error' : 'ok',\n lastCheckAt,\n resources: sortedResources,\n isStale: false,\n config: this.healthConfig,\n }\n }\n\n _formatResult(result, cached = false) {\n const isStale =\n !result.lastCheckAt ||\n Date.now() - result.lastCheckAt > this.healthConfig.staleThresholdMs\n\n return {\n ...result,\n isStale,\n status: isStale ? 'stale' : result.status,\n ...(isStale && {\n error:\n 'Health check data is stale, health-check worker may not be running. Resource statuses are unknown.',\n }),\n ...(cached && { cached: true }),\n }\n }\n\n async performHealthCheck() {\n if (this._refreshPromise) {\n return this._refreshPromise\n }\n\n this._refreshPromise = this._performHealthCheckInternal()\n .then(result => {\n this._refreshPromise = null\n return this._formatResult(result)\n })\n .catch(err => {\n this._refreshPromise = null\n throw err\n })\n\n return this._refreshPromise\n }\n\n async getCachedResult() {\n try {\n const cached = await this._cache.get()\n if (cached) return this._formatResult(cached)\n return null\n } catch (err) {\n console.error(`${this.prefixLogs} Failed to read from cache:`, err)\n return {\n status: 'error',\n lastCheckAt: null,\n resources: {},\n isStale: true,\n error:\n 'Redis unavailable, unable to read health status of other resources',\n config: this.healthConfig,\n }\n }\n }\n\n async refreshCache() {\n const result = await this._performHealthCheckInternal()\n await this._cache.set(result)\n return result\n }\n\n clearCache() {\n this._refreshPromise = null\n }\n\n healthHandler() {\n return async (req, res) => {\n try {\n const result = await this.getCachedResult()\n\n if (!result) {\n res.status(503).json({\n status: 'error',\n lastCheckAt: null,\n resources: {},\n isStale: true,\n error:\n 'No health check data yet, health-check worker may not be running',\n config: this.healthConfig,\n })\n return\n }\n\n const statusCode = result.status === 'ok' ? 200 : 503\n res.status(statusCode).json(result)\n } catch (err) {\n console.error(`${this.prefixLogs} Health check failed:`, err)\n res.status(503).json({\n status: 'error',\n lastCheckAt: null,\n resources: {},\n isStale: true,\n error:\n 'Redis unavailable, unable to read health status of other resources',\n config: this.healthConfig,\n })\n }\n }\n }\n\n async cleanup() {\n for (const [, { pool }] of this._databasePools) {\n try {\n await closePool(pool)\n } catch (err) {\n console.error(`${this.prefixLogs} Error closing database pool:`, err)\n }\n }\n this._databasePools.clear()\n }\n}\n\nmodule.exports = { HealthCheckClient, DEFAULT_HEALTH_CONFIG }\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"healthCheckUtils.d.ts","sourceRoot":"","sources":["../../src/health/healthCheckUtils.js"],"names":[],"mappings":"AAgBA;;;;;;;;;;GAUG;AACH,uDAVW,MAAM,GAQJ,iBAAiB,CA6C7B;AAED;;;;;;;GAOG;AACH;IANwB,WAAW,EAAxB,GAAG;IACc,OAAO;IACP,QAAQ;IACR,MAAM;IACrB,iBAAiB,CAe7B;AAED;;;;;;;GAOG;AACH;IANwB,WAAW,EAAxB,GAAG;IACc,QAAQ;IACR,OAAO;IACP,MAAM;UACf,GAAG,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,CAiBjD;AAjHD;;;GAGG;AACH;QAHkB,MAAM,GAAE,MAAM;IACnB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,CAO1C"}
1
+ {"version":3,"file":"healthCheckUtils.d.ts","sourceRoot":"","sources":["../../src/health/healthCheckUtils.js"],"names":[],"mappings":"AAaA;;;;;;;;;;GAUG;AACH,uDAVW,MAAM,GAQJ,iBAAiB,CA6C7B;AAED;;;;;;;GAOG;AACH;IANwB,WAAW,EAAxB,GAAG;IACc,OAAO;IACP,QAAQ;IACR,MAAM;IACrB,iBAAiB,CAiB7B;AAED;;;;;;;GAOG;AACH;IANwB,WAAW,EAAxB,GAAG;IACc,QAAQ;IACR,OAAO;IACP,MAAM;UACf,GAAG,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,CAiBjD;AAnHD;;;GAGG;AACH;QAHkB,MAAM,GAAE,MAAM;IACnB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,CAO1C"}
@@ -1,8 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  const {
4
- HealthCheckClient,
5
- DEFAULT_HEALTH_CONFIG
4
+ HealthCheckClient
6
5
  } = require('./healthCheckClient');
7
6
 
8
7
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"healthCheckUtils.js","names":["HealthCheckClient","DEFAULT_HEALTH_CONFIG","require","additionalDatabaseUrlsToResources","urls","Object","entries","filter","url","map","env","createHealthCheckWorkerClient","options","resources","appName","cacheKey","config","databaseUrl","databaseName","additionalDatabaseUrls","resourcesArray","Array","isArray","length","process","DATABASE_URL","push","clusterResources","redisResource","find","r","client","Error","BUILD_APP_NAME","createHealthCheckEndpointClient","redisClient","getHealthCheckStatus","healthHandler","module","exports"],"sources":["../../src/health/healthCheckUtils.js"],"sourcesContent":["const {\n HealthCheckClient,\n DEFAULT_HEALTH_CONFIG,\n} = require('./healthCheckClient')\n\n/**\n * @param {Object<string, string>} urls\n * @returns {{ env: string, url: string }[]}\n */\nfunction additionalDatabaseUrlsToResources(urls) {\n if (!urls || typeof urls !== 'object') return []\n return Object.entries(urls)\n .filter(([, url]) => url)\n .map(([env, url]) => ({ env, url }))\n}\n\n/**\n * @param {Object} options\n * @param {{ env: string } | { env: string, url?: string } | { env: string, client?: any }}[] options.resources\n * @param {string} [options.appName] - For cache key: healthcheck:${appName}\n * @param {string} [options.cacheKey] - Redis key (overrides appName)\n * @param {Object} [options.config]\n * @param {string} [options.databaseUrl]\n * @param {string} [options.databaseName]\n * @param {Object<string, string>} [options.additionalDatabaseUrls]\n * @returns {HealthCheckClient}\n */\nfunction createHealthCheckWorkerClient(options) {\n const {\n resources,\n appName,\n cacheKey,\n config,\n databaseUrl,\n databaseName,\n additionalDatabaseUrls,\n } = options\n\n let resourcesArray = Array.isArray(resources) ? resources : []\n\n if (resourcesArray.length === 0) {\n resourcesArray = []\n\n if (databaseUrl) {\n const url = databaseUrl || process.env.DATABASE_URL\n if (url) {\n const env = databaseName || 'DATABASE_URL'\n resourcesArray.push({ env, url })\n }\n }\n\n const clusterResources = additionalDatabaseUrlsToResources(\n additionalDatabaseUrls || {}\n )\n resourcesArray.push(...clusterResources)\n }\n\n const redisResource = resourcesArray.find(r => 'client' in r && r.client)\n if (!redisResource) {\n throw new Error(\n 'resources must include Redis resource with client (e.g. { env: \"REDIS_URL\", client })'\n )\n }\n\n return new HealthCheckClient({\n resources: resourcesArray,\n appName: appName || process.env.BUILD_APP_NAME || 'unknown-app',\n cacheKey,\n config,\n })\n}\n\n/**\n * @param {Object} options\n * @param {any} options.redisClient\n * @param {string} [options.appName] - For cache key: healthcheck:${appName}\n * @param {string} [options.cacheKey] - Redis key (e.g. 'health:database:status')\n * @param {Object} [options.config]\n * @returns {HealthCheckClient}\n */\nfunction createHealthCheckEndpointClient(options) {\n const { redisClient, appName, cacheKey, config } = options\n\n if (!redisClient) {\n throw new Error('redisClient is required for createHealthCheckEndpointClient')\n }\n\n return new HealthCheckClient({\n resources: [{ env: 'REDIS_URL', client: redisClient }],\n appName: appName || process.env.BUILD_APP_NAME || 'unknown-app',\n cacheKey,\n config,\n })\n}\n\n/**\n * @param {Object} options\n * @param {any} options.redisClient\n * @param {string} [options.cacheKey] - Redis key (e.g. 'health:database:status')\n * @param {string} [options.appName] - For cache key: healthcheck:${appName}\n * @param {Object} [options.config]\n * @returns {(req: any, res: any) => Promise<void>}\n */\nfunction getHealthCheckStatus(options) {\n const { redisClient, cacheKey, appName, config } = options\n\n if (!redisClient) {\n throw new Error('redisClient is required for getHealthCheckStatus')\n }\n\n const client = createHealthCheckEndpointClient({\n redisClient,\n cacheKey,\n appName,\n config,\n })\n\n return client.healthHandler()\n}\n\nmodule.exports = {\n createHealthCheckWorkerClient,\n createHealthCheckEndpointClient,\n getHealthCheckStatus,\n additionalDatabaseUrlsToResources,\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"healthCheckUtils.js","names":["HealthCheckClient","require","additionalDatabaseUrlsToResources","urls","Object","entries","filter","url","map","env","createHealthCheckWorkerClient","options","resources","appName","cacheKey","config","databaseUrl","databaseName","additionalDatabaseUrls","resourcesArray","Array","isArray","length","process","DATABASE_URL","push","clusterResources","redisResource","find","r","client","Error","BUILD_APP_NAME","createHealthCheckEndpointClient","redisClient","getHealthCheckStatus","healthHandler","module","exports"],"sources":["../../src/health/healthCheckUtils.js"],"sourcesContent":["const { HealthCheckClient } = require('./healthCheckClient')\n\n/**\n * @param {Object<string, string>} urls\n * @returns {{ env: string, url: string }[]}\n */\nfunction additionalDatabaseUrlsToResources(urls) {\n if (!urls || typeof urls !== 'object') return []\n return Object.entries(urls)\n .filter(([, url]) => url)\n .map(([env, url]) => ({ env, url }))\n}\n\n/**\n * @param {Object} options\n * @param {{ env: string } | { env: string, url?: string } | { env: string, client?: any }}[] options.resources\n * @param {string} [options.appName] - For cache key: healthcheck:${appName}\n * @param {string} [options.cacheKey] - Redis key (overrides appName)\n * @param {Object} [options.config]\n * @param {string} [options.databaseUrl]\n * @param {string} [options.databaseName]\n * @param {Object<string, string>} [options.additionalDatabaseUrls]\n * @returns {HealthCheckClient}\n */\nfunction createHealthCheckWorkerClient(options) {\n const {\n resources,\n appName,\n cacheKey,\n config,\n databaseUrl,\n databaseName,\n additionalDatabaseUrls,\n } = options\n\n let resourcesArray = Array.isArray(resources) ? resources : []\n\n if (resourcesArray.length === 0) {\n resourcesArray = []\n\n if (databaseUrl) {\n const url = databaseUrl || process.env.DATABASE_URL\n if (url) {\n const env = databaseName || 'DATABASE_URL'\n resourcesArray.push({ env, url })\n }\n }\n\n const clusterResources = additionalDatabaseUrlsToResources(\n additionalDatabaseUrls || {}\n )\n resourcesArray.push(...clusterResources)\n }\n\n const redisResource = resourcesArray.find(r => 'client' in r && r.client)\n if (!redisResource) {\n throw new Error(\n 'resources must include Redis resource with client (e.g. { env: \"REDIS_URL\", client })'\n )\n }\n\n return new HealthCheckClient({\n resources: resourcesArray,\n appName: appName || process.env.BUILD_APP_NAME || 'unknown-app',\n cacheKey,\n config,\n })\n}\n\n/**\n * @param {Object} options\n * @param {any} options.redisClient\n * @param {string} [options.appName] - For cache key: healthcheck:${appName}\n * @param {string} [options.cacheKey] - Redis key (e.g. 'health:database:status')\n * @param {Object} [options.config]\n * @returns {HealthCheckClient}\n */\nfunction createHealthCheckEndpointClient(options) {\n const { redisClient, appName, cacheKey, config } = options\n\n if (!redisClient) {\n throw new Error(\n 'redisClient is required for createHealthCheckEndpointClient'\n )\n }\n\n return new HealthCheckClient({\n resources: [{ env: 'REDIS_URL', client: redisClient }],\n appName: appName || process.env.BUILD_APP_NAME || 'unknown-app',\n cacheKey,\n config,\n })\n}\n\n/**\n * @param {Object} options\n * @param {any} options.redisClient\n * @param {string} [options.cacheKey] - Redis key (e.g. 'health:database:status')\n * @param {string} [options.appName] - For cache key: healthcheck:${appName}\n * @param {Object} [options.config]\n * @returns {(req: any, res: any) => Promise<void>}\n */\nfunction getHealthCheckStatus(options) {\n const { redisClient, cacheKey, appName, config } = options\n\n if (!redisClient) {\n throw new Error('redisClient is required for getHealthCheckStatus')\n }\n\n const client = createHealthCheckEndpointClient({\n redisClient,\n cacheKey,\n appName,\n config,\n })\n\n return client.healthHandler()\n}\n\nmodule.exports = {\n createHealthCheckWorkerClient,\n createHealthCheckEndpointClient,\n getHealthCheckStatus,\n additionalDatabaseUrlsToResources,\n}\n"],"mappings":";;AAAA,MAAM;EAAEA;AAAkB,CAAC,GAAGC,OAAO,CAAC,qBAAqB,CAAC;;AAE5D;AACA;AACA;AACA;AACA,SAASC,iCAAiCA,CAACC,IAAI,EAAE;EAC/C,IAAI,CAACA,IAAI,IAAI,OAAOA,IAAI,KAAK,QAAQ,EAAE,OAAO,EAAE;EAChD,OAAOC,MAAM,CAACC,OAAO,CAACF,IAAI,CAAC,CACxBG,MAAM,CAAC,CAAC,GAAGC,GAAG,CAAC,KAAKA,GAAG,CAAC,CACxBC,GAAG,CAAC,CAAC,CAACC,GAAG,EAAEF,GAAG,CAAC,MAAM;IAAEE,GAAG;IAAEF;EAAI,CAAC,CAAC,CAAC;AACxC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASG,6BAA6BA,CAACC,OAAO,EAAE;EAC9C,MAAM;IACJC,SAAS;IACTC,OAAO;IACPC,QAAQ;IACRC,MAAM;IACNC,WAAW;IACXC,YAAY;IACZC;EACF,CAAC,GAAGP,OAAO;EAEX,IAAIQ,cAAc,GAAGC,KAAK,CAACC,OAAO,CAACT,SAAS,CAAC,GAAGA,SAAS,GAAG,EAAE;EAE9D,IAAIO,cAAc,CAACG,MAAM,KAAK,CAAC,EAAE;IAC/BH,cAAc,GAAG,EAAE;IAEnB,IAAIH,WAAW,EAAE;MACf,MAAMT,GAAG,GAAGS,WAAW,IAAIO,OAAO,CAACd,GAAG,CAACe,YAAY;MACnD,IAAIjB,GAAG,EAAE;QACP,MAAME,GAAG,GAAGQ,YAAY,IAAI,cAAc;QAC1CE,cAAc,CAACM,IAAI,CAAC;UAAEhB,GAAG;UAAEF;QAAI,CAAC,CAAC;MACnC;IACF;IAEA,MAAMmB,gBAAgB,GAAGxB,iCAAiC,CACxDgB,sBAAsB,IAAI,CAAC,CAC7B,CAAC;IACDC,cAAc,CAACM,IAAI,CAAC,GAAGC,gBAAgB,CAAC;EAC1C;EAEA,MAAMC,aAAa,GAAGR,cAAc,CAACS,IAAI,CAACC,CAAC,IAAI,QAAQ,IAAIA,CAAC,IAAIA,CAAC,CAACC,MAAM,CAAC;EACzE,IAAI,CAACH,aAAa,EAAE;IAClB,MAAM,IAAII,KAAK,CACb,uFACF,CAAC;EACH;EAEA,OAAO,IAAI/B,iBAAiB,CAAC;IAC3BY,SAAS,EAAEO,cAAc;IACzBN,OAAO,EAAEA,OAAO,IAAIU,OAAO,CAACd,GAAG,CAACuB,cAAc,IAAI,aAAa;IAC/DlB,QAAQ;IACRC;EACF,CAAC,CAAC;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASkB,+BAA+BA,CAACtB,OAAO,EAAE;EAChD,MAAM;IAAEuB,WAAW;IAAErB,OAAO;IAAEC,QAAQ;IAAEC;EAAO,CAAC,GAAGJ,OAAO;EAE1D,IAAI,CAACuB,WAAW,EAAE;IAChB,MAAM,IAAIH,KAAK,CACb,6DACF,CAAC;EACH;EAEA,OAAO,IAAI/B,iBAAiB,CAAC;IAC3BY,SAAS,EAAE,CAAC;MAAEH,GAAG,EAAE,WAAW;MAAEqB,MAAM,EAAEI;IAAY,CAAC,CAAC;IACtDrB,OAAO,EAAEA,OAAO,IAAIU,OAAO,CAACd,GAAG,CAACuB,cAAc,IAAI,aAAa;IAC/DlB,QAAQ;IACRC;EACF,CAAC,CAAC;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASoB,oBAAoBA,CAACxB,OAAO,EAAE;EACrC,MAAM;IAAEuB,WAAW;IAAEpB,QAAQ;IAAED,OAAO;IAAEE;EAAO,CAAC,GAAGJ,OAAO;EAE1D,IAAI,CAACuB,WAAW,EAAE;IAChB,MAAM,IAAIH,KAAK,CAAC,kDAAkD,CAAC;EACrE;EAEA,MAAMD,MAAM,GAAGG,+BAA+B,CAAC;IAC7CC,WAAW;IACXpB,QAAQ;IACRD,OAAO;IACPE;EACF,CAAC,CAAC;EAEF,OAAOe,MAAM,CAACM,aAAa,CAAC,CAAC;AAC/B;AAEAC,MAAM,CAACC,OAAO,GAAG;EACf5B,6BAA6B;EAC7BuB,+BAA+B;EAC/BE,oBAAoB;EACpBjC;AACF,CAAC","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"healthCheckWorker.d.ts","sourceRoot":"","sources":["../../src/health/healthCheckWorker.js"],"names":[],"mappings":"AAcA,2EA0DC"}
1
+ {"version":3,"file":"healthCheckWorker.d.ts","sourceRoot":"","sources":["../../src/health/healthCheckWorker.js"],"names":[],"mappings":"AAYA,2EA0DC"}
@@ -1 +1 @@
1
- {"version":3,"file":"healthCheckWorker.js","names":["createHealthCheckWorkerClient","require","DEFAULT_HEALTH_CONFIG","createHealthCheckWorker","options","refreshIntervalMs","checkIntervalMs","workerClientOptions","appName","process","env","BUILD_APP_NAME","dynoId","HOSTNAME","processType","BUILD_DYNO_PROCESS_TYPE","logValues","HEALTH_LOG_VALUES","prefixLogs","healthCheckClient","runHealthCheckWorker","console","log","refreshCache","err","error","interval","setInterval","result","lastCheckAt","status","on","clearInterval","cleanup","finally","exit"],"sources":["../../src/health/healthCheckWorker.js"],"sourcesContent":["/**\n * @param {Object} options\n * @param {{ name: string } | { name: string, url?: string } | { name: string, client: any }}[] options.resources - Must include Redis resource with client\n * @param {string} [options.appName]\n * @param {number} [options.refreshIntervalMs]\n * @param {string} [options.databaseUrl]\n * @param {string} [options.databaseName]\n * @param {Object<string, string>} [options.additionalDatabaseUrls]\n */\nconst {\n createHealthCheckWorkerClient,\n} = require('./healthCheckUtils')\nconst { DEFAULT_HEALTH_CONFIG } = require('./healthCheckClient')\n\nexport function createHealthCheckWorker(options) {\n const {\n refreshIntervalMs = DEFAULT_HEALTH_CONFIG.checkIntervalMs,\n ...workerClientOptions\n } = options\n\n const appName =\n workerClientOptions.appName || process.env.BUILD_APP_NAME || 'unknown-app'\n const dynoId = process.env.HOSTNAME || 'unknown-dyno'\n const processType =\n process.env.BUILD_DYNO_PROCESS_TYPE || 'health-check-worker'\n const logValues = process.env.HEALTH_LOG_VALUES === 'true'\n const prefixLogs = `[${processType}] [${appName}] [${dynoId}] [HealthCheck]`\n\n const healthCheckClient = createHealthCheckWorkerClient(workerClientOptions)\n\n return async function runHealthCheckWorker() {\n console.log(`${prefixLogs} Starting health check worker...`)\n console.log(`${prefixLogs} Refresh interval: ${refreshIntervalMs}ms`)\n\n try {\n await healthCheckClient.refreshCache()\n if (logValues) {\n console.log(`${prefixLogs} Initial health check completed`)\n }\n } catch (err) {\n console.error(`${prefixLogs} Initial health check failed:`, err)\n }\n\n const interval = setInterval(async () => {\n try {\n const result = await healthCheckClient.refreshCache()\n if (logValues) {\n console.log(\n `${prefixLogs} Health check refreshed at ${result.lastCheckAt}, status: ${result.status}`\n )\n }\n } catch (err) {\n console.error(`${prefixLogs} Health check refresh failed:`, err)\n }\n }, refreshIntervalMs)\n\n process.on('SIGTERM', () => {\n console.log(`${prefixLogs} Received SIGTERM, shutting down...`)\n clearInterval(interval)\n healthCheckClient.cleanup().finally(() => {\n process.exit(0)\n })\n })\n\n process.on('SIGINT', () => {\n console.log(`${prefixLogs} Received SIGINT, shutting down...`)\n clearInterval(interval)\n healthCheckClient.cleanup().finally(() => {\n process.exit(0)\n })\n })\n }\n}\n"],"mappings":";;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;EACJA;AACF,CAAC,GAAGC,OAAO,CAAC,oBAAoB,CAAC;AACjC,MAAM;EAAEC;AAAsB,CAAC,GAAGD,OAAO,CAAC,qBAAqB,CAAC;AAEzD,SAASE,uBAAuBA,CAACC,OAAO,EAAE;EAC/C,MAAM;IACJC,iBAAiB,GAAGH,qBAAqB,CAACI,eAAe;IACzD,GAAGC;EACL,CAAC,GAAGH,OAAO;EAEX,MAAMI,OAAO,GACXD,mBAAmB,CAACC,OAAO,IAAIC,OAAO,CAACC,GAAG,CAACC,cAAc,IAAI,aAAa;EAC5E,MAAMC,MAAM,GAAGH,OAAO,CAACC,GAAG,CAACG,QAAQ,IAAI,cAAc;EACrD,MAAMC,WAAW,GACfL,OAAO,CAACC,GAAG,CAACK,uBAAuB,IAAI,qBAAqB;EAC9D,MAAMC,SAAS,GAAGP,OAAO,CAACC,GAAG,CAACO,iBAAiB,KAAK,MAAM;EAC1D,MAAMC,UAAU,GAAG,IAAIJ,WAAW,MAAMN,OAAO,MAAMI,MAAM,iBAAiB;EAE5E,MAAMO,iBAAiB,GAAGnB,6BAA6B,CAACO,mBAAmB,CAAC;EAE5E,OAAO,eAAea,oBAAoBA,CAAA,EAAG;IAC3CC,OAAO,CAACC,GAAG,CAAC,GAAGJ,UAAU,kCAAkC,CAAC;IAC5DG,OAAO,CAACC,GAAG,CAAC,GAAGJ,UAAU,sBAAsBb,iBAAiB,IAAI,CAAC;IAErE,IAAI;MACF,MAAMc,iBAAiB,CAACI,YAAY,CAAC,CAAC;MACtC,IAAIP,SAAS,EAAE;QACbK,OAAO,CAACC,GAAG,CAAC,GAAGJ,UAAU,iCAAiC,CAAC;MAC7D;IACF,CAAC,CAAC,OAAOM,GAAG,EAAE;MACZH,OAAO,CAACI,KAAK,CAAC,GAAGP,UAAU,+BAA+B,EAAEM,GAAG,CAAC;IAClE;IAEA,MAAME,QAAQ,GAAGC,WAAW,CAAC,YAAY;MACvC,IAAI;QACF,MAAMC,MAAM,GAAG,MAAMT,iBAAiB,CAACI,YAAY,CAAC,CAAC;QACrD,IAAIP,SAAS,EAAE;UACbK,OAAO,CAACC,GAAG,CACT,GAAGJ,UAAU,8BAA8BU,MAAM,CAACC,WAAW,aAAaD,MAAM,CAACE,MAAM,EACzF,CAAC;QACH;MACF,CAAC,CAAC,OAAON,GAAG,EAAE;QACZH,OAAO,CAACI,KAAK,CAAC,GAAGP,UAAU,+BAA+B,EAAEM,GAAG,CAAC;MAClE;IACF,CAAC,EAAEnB,iBAAiB,CAAC;IAErBI,OAAO,CAACsB,EAAE,CAAC,SAAS,EAAE,MAAM;MAC1BV,OAAO,CAACC,GAAG,CAAC,GAAGJ,UAAU,qCAAqC,CAAC;MAC/Dc,aAAa,CAACN,QAAQ,CAAC;MACvBP,iBAAiB,CAACc,OAAO,CAAC,CAAC,CAACC,OAAO,CAAC,MAAM;QACxCzB,OAAO,CAAC0B,IAAI,CAAC,CAAC,CAAC;MACjB,CAAC,CAAC;IACJ,CAAC,CAAC;IAEF1B,OAAO,CAACsB,EAAE,CAAC,QAAQ,EAAE,MAAM;MACzBV,OAAO,CAACC,GAAG,CAAC,GAAGJ,UAAU,oCAAoC,CAAC;MAC9Dc,aAAa,CAACN,QAAQ,CAAC;MACvBP,iBAAiB,CAACc,OAAO,CAAC,CAAC,CAACC,OAAO,CAAC,MAAM;QACxCzB,OAAO,CAAC0B,IAAI,CAAC,CAAC,CAAC;MACjB,CAAC,CAAC;IACJ,CAAC,CAAC;EACJ,CAAC;AACH","ignoreList":[]}
1
+ {"version":3,"file":"healthCheckWorker.js","names":["createHealthCheckWorkerClient","require","DEFAULT_HEALTH_CONFIG","createHealthCheckWorker","options","refreshIntervalMs","checkIntervalMs","workerClientOptions","appName","process","env","BUILD_APP_NAME","dynoId","HOSTNAME","processType","BUILD_DYNO_PROCESS_TYPE","logValues","HEALTH_LOG_VALUES","prefixLogs","healthCheckClient","runHealthCheckWorker","console","log","refreshCache","err","error","interval","setInterval","result","lastCheckAt","status","on","clearInterval","cleanup","finally","exit"],"sources":["../../src/health/healthCheckWorker.js"],"sourcesContent":["/**\n * @param {Object} options\n * @param {{ name: string } | { name: string, url?: string } | { name: string, client: any }}[] options.resources - Must include Redis resource with client\n * @param {string} [options.appName]\n * @param {number} [options.refreshIntervalMs]\n * @param {string} [options.databaseUrl]\n * @param {string} [options.databaseName]\n * @param {Object<string, string>} [options.additionalDatabaseUrls]\n */\nconst { createHealthCheckWorkerClient } = require('./healthCheckUtils')\nconst { DEFAULT_HEALTH_CONFIG } = require('./healthCheckClient')\n\nexport function createHealthCheckWorker(options) {\n const {\n refreshIntervalMs = DEFAULT_HEALTH_CONFIG.checkIntervalMs,\n ...workerClientOptions\n } = options\n\n const appName =\n workerClientOptions.appName || process.env.BUILD_APP_NAME || 'unknown-app'\n const dynoId = process.env.HOSTNAME || 'unknown-dyno'\n const processType =\n process.env.BUILD_DYNO_PROCESS_TYPE || 'health-check-worker'\n const logValues = process.env.HEALTH_LOG_VALUES === 'true'\n const prefixLogs = `[${processType}] [${appName}] [${dynoId}] [HealthCheck]`\n\n const healthCheckClient = createHealthCheckWorkerClient(workerClientOptions)\n\n return async function runHealthCheckWorker() {\n console.log(`${prefixLogs} Starting health check worker...`)\n console.log(`${prefixLogs} Refresh interval: ${refreshIntervalMs}ms`)\n\n try {\n await healthCheckClient.refreshCache()\n if (logValues) {\n console.log(`${prefixLogs} Initial health check completed`)\n }\n } catch (err) {\n console.error(`${prefixLogs} Initial health check failed:`, err)\n }\n\n const interval = setInterval(async () => {\n try {\n const result = await healthCheckClient.refreshCache()\n if (logValues) {\n console.log(\n `${prefixLogs} Health check refreshed at ${result.lastCheckAt}, status: ${result.status}`\n )\n }\n } catch (err) {\n console.error(`${prefixLogs} Health check refresh failed:`, err)\n }\n }, refreshIntervalMs)\n\n process.on('SIGTERM', () => {\n console.log(`${prefixLogs} Received SIGTERM, shutting down...`)\n clearInterval(interval)\n healthCheckClient.cleanup().finally(() => {\n process.exit(0)\n })\n })\n\n process.on('SIGINT', () => {\n console.log(`${prefixLogs} Received SIGINT, shutting down...`)\n clearInterval(interval)\n healthCheckClient.cleanup().finally(() => {\n process.exit(0)\n })\n })\n }\n}\n"],"mappings":";;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;EAAEA;AAA8B,CAAC,GAAGC,OAAO,CAAC,oBAAoB,CAAC;AACvE,MAAM;EAAEC;AAAsB,CAAC,GAAGD,OAAO,CAAC,qBAAqB,CAAC;AAEzD,SAASE,uBAAuBA,CAACC,OAAO,EAAE;EAC/C,MAAM;IACJC,iBAAiB,GAAGH,qBAAqB,CAACI,eAAe;IACzD,GAAGC;EACL,CAAC,GAAGH,OAAO;EAEX,MAAMI,OAAO,GACXD,mBAAmB,CAACC,OAAO,IAAIC,OAAO,CAACC,GAAG,CAACC,cAAc,IAAI,aAAa;EAC5E,MAAMC,MAAM,GAAGH,OAAO,CAACC,GAAG,CAACG,QAAQ,IAAI,cAAc;EACrD,MAAMC,WAAW,GACfL,OAAO,CAACC,GAAG,CAACK,uBAAuB,IAAI,qBAAqB;EAC9D,MAAMC,SAAS,GAAGP,OAAO,CAACC,GAAG,CAACO,iBAAiB,KAAK,MAAM;EAC1D,MAAMC,UAAU,GAAG,IAAIJ,WAAW,MAAMN,OAAO,MAAMI,MAAM,iBAAiB;EAE5E,MAAMO,iBAAiB,GAAGnB,6BAA6B,CAACO,mBAAmB,CAAC;EAE5E,OAAO,eAAea,oBAAoBA,CAAA,EAAG;IAC3CC,OAAO,CAACC,GAAG,CAAC,GAAGJ,UAAU,kCAAkC,CAAC;IAC5DG,OAAO,CAACC,GAAG,CAAC,GAAGJ,UAAU,sBAAsBb,iBAAiB,IAAI,CAAC;IAErE,IAAI;MACF,MAAMc,iBAAiB,CAACI,YAAY,CAAC,CAAC;MACtC,IAAIP,SAAS,EAAE;QACbK,OAAO,CAACC,GAAG,CAAC,GAAGJ,UAAU,iCAAiC,CAAC;MAC7D;IACF,CAAC,CAAC,OAAOM,GAAG,EAAE;MACZH,OAAO,CAACI,KAAK,CAAC,GAAGP,UAAU,+BAA+B,EAAEM,GAAG,CAAC;IAClE;IAEA,MAAME,QAAQ,GAAGC,WAAW,CAAC,YAAY;MACvC,IAAI;QACF,MAAMC,MAAM,GAAG,MAAMT,iBAAiB,CAACI,YAAY,CAAC,CAAC;QACrD,IAAIP,SAAS,EAAE;UACbK,OAAO,CAACC,GAAG,CACT,GAAGJ,UAAU,8BAA8BU,MAAM,CAACC,WAAW,aAAaD,MAAM,CAACE,MAAM,EACzF,CAAC;QACH;MACF,CAAC,CAAC,OAAON,GAAG,EAAE;QACZH,OAAO,CAACI,KAAK,CAAC,GAAGP,UAAU,+BAA+B,EAAEM,GAAG,CAAC;MAClE;IACF,CAAC,EAAEnB,iBAAiB,CAAC;IAErBI,OAAO,CAACsB,EAAE,CAAC,SAAS,EAAE,MAAM;MAC1BV,OAAO,CAACC,GAAG,CAAC,GAAGJ,UAAU,qCAAqC,CAAC;MAC/Dc,aAAa,CAACN,QAAQ,CAAC;MACvBP,iBAAiB,CAACc,OAAO,CAAC,CAAC,CAACC,OAAO,CAAC,MAAM;QACxCzB,OAAO,CAAC0B,IAAI,CAAC,CAAC,CAAC;MACjB,CAAC,CAAC;IACJ,CAAC,CAAC;IAEF1B,OAAO,CAACsB,EAAE,CAAC,QAAQ,EAAE,MAAM;MACzBV,OAAO,CAACC,GAAG,CAAC,GAAGJ,UAAU,oCAAoC,CAAC;MAC9Dc,aAAa,CAACN,QAAQ,CAAC;MACvBP,iBAAiB,CAACc,OAAO,CAAC,CAAC,CAACC,OAAO,CAAC,MAAM;QACxCzB,OAAO,CAAC0B,IAAI,CAAC,CAAC,CAAC;MACjB,CAAC,CAAC;IACJ,CAAC,CAAC;EACJ,CAAC;AACH","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adalo/metrics",
3
- "version": "0.1.134",
3
+ "version": "0.1.136",
4
4
  "description": "Reusable metrics utilities for Node.js and Laravel apps",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -1,4 +1,5 @@
1
1
  const { Pool } = require('pg')
2
+ const mysql = require('mysql2/promise')
2
3
 
3
4
  const DB_TYPE_POSTGRES = 'postgres'
4
5
  const DB_TYPE_MYSQL = 'mysql'
@@ -51,7 +52,6 @@ function createDatabasePool(env, url, connectionTimeoutMs) {
51
52
  const type = getDatabaseType(url)
52
53
 
53
54
  if (type === DB_TYPE_MYSQL) {
54
- const mysql = require('mysql2/promise')
55
55
  const config = parseConnectionUrl(url, DB_TYPE_MYSQL)
56
56
  if (!config) {
57
57
  throw new Error(`Invalid MySQL URL for ${env}`)
@@ -85,7 +85,7 @@ function createDatabasePool(env, url, connectionTimeoutMs) {
85
85
  */
86
86
  async function runHealthCheck(pool, type) {
87
87
  if (type === DB_TYPE_MYSQL) {
88
- const [rows] = await pool.execute('SELECT 1')
88
+ await pool.execute('SELECT 1')
89
89
  return
90
90
  }
91
91
  await pool.query('SELECT 1')
@@ -23,8 +23,7 @@ class HealthCheckCache {
23
23
  this.appName =
24
24
  options.appName || process.env.BUILD_APP_NAME || 'unknown-app'
25
25
  this.staleThresholdMs = options.staleThresholdMs ?? 180_000
26
- this.cacheKey =
27
- options.cacheKey || `healthcheck:${this.appName}`
26
+ this.cacheKey = options.cacheKey || `healthcheck:${this.appName}`
28
27
 
29
28
  /** In-memory fallback cache */
30
29
  this._memoryCache = null
@@ -1,8 +1,5 @@
1
- const {
2
- createDatabasePool,
3
- runHealthCheck,
4
- closePool,
5
- } = require('./databaseChecker')
1
+ const { createDatabasePool, runHealthCheck, closePool } =
2
+ require('./databaseChecker').default
6
3
  const {
7
4
  getRedisClientType,
8
5
  REDIS_V4,
@@ -161,7 +158,9 @@ class HealthCheckClient {
161
158
  return { status: 'error', error: 'Unknown Redis client type' }
162
159
  }
163
160
 
164
- return pong === 'PONG' ? { status: 'ok' } : { status: 'error', error: `Unexpected: ${pong}` }
161
+ return pong === 'PONG'
162
+ ? { status: 'ok' }
163
+ : { status: 'error', error: `Unexpected: ${pong}` }
165
164
  } catch (err) {
166
165
  return { status: 'error', error: maskSensitiveData(err.message) }
167
166
  }
@@ -299,7 +298,7 @@ class HealthCheckClient {
299
298
  }
300
299
 
301
300
  async cleanup() {
302
- for (const [, { pool, type }] of this._databasePools) {
301
+ for (const [, { pool }] of this._databasePools) {
303
302
  try {
304
303
  await closePool(pool)
305
304
  } catch (err) {
@@ -1,7 +1,4 @@
1
- const {
2
- HealthCheckClient,
3
- DEFAULT_HEALTH_CONFIG,
4
- } = require('./healthCheckClient')
1
+ const { HealthCheckClient } = require('./healthCheckClient')
5
2
 
6
3
  /**
7
4
  * @param {Object<string, string>} urls
@@ -82,7 +79,9 @@ function createHealthCheckEndpointClient(options) {
82
79
  const { redisClient, appName, cacheKey, config } = options
83
80
 
84
81
  if (!redisClient) {
85
- throw new Error('redisClient is required for createHealthCheckEndpointClient')
82
+ throw new Error(
83
+ 'redisClient is required for createHealthCheckEndpointClient'
84
+ )
86
85
  }
87
86
 
88
87
  return new HealthCheckClient({
@@ -7,9 +7,7 @@
7
7
  * @param {string} [options.databaseName]
8
8
  * @param {Object<string, string>} [options.additionalDatabaseUrls]
9
9
  */
10
- const {
11
- createHealthCheckWorkerClient,
12
- } = require('./healthCheckUtils')
10
+ const { createHealthCheckWorkerClient } = require('./healthCheckUtils')
13
11
  const { DEFAULT_HEALTH_CONFIG } = require('./healthCheckClient')
14
12
 
15
13
  export function createHealthCheckWorker(options) {