@onlineapps/service-common 1.0.12 → 1.0.13

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/README.md CHANGED
@@ -53,10 +53,10 @@ await waitForInfrastructureReady({
53
53
  Waits for all infrastructure services to be reported as healthy by Registry.
54
54
 
55
55
  **Options:**
56
- - `redisUrl` (string): Redis URL (default: from ENV or `redis://api_node_cache:6379`)
56
+ - `redisUrl` (string): Redis URL
57
57
  - `maxWait` (number): Maximum wait time in ms (default: 300000 = 5 minutes)
58
58
  - `checkInterval` (number): Check interval in ms (default: 5000 = 5 seconds)
59
- - `logger` (Object): Logger instance (default: console)
59
+ - `logger` (Object|Function): **Required** logger instance (or function). No implicit console fallback.
60
60
 
61
61
  **Returns:** `Promise<boolean>` - True if all infrastructure services are ready
62
62
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlineapps/service-common",
3
- "version": "1.0.12",
3
+ "version": "1.0.13",
4
4
  "description": "Common utilities for both infrastructure services and business services",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -37,15 +37,22 @@ async function waitForHealthCheckQueueReady(options = {}) {
37
37
  const redisUrl = buildRedisUrl({ redisUrl: options.redisUrl });
38
38
  const maxWait = runtimeCfg.get('infrastructureHealthQueueWaitMaxTimeMs', options.maxWait);
39
39
  const checkInterval = runtimeCfg.get('infrastructureHealthQueueWaitCheckIntervalMs', options.checkInterval);
40
- const logger = options.logger || console;
40
+ const logger = options.logger;
41
+ if (!logger) {
42
+ throw new Error('[service-common][waitForHealthCheckQueueReady] Missing dependency - logger is required (no console fallback).');
43
+ }
41
44
 
42
45
  const log = (msg) => {
43
46
  if (logger && typeof logger.info === 'function') {
44
47
  logger.info(msg);
45
48
  } else if (logger && typeof logger.log === 'function') {
46
49
  logger.log(msg);
50
+ } else if (logger && typeof logger === 'function') {
51
+ logger(msg);
47
52
  } else {
48
- console.log(msg);
53
+ throw new Error(
54
+ '[service-common][waitForHealthCheckQueueReady] Invalid logger - Expected logger.info(), logger.log(), or function logger(message).'
55
+ );
49
56
  }
50
57
  };
51
58
 
@@ -48,7 +48,10 @@ async function waitForInfrastructureReady(options = {}) {
48
48
  const redisUrl = buildRedisUrl({ redisUrl: options.redisUrl });
49
49
  const maxWait = runtimeCfg.get('infrastructureHealthWaitMaxTimeMs', options.maxWait);
50
50
  const checkInterval = runtimeCfg.get('infrastructureHealthWaitCheckIntervalMs', options.checkInterval);
51
- const logger = options.logger || console;
51
+ const logger = options.logger;
52
+ if (!logger) {
53
+ throw new Error('[service-common][waitForInfrastructureReady] Missing dependency - logger is required (no console fallback).');
54
+ }
52
55
 
53
56
  // Helper to log messages (compatible with both console and winston)
54
57
  const log = (messageStr) => {
@@ -62,7 +65,9 @@ async function waitForInfrastructureReady(options = {}) {
62
65
  // console.log or similar
63
66
  logger(messageStr);
64
67
  } else {
65
- console.log(messageStr);
68
+ throw new Error(
69
+ '[service-common][waitForInfrastructureReady] Invalid logger - Expected logger.info(), logger.log(), or function logger(message).'
70
+ );
66
71
  }
67
72
  };
68
73
 
@@ -3,46 +3,52 @@
3
3
  /**
4
4
  * PostgreSQL Client Utilities
5
5
  *
6
- * Provides helper functions for building PostgreSQL connection URLs
7
- * with fallback support for infrastructure client configuration.
8
- *
9
- * EXCEPTION: Fallbacks are allowed ONLY for infrastructure client configuration.
10
- * This is the ONLY place where fallbacks are acceptable.
6
+ * Provides helper functions for building PostgreSQL connection URLs.
7
+ *
8
+ * NO FALLBACKS: Topology must be explicit via ENV/config. This module must not
9
+ * embed docker-compose hostnames or credentials.
11
10
  */
12
11
 
13
12
  /**
14
13
  * Build a PostgreSQL connection URL from environment.
15
14
  *
16
- * EXCEPTION: Fallbacks are allowed ONLY for infrastructure client configuration.
17
- * This is the ONLY place where fallbacks are acceptable.
18
- *
19
- * Environment variable precedence (checked in order):
20
- * 1. POSTGRES_URL (full URL, e.g. postgres://monitoring:monitoring_pass@api_monitoring_postgres:5432/monitoring) - ENV variable name
21
- * 2. POSTGRES_HOST + POSTGRES_PORT + POSTGRES_USER + POSTGRES_PASSWORD + POSTGRES_DB (if POSTGRES_URL not set)
22
- * 3. Fallback: postgres://monitoring:monitoring_pass@api_monitoring_postgres:5432/monitoring (docker-compose default)
23
- *
24
15
  * @param {Object} options - Options
25
16
  * @param {Object} [options.env=process.env] - Environment variables
26
- * @param {Object} [options.defaults] - Default host/port/user/password/db overrides
27
17
  * @returns {string} PostgreSQL connection URL
28
18
  */
29
19
  function buildPostgresUrl(options = {}) {
30
20
  const env = options.env || process.env || {};
31
- const defaults = options.defaults || {};
32
21
 
33
- // Priority 1: POSTGRES_URL from environment (ENV variable name: POSTGRES_URL)
34
- if (env.POSTGRES_URL && typeof env.POSTGRES_URL === 'string' && env.POSTGRES_URL.length > 0) {
35
- return env.POSTGRES_URL;
22
+ const url = env.POSTGRES_URL && typeof env.POSTGRES_URL === 'string' ? env.POSTGRES_URL.trim() : '';
23
+ if (url) return url;
24
+
25
+ const host = env.POSTGRES_HOST && typeof env.POSTGRES_HOST === 'string' ? env.POSTGRES_HOST.trim() : '';
26
+ const port = env.POSTGRES_PORT && typeof env.POSTGRES_PORT === 'string' ? env.POSTGRES_PORT.trim() : '';
27
+ const user = env.POSTGRES_USER && typeof env.POSTGRES_USER === 'string' ? env.POSTGRES_USER.trim() : '';
28
+ const password = env.POSTGRES_PASSWORD && typeof env.POSTGRES_PASSWORD === 'string' ? env.POSTGRES_PASSWORD.trim() : '';
29
+ const database = env.POSTGRES_DB && typeof env.POSTGRES_DB === 'string' ? env.POSTGRES_DB.trim() : '';
30
+
31
+ const anyPartsProvided = Boolean(host || port || user || password || database);
32
+ if (!anyPartsProvided) {
33
+ throw new Error(
34
+ '[service-common][postgres] Missing configuration - POSTGRES_URL is required, or provide all: POSTGRES_HOST, POSTGRES_PORT, POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB.'
35
+ );
36
36
  }
37
37
 
38
- // Priority 2: POSTGRES_HOST + POSTGRES_PORT + POSTGRES_USER + POSTGRES_PASSWORD + POSTGRES_DB (if POSTGRES_URL not set)
39
- // Fallback for docker-compose environment (defined in library, not in docker-compose.yml)
40
- const host = env.POSTGRES_HOST || defaults.host || 'api_monitoring_postgres';
41
- const port = env.POSTGRES_PORT || defaults.port || '5432';
42
- const user = env.POSTGRES_USER || defaults.user || 'monitoring';
43
- const password = env.POSTGRES_PASSWORD || defaults.password || 'monitoring_pass';
44
- const database = env.POSTGRES_DB || defaults.database || 'monitoring';
38
+ const missing = [];
39
+ if (!host) missing.push('POSTGRES_HOST');
40
+ if (!port) missing.push('POSTGRES_PORT');
41
+ if (!user) missing.push('POSTGRES_USER');
42
+ if (!password) missing.push('POSTGRES_PASSWORD');
43
+ if (!database) missing.push('POSTGRES_DB');
44
+ if (missing.length > 0) {
45
+ throw new Error(
46
+ `[service-common][postgres] Missing configuration - Partial PostgreSQL config provided. Missing: ${missing.join(', ')}. ` +
47
+ 'Fix: set POSTGRES_URL or set all POSTGRES_* parts.'
48
+ );
49
+ }
45
50
 
51
+ // Do not attempt to do smart encoding here; POSTGRES_URL is the recommended option.
46
52
  return `postgres://${user}:${password}@${host}:${port}/${database}`;
47
53
  }
48
54
 
@@ -59,8 +65,7 @@ function createPostgresPool(options = {}) {
59
65
  const { Pool } = require('pg');
60
66
 
61
67
  const connectionString = buildPostgresUrl({
62
- env: options.env,
63
- defaults: options.defaults
68
+ env: options.env
64
69
  });
65
70
 
66
71
  const poolConfig = {
@@ -81,7 +86,10 @@ function createPostgresPool(options = {}) {
81
86
  * @param {Object} logger - Logger object with info/error methods
82
87
  * @returns {Promise<void>}
83
88
  */
84
- async function connectPostgres(pool, logger = console) {
89
+ async function connectPostgres(pool, logger) {
90
+ if (!logger) {
91
+ throw new Error('[service-common][postgres] Missing dependency - logger is required (no console fallback).');
92
+ }
85
93
  try {
86
94
  await pool.query('SELECT NOW()');
87
95
  if (logger && logger.info) {