@okf/ootils 1.26.1 → 1.26.2

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/node.d.mts CHANGED
@@ -1,5 +1,3 @@
1
- import { Client } from '@elastic/elasticsearch';
2
- import Redis from 'ioredis';
3
1
  import * as _google_cloud_secret_manager_build_src_v1 from '@google-cloud/secret-manager/build/src/v1';
4
2
  import * as mongoose from 'mongoose';
5
3
  import mongoose__default, { Document, Types, Schema } from 'mongoose';
@@ -1182,17 +1180,39 @@ declare namespace MongoConnector {
1182
1180
 
1183
1181
  declare class ElasticSearchConnector {
1184
1182
  static getInstance(): any;
1185
- static getClient(): any;
1186
- constructor(options?: {});
1187
- client: Client | null;
1188
- cloudId: any;
1189
- apiKey: any;
1190
1183
  /**
1191
- * Initialize Elasticsearch client
1184
+ * Get an Elasticsearch client.
1185
+ * @param {string} [env] - Optional env to get a specific env's client.
1186
+ * If omitted, returns the current env's client (backwards compat).
1187
+ */
1188
+ static getClient(env?: string): any;
1189
+ static getEnv(): any;
1190
+ /**
1191
+ * @param {Object} options
1192
+ *
1193
+ * Multi-env mode (preferred):
1194
+ * { env: 'dev', configs: { dev: { cloudId, apiKey }, staging: { cloudId, apiKey }, prod: { cloudId, apiKey } } }
1195
+ *
1196
+ * Legacy single-env mode (backwards compat):
1197
+ * { cloudId: '...', apiKey: '...' }
1198
+ */
1199
+ constructor(options?: Object);
1200
+ env: any;
1201
+ clients: {};
1202
+ client: any;
1203
+ _configs: any;
1204
+ _legacyConfig: {
1205
+ cloudId: any;
1206
+ apiKey: any;
1207
+ } | undefined;
1208
+ /**
1209
+ * Initialize Elasticsearch client(s).
1210
+ * Multi-env: connects to all configured envs.
1211
+ * Legacy: connects a single client.
1192
1212
  */
1193
- connect(): Client;
1213
+ connect(): any;
1194
1214
  /**
1195
- * Close the Elasticsearch client
1215
+ * Close all Elasticsearch clients.
1196
1216
  */
1197
1217
  close(): Promise<void>;
1198
1218
  }
@@ -1203,7 +1223,12 @@ declare namespace ElasticSearchConnector {
1203
1223
  declare class RedisCacheConnector {
1204
1224
  static getEnv(): any;
1205
1225
  static getInstance(): any;
1206
- static getClient(): any;
1226
+ /**
1227
+ * Get a Redis client.
1228
+ * @param {string} [env] - Optional env to get a specific env's client.
1229
+ * If omitted, returns the current env's client (backwards compat).
1230
+ */
1231
+ static getClient(env?: string): any;
1207
1232
  /**
1208
1233
  * Find documents in Redis cache
1209
1234
  * @param {Object} params - Search parameters
@@ -1239,12 +1264,6 @@ declare class RedisCacheConnector {
1239
1264
  /**
1240
1265
  * Generate Redis key for config caching
1241
1266
  * @private
1242
- * @param {Object} params - Parameters for key generation
1243
- * @param {string} params.tenant - The tenant identifier
1244
- * @param {'platformConfigs'|'tpl'} params.modelName - The model/collection name
1245
- * @param {string} params.type - The document type
1246
- * @param {string} [params.env] - Environment (defaults to current env)
1247
- * @returns {string} The Redis key
1248
1267
  */
1249
1268
  private static _getRedisKeyForConfig;
1250
1269
  /**
@@ -1295,18 +1314,33 @@ declare class RedisCacheConnector {
1295
1314
  * @static
1296
1315
  */
1297
1316
  static loadTplsAndPlatformConfigsToCache({ tenant }?: string): Promise<void>;
1298
- constructor(options?: {});
1299
- client: Redis | null;
1300
- host: any;
1317
+ /**
1318
+ * @param {Object} options
1319
+ *
1320
+ * Multi-env mode (preferred):
1321
+ * { env: 'dev', configs: { dev: { host, port, password }, staging: { host, port, password }, prod: { host, port, password } } }
1322
+ *
1323
+ * Legacy single-env mode (backwards compat):
1324
+ * { host: '...', port: 6379, password: '...', env: 'dev' }
1325
+ */
1326
+ constructor(options?: Object);
1301
1327
  env: any;
1302
- port: any;
1303
- password: any;
1328
+ clients: {};
1329
+ client: any;
1330
+ _configs: any;
1331
+ _legacyConfig: {
1332
+ host: any;
1333
+ port: any;
1334
+ password: any;
1335
+ } | undefined;
1304
1336
  /**
1305
- * Initialize Redis client
1337
+ * Initialize Redis client(s).
1338
+ * Multi-env: connects to all configured envs.
1339
+ * Legacy: connects a single client.
1306
1340
  */
1307
- connect: () => Promise<Redis>;
1341
+ connect: () => Promise<any>;
1308
1342
  /**
1309
- * Close the Redis client
1343
+ * Close all Redis clients.
1310
1344
  */
1311
1345
  close(): Promise<void>;
1312
1346
  }
@@ -1333,6 +1367,45 @@ declare class SecretManagerConnector {
1333
1367
  static getDbConfigs(): any;
1334
1368
  static getTenantEnvConfigs(tenant: any): any;
1335
1369
  static getEnvSpecificConfigs(env: any): any;
1370
+ /**
1371
+ * Get Redis configs for all envs, structured for RedisCacheConnector multi-env mode.
1372
+ * @returns {{ dev: { host, port, password }, staging: { host, port, password }, prod: { host, port, password } }}
1373
+ */
1374
+ static getRedisConfigsForAllEnvs(): {
1375
+ dev: {
1376
+ host: any;
1377
+ port: any;
1378
+ password: any;
1379
+ };
1380
+ staging: {
1381
+ host: any;
1382
+ port: any;
1383
+ password: any;
1384
+ };
1385
+ prod: {
1386
+ host: any;
1387
+ port: any;
1388
+ password: any;
1389
+ };
1390
+ };
1391
+ /**
1392
+ * Get Elasticsearch configs for all envs, structured for ElasticSearchConnector multi-env mode.
1393
+ * @returns {{ dev: { cloudId, apiKey }, staging: { cloudId, apiKey }, prod: { cloudId, apiKey } }}
1394
+ */
1395
+ static getElasticConfigsForAllEnvs(): {
1396
+ dev: {
1397
+ cloudId: any;
1398
+ apiKey: any;
1399
+ };
1400
+ staging: {
1401
+ cloudId: any;
1402
+ apiKey: any;
1403
+ };
1404
+ prod: {
1405
+ cloudId: any;
1406
+ apiKey: any;
1407
+ };
1408
+ };
1336
1409
  static addSecretVersion(secretName: any, data: any): Promise<any>;
1337
1410
  static getInstance(): any;
1338
1411
  constructor({ secrets }?: {
package/dist/node.d.ts CHANGED
@@ -1,5 +1,3 @@
1
- import { Client } from '@elastic/elasticsearch';
2
- import Redis from 'ioredis';
3
1
  import * as _google_cloud_secret_manager_build_src_v1 from '@google-cloud/secret-manager/build/src/v1';
4
2
  import * as mongoose from 'mongoose';
5
3
  import mongoose__default, { Document, Types, Schema } from 'mongoose';
@@ -1182,17 +1180,39 @@ declare namespace MongoConnector {
1182
1180
 
1183
1181
  declare class ElasticSearchConnector {
1184
1182
  static getInstance(): any;
1185
- static getClient(): any;
1186
- constructor(options?: {});
1187
- client: Client | null;
1188
- cloudId: any;
1189
- apiKey: any;
1190
1183
  /**
1191
- * Initialize Elasticsearch client
1184
+ * Get an Elasticsearch client.
1185
+ * @param {string} [env] - Optional env to get a specific env's client.
1186
+ * If omitted, returns the current env's client (backwards compat).
1187
+ */
1188
+ static getClient(env?: string): any;
1189
+ static getEnv(): any;
1190
+ /**
1191
+ * @param {Object} options
1192
+ *
1193
+ * Multi-env mode (preferred):
1194
+ * { env: 'dev', configs: { dev: { cloudId, apiKey }, staging: { cloudId, apiKey }, prod: { cloudId, apiKey } } }
1195
+ *
1196
+ * Legacy single-env mode (backwards compat):
1197
+ * { cloudId: '...', apiKey: '...' }
1198
+ */
1199
+ constructor(options?: Object);
1200
+ env: any;
1201
+ clients: {};
1202
+ client: any;
1203
+ _configs: any;
1204
+ _legacyConfig: {
1205
+ cloudId: any;
1206
+ apiKey: any;
1207
+ } | undefined;
1208
+ /**
1209
+ * Initialize Elasticsearch client(s).
1210
+ * Multi-env: connects to all configured envs.
1211
+ * Legacy: connects a single client.
1192
1212
  */
1193
- connect(): Client;
1213
+ connect(): any;
1194
1214
  /**
1195
- * Close the Elasticsearch client
1215
+ * Close all Elasticsearch clients.
1196
1216
  */
1197
1217
  close(): Promise<void>;
1198
1218
  }
@@ -1203,7 +1223,12 @@ declare namespace ElasticSearchConnector {
1203
1223
  declare class RedisCacheConnector {
1204
1224
  static getEnv(): any;
1205
1225
  static getInstance(): any;
1206
- static getClient(): any;
1226
+ /**
1227
+ * Get a Redis client.
1228
+ * @param {string} [env] - Optional env to get a specific env's client.
1229
+ * If omitted, returns the current env's client (backwards compat).
1230
+ */
1231
+ static getClient(env?: string): any;
1207
1232
  /**
1208
1233
  * Find documents in Redis cache
1209
1234
  * @param {Object} params - Search parameters
@@ -1239,12 +1264,6 @@ declare class RedisCacheConnector {
1239
1264
  /**
1240
1265
  * Generate Redis key for config caching
1241
1266
  * @private
1242
- * @param {Object} params - Parameters for key generation
1243
- * @param {string} params.tenant - The tenant identifier
1244
- * @param {'platformConfigs'|'tpl'} params.modelName - The model/collection name
1245
- * @param {string} params.type - The document type
1246
- * @param {string} [params.env] - Environment (defaults to current env)
1247
- * @returns {string} The Redis key
1248
1267
  */
1249
1268
  private static _getRedisKeyForConfig;
1250
1269
  /**
@@ -1295,18 +1314,33 @@ declare class RedisCacheConnector {
1295
1314
  * @static
1296
1315
  */
1297
1316
  static loadTplsAndPlatformConfigsToCache({ tenant }?: string): Promise<void>;
1298
- constructor(options?: {});
1299
- client: Redis | null;
1300
- host: any;
1317
+ /**
1318
+ * @param {Object} options
1319
+ *
1320
+ * Multi-env mode (preferred):
1321
+ * { env: 'dev', configs: { dev: { host, port, password }, staging: { host, port, password }, prod: { host, port, password } } }
1322
+ *
1323
+ * Legacy single-env mode (backwards compat):
1324
+ * { host: '...', port: 6379, password: '...', env: 'dev' }
1325
+ */
1326
+ constructor(options?: Object);
1301
1327
  env: any;
1302
- port: any;
1303
- password: any;
1328
+ clients: {};
1329
+ client: any;
1330
+ _configs: any;
1331
+ _legacyConfig: {
1332
+ host: any;
1333
+ port: any;
1334
+ password: any;
1335
+ } | undefined;
1304
1336
  /**
1305
- * Initialize Redis client
1337
+ * Initialize Redis client(s).
1338
+ * Multi-env: connects to all configured envs.
1339
+ * Legacy: connects a single client.
1306
1340
  */
1307
- connect: () => Promise<Redis>;
1341
+ connect: () => Promise<any>;
1308
1342
  /**
1309
- * Close the Redis client
1343
+ * Close all Redis clients.
1310
1344
  */
1311
1345
  close(): Promise<void>;
1312
1346
  }
@@ -1333,6 +1367,45 @@ declare class SecretManagerConnector {
1333
1367
  static getDbConfigs(): any;
1334
1368
  static getTenantEnvConfigs(tenant: any): any;
1335
1369
  static getEnvSpecificConfigs(env: any): any;
1370
+ /**
1371
+ * Get Redis configs for all envs, structured for RedisCacheConnector multi-env mode.
1372
+ * @returns {{ dev: { host, port, password }, staging: { host, port, password }, prod: { host, port, password } }}
1373
+ */
1374
+ static getRedisConfigsForAllEnvs(): {
1375
+ dev: {
1376
+ host: any;
1377
+ port: any;
1378
+ password: any;
1379
+ };
1380
+ staging: {
1381
+ host: any;
1382
+ port: any;
1383
+ password: any;
1384
+ };
1385
+ prod: {
1386
+ host: any;
1387
+ port: any;
1388
+ password: any;
1389
+ };
1390
+ };
1391
+ /**
1392
+ * Get Elasticsearch configs for all envs, structured for ElasticSearchConnector multi-env mode.
1393
+ * @returns {{ dev: { cloudId, apiKey }, staging: { cloudId, apiKey }, prod: { cloudId, apiKey } }}
1394
+ */
1395
+ static getElasticConfigsForAllEnvs(): {
1396
+ dev: {
1397
+ cloudId: any;
1398
+ apiKey: any;
1399
+ };
1400
+ staging: {
1401
+ cloudId: any;
1402
+ apiKey: any;
1403
+ };
1404
+ prod: {
1405
+ cloudId: any;
1406
+ apiKey: any;
1407
+ };
1408
+ };
1336
1409
  static addSecretVersion(secretName: any, data: any): Promise<any>;
1337
1410
  static getInstance(): any;
1338
1411
  constructor({ secrets }?: {
package/dist/node.js CHANGED
@@ -874,31 +874,54 @@ var require_ElasticSearchConnector = __commonJS({
874
874
  "use strict";
875
875
  var { Client } = require("@elastic/elasticsearch");
876
876
  var ElasticSearchConnector2 = class _ElasticSearchConnector {
877
+ /**
878
+ * @param {Object} options
879
+ *
880
+ * Multi-env mode (preferred):
881
+ * { env: 'dev', configs: { dev: { cloudId, apiKey }, staging: { cloudId, apiKey }, prod: { cloudId, apiKey } } }
882
+ *
883
+ * Legacy single-env mode (backwards compat):
884
+ * { cloudId: '...', apiKey: '...' }
885
+ */
877
886
  constructor(options = {}) {
887
+ this.env = options.env || null;
888
+ this.clients = {};
878
889
  this.client = null;
879
- this.cloudId = options.cloudId;
880
- this.apiKey = options.apiKey;
881
- _ElasticSearchConnector.instance = this;
882
- if (!this.cloudId) {
883
- throw new Error("Cloud ID must be provided in constructor options or ELASTIC_CLOUD_ID environment variable");
884
- }
885
- if (!this.apiKey) {
886
- throw new Error("API Key must be provided in constructor options or ELASTIC_API_KEY environment variable");
890
+ if (options.configs) {
891
+ this._configs = options.configs;
892
+ } else if (options.cloudId && options.apiKey) {
893
+ this._legacyConfig = { cloudId: options.cloudId, apiKey: options.apiKey };
894
+ } else {
895
+ throw new Error("ElasticSearchConnector: provide either { configs } for multi-env or { cloudId, apiKey } for single-env");
887
896
  }
897
+ _ElasticSearchConnector.instance = this;
888
898
  }
889
899
  /**
890
- * Initialize Elasticsearch client
900
+ * Initialize Elasticsearch client(s).
901
+ * Multi-env: connects to all configured envs.
902
+ * Legacy: connects a single client.
891
903
  */
892
904
  connect() {
893
- this.client = new Client({
894
- cloud: {
895
- id: this.cloudId
896
- },
897
- auth: {
898
- apiKey: this.apiKey
905
+ if (this._configs) {
906
+ for (const [env, conf] of Object.entries(this._configs)) {
907
+ if (!conf.cloudId || !conf.apiKey) {
908
+ console.log(`[ES] Skipping env "${env}" \u2014 missing cloudId or apiKey`);
909
+ continue;
910
+ }
911
+ this.clients[env] = new Client({
912
+ cloud: { id: conf.cloudId },
913
+ auth: { apiKey: conf.apiKey }
914
+ });
899
915
  }
900
- });
901
- console.log("\u2705 Elasticsearch client initialized");
916
+ this.client = this.clients[this.env] || null;
917
+ console.log(`\u2705 Elasticsearch clients initialized for envs: ${Object.keys(this.clients).join(", ")}`);
918
+ } else {
919
+ this.client = new Client({
920
+ cloud: { id: this._legacyConfig.cloudId },
921
+ auth: { apiKey: this._legacyConfig.apiKey }
922
+ });
923
+ console.log("\u2705 Elasticsearch client initialized");
924
+ }
902
925
  return this.client;
903
926
  }
904
927
  // Static method to get the instance
@@ -908,22 +931,43 @@ var require_ElasticSearchConnector = __commonJS({
908
931
  }
909
932
  return _ElasticSearchConnector.instance;
910
933
  }
911
- // Static method to get the client
912
- static getClient() {
913
- if (!_ElasticSearchConnector.instance || !_ElasticSearchConnector.instance.client) {
914
- throw new Error("ElasticSearchConnector not initialized or client not connected");
934
+ /**
935
+ * Get an Elasticsearch client.
936
+ * @param {string} [env] - Optional env to get a specific env's client.
937
+ * If omitted, returns the current env's client (backwards compat).
938
+ */
939
+ static getClient(env) {
940
+ const inst = _ElasticSearchConnector.instance;
941
+ if (!inst) {
942
+ throw new Error("ElasticSearchConnector not initialized");
943
+ }
944
+ if (env && inst.clients[env]) {
945
+ return inst.clients[env];
915
946
  }
916
- return _ElasticSearchConnector.instance.client;
947
+ if (inst.client) {
948
+ return inst.client;
949
+ }
950
+ throw new Error("ElasticSearchConnector not initialized or client not connected");
951
+ }
952
+ static getEnv() {
953
+ return _ElasticSearchConnector.instance?.env;
917
954
  }
918
955
  /**
919
- * Close the Elasticsearch client
956
+ * Close all Elasticsearch clients.
920
957
  */
921
958
  async close() {
922
- if (this.client) {
959
+ for (const [env, client] of Object.entries(this.clients)) {
960
+ try {
961
+ await client.close();
962
+ } catch (_) {
963
+ }
964
+ }
965
+ if (this.client && !Object.values(this.clients).includes(this.client)) {
923
966
  await this.client.close();
924
- console.log("\u2705 Elasticsearch client closed");
925
- this.client = null;
926
967
  }
968
+ this.clients = {};
969
+ this.client = null;
970
+ console.log("\u2705 Elasticsearch client(s) closed");
927
971
  }
928
972
  };
929
973
  ElasticSearchConnector2.instance = null;
@@ -1235,6 +1279,36 @@ var init_SecretManagerConnector = __esm({
1235
1279
  const configs = _SecretManagerConnector.getSecret("envSpecificConfigs");
1236
1280
  return env ? configs[env] : configs;
1237
1281
  }
1282
+ /**
1283
+ * Get Redis configs for all envs, structured for RedisCacheConnector multi-env mode.
1284
+ * @returns {{ dev: { host, port, password }, staging: { host, port, password }, prod: { host, port, password } }}
1285
+ */
1286
+ static getRedisConfigsForAllEnvs() {
1287
+ const all = _SecretManagerConnector.getEnvSpecificConfigs();
1288
+ const result = {};
1289
+ for (const env of Object.keys(all)) {
1290
+ const c = all[env];
1291
+ if (c?.REDIS_HOST) {
1292
+ result[env] = { host: c.REDIS_HOST, port: c.REDIS_PORT, password: c.REDIS_PASSWORD };
1293
+ }
1294
+ }
1295
+ return result;
1296
+ }
1297
+ /**
1298
+ * Get Elasticsearch configs for all envs, structured for ElasticSearchConnector multi-env mode.
1299
+ * @returns {{ dev: { cloudId, apiKey }, staging: { cloudId, apiKey }, prod: { cloudId, apiKey } }}
1300
+ */
1301
+ static getElasticConfigsForAllEnvs() {
1302
+ const all = _SecretManagerConnector.getEnvSpecificConfigs();
1303
+ const result = {};
1304
+ for (const env of Object.keys(all)) {
1305
+ const c = all[env];
1306
+ if (c?.ELASTIC_CLOUD_ID) {
1307
+ result[env] = { cloudId: c.ELASTIC_CLOUD_ID, apiKey: c.ELASTIC_API_KEY };
1308
+ }
1309
+ }
1310
+ return result;
1311
+ }
1238
1312
  static async addSecretVersion(secretName, data) {
1239
1313
  const instance = _SecretManagerConnector.instance;
1240
1314
  const payload = Buffer.from(JSON.stringify(data, null, 2));
@@ -3324,24 +3398,56 @@ var BASE_SETTINGS_FOR_CONFIGS_CACHE = [
3324
3398
  }
3325
3399
  ];
3326
3400
  var RedisCacheConnector = class _RedisCacheConnector {
3401
+ /**
3402
+ * @param {Object} options
3403
+ *
3404
+ * Multi-env mode (preferred):
3405
+ * { env: 'dev', configs: { dev: { host, port, password }, staging: { host, port, password }, prod: { host, port, password } } }
3406
+ *
3407
+ * Legacy single-env mode (backwards compat):
3408
+ * { host: '...', port: 6379, password: '...', env: 'dev' }
3409
+ */
3327
3410
  constructor(options = {}) {
3328
3411
  /**
3329
- * Initialize Redis client
3412
+ * Initialize Redis client(s).
3413
+ * Multi-env: connects to all configured envs.
3414
+ * Legacy: connects a single client.
3330
3415
  */
3331
3416
  __publicField(this, "connect", async () => {
3332
3417
  try {
3333
- this.client = new import_ioredis.default({
3334
- host: this.host,
3335
- port: this.port,
3336
- password: this.password
3337
- });
3338
- this.client.on("connect", () => {
3339
- console.log("\u2705 Connected to our redis cache instance!");
3340
- });
3341
- await new Promise((resolve, reject) => {
3342
- this.client.on("ready", resolve);
3343
- this.client.on("error", reject);
3344
- });
3418
+ if (this._configs) {
3419
+ for (const [env, conf] of Object.entries(this._configs)) {
3420
+ if (!conf.host || !conf.port || !conf.password) {
3421
+ console.log(`[Redis] Skipping env "${env}" \u2014 missing config`);
3422
+ continue;
3423
+ }
3424
+ const redisClient = new import_ioredis.default({
3425
+ host: conf.host,
3426
+ port: conf.port,
3427
+ password: conf.password
3428
+ });
3429
+ await new Promise((resolve, reject) => {
3430
+ redisClient.on("ready", resolve);
3431
+ redisClient.on("error", reject);
3432
+ });
3433
+ this.clients[env] = redisClient;
3434
+ }
3435
+ this.client = this.clients[this.env] || null;
3436
+ console.log(`\u2705 Redis clients initialized for envs: ${Object.keys(this.clients).join(", ")}`);
3437
+ } else {
3438
+ this.client = new import_ioredis.default({
3439
+ host: this._legacyConfig.host,
3440
+ port: this._legacyConfig.port,
3441
+ password: this._legacyConfig.password
3442
+ });
3443
+ this.client.on("connect", () => {
3444
+ console.log("\u2705 Connected to our redis cache instance!");
3445
+ });
3446
+ await new Promise((resolve, reject) => {
3447
+ this.client.on("ready", resolve);
3448
+ this.client.on("error", reject);
3449
+ });
3450
+ }
3345
3451
  return this.client;
3346
3452
  } catch (err) {
3347
3453
  console.error(err.message);
@@ -3353,24 +3459,20 @@ var RedisCacheConnector = class _RedisCacheConnector {
3353
3459
  "RedisCacheConnector instance already exists. Use RedisCacheConnector.getInstance() instead."
3354
3460
  );
3355
3461
  }
3356
- this.client = null;
3357
- this.host = options.host;
3358
3462
  this.env = options.env;
3359
- this.port = options.port;
3360
- this.password = options.password;
3361
- _RedisCacheConnector.instance = this;
3362
- if (!this.host) {
3363
- throw new Error("Host must be provided in constructor options");
3364
- }
3365
- if (!this.port) {
3366
- throw new Error("Port must be provided in constructor options");
3367
- }
3368
- if (!this.password) {
3369
- throw new Error("Password must be provided in constructor options");
3463
+ this.clients = {};
3464
+ this.client = null;
3465
+ if (options.configs) {
3466
+ this._configs = options.configs;
3467
+ } else if (options.host && options.port && options.password) {
3468
+ this._legacyConfig = { host: options.host, port: options.port, password: options.password };
3469
+ } else {
3470
+ throw new Error("RedisCacheConnector: provide either { configs } for multi-env or { host, port, password } for single-env");
3370
3471
  }
3371
3472
  if (!this.env) {
3372
3473
  throw new Error("Env must be provided in constructor options");
3373
3474
  }
3475
+ _RedisCacheConnector.instance = this;
3374
3476
  }
3375
3477
  static getEnv() {
3376
3478
  if (!_RedisCacheConnector.instance) {
@@ -3385,14 +3487,23 @@ var RedisCacheConnector = class _RedisCacheConnector {
3385
3487
  }
3386
3488
  return _RedisCacheConnector.instance;
3387
3489
  }
3388
- // Static method to get the client
3389
- static getClient() {
3390
- if (!_RedisCacheConnector.instance || !_RedisCacheConnector.instance.client) {
3391
- throw new Error(
3392
- "RedisCacheConnector not initialized or client not connected"
3393
- );
3490
+ /**
3491
+ * Get a Redis client.
3492
+ * @param {string} [env] - Optional env to get a specific env's client.
3493
+ * If omitted, returns the current env's client (backwards compat).
3494
+ */
3495
+ static getClient(env) {
3496
+ const inst = _RedisCacheConnector.instance;
3497
+ if (!inst) {
3498
+ throw new Error("RedisCacheConnector not initialized or client not connected");
3394
3499
  }
3395
- return _RedisCacheConnector.instance.client;
3500
+ if (env && inst.clients[env]) {
3501
+ return inst.clients[env];
3502
+ }
3503
+ if (inst.client) {
3504
+ return inst.client;
3505
+ }
3506
+ throw new Error("RedisCacheConnector not initialized or client not connected");
3396
3507
  }
3397
3508
  /**
3398
3509
  * Find documents in Redis cache
@@ -3406,8 +3517,8 @@ var RedisCacheConnector = class _RedisCacheConnector {
3406
3517
  */
3407
3518
  static async findConfigsInCache({ tenant, modelName, type, env }) {
3408
3519
  try {
3409
- const client = this.getClient();
3410
3520
  const environment = env || this.getEnv();
3521
+ const client = this.getClient(environment);
3411
3522
  const keyPrefix = `${environment}:${tenant}:${modelName}:`;
3412
3523
  const keys = await client.keys(`${keyPrefix}${type || "*"}`);
3413
3524
  if (keys.length === 0) {
@@ -3472,12 +3583,6 @@ var RedisCacheConnector = class _RedisCacheConnector {
3472
3583
  /**
3473
3584
  * Generate Redis key for config caching
3474
3585
  * @private
3475
- * @param {Object} params - Parameters for key generation
3476
- * @param {string} params.tenant - The tenant identifier
3477
- * @param {'platformConfigs'|'tpl'} params.modelName - The model/collection name
3478
- * @param {string} params.type - The document type
3479
- * @param {string} [params.env] - Environment (defaults to current env)
3480
- * @returns {string} The Redis key
3481
3586
  */
3482
3587
  static _getRedisKeyForConfig({ tenant, modelName, type, env }) {
3483
3588
  const environment = env || this.getEnv();
@@ -3495,12 +3600,13 @@ var RedisCacheConnector = class _RedisCacheConnector {
3495
3600
  * @see {platformConfigTypes} for valid platformConfigs type values
3496
3601
  */
3497
3602
  static async setOneConfigInCache({ tenant, modelName, type, val, env }) {
3498
- const client = this.getClient();
3603
+ const environment = env || this.getEnv();
3604
+ const client = this.getClient(environment);
3499
3605
  const cacheKey = this._getRedisKeyForConfig({
3500
3606
  tenant,
3501
3607
  modelName,
3502
3608
  type,
3503
- env
3609
+ env: environment
3504
3610
  });
3505
3611
  await client.set(cacheKey, JSON.stringify(val));
3506
3612
  }
@@ -3526,12 +3632,13 @@ var RedisCacheConnector = class _RedisCacheConnector {
3526
3632
  newVal,
3527
3633
  env
3528
3634
  }) {
3529
- const client = this.getClient();
3635
+ const environment = env || this.getEnv();
3636
+ const client = this.getClient(environment);
3530
3637
  const cacheKey = this._getRedisKeyForConfig({
3531
3638
  tenant,
3532
3639
  modelName,
3533
3640
  type,
3534
- env
3641
+ env: environment
3535
3642
  });
3536
3643
  const delResult = await client.del(cacheKey);
3537
3644
  let setResult;
@@ -3556,8 +3663,8 @@ var RedisCacheConnector = class _RedisCacheConnector {
3556
3663
  */
3557
3664
  static async loadTplsAndPlatformConfigsToCache({ tenant }) {
3558
3665
  try {
3559
- const client = this.getClient();
3560
3666
  const environment = this.getEnv();
3667
+ const client = this.getClient(environment);
3561
3668
  if (!tenant) throw new Error("No tenant/s defined to recache");
3562
3669
  console.log(`Loading configs and templates into cache...`);
3563
3670
  const tenantToClusterMapping = import_MongoConnector2.MongoConnector.getTenantToClusterMapping();
@@ -3607,14 +3714,21 @@ var RedisCacheConnector = class _RedisCacheConnector {
3607
3714
  }
3608
3715
  }
3609
3716
  /**
3610
- * Close the Redis client
3717
+ * Close all Redis clients.
3611
3718
  */
3612
3719
  async close() {
3613
- if (this.client) {
3720
+ for (const [env, client] of Object.entries(this.clients)) {
3721
+ try {
3722
+ await client.quit();
3723
+ } catch (_) {
3724
+ }
3725
+ }
3726
+ if (this.client && !Object.values(this.clients).includes(this.client)) {
3614
3727
  await this.client.quit();
3615
- console.log("\u2705 Redis client closed");
3616
- this.client = null;
3617
3728
  }
3729
+ this.clients = {};
3730
+ this.client = null;
3731
+ console.log("\u2705 Redis client closed");
3618
3732
  }
3619
3733
  };
3620
3734
  RedisCacheConnector.instance = null;
package/dist/node.mjs CHANGED
@@ -879,31 +879,54 @@ var require_ElasticSearchConnector = __commonJS({
879
879
  "use strict";
880
880
  var { Client } = __require("@elastic/elasticsearch");
881
881
  var ElasticSearchConnector2 = class _ElasticSearchConnector {
882
+ /**
883
+ * @param {Object} options
884
+ *
885
+ * Multi-env mode (preferred):
886
+ * { env: 'dev', configs: { dev: { cloudId, apiKey }, staging: { cloudId, apiKey }, prod: { cloudId, apiKey } } }
887
+ *
888
+ * Legacy single-env mode (backwards compat):
889
+ * { cloudId: '...', apiKey: '...' }
890
+ */
882
891
  constructor(options = {}) {
892
+ this.env = options.env || null;
893
+ this.clients = {};
883
894
  this.client = null;
884
- this.cloudId = options.cloudId;
885
- this.apiKey = options.apiKey;
886
- _ElasticSearchConnector.instance = this;
887
- if (!this.cloudId) {
888
- throw new Error("Cloud ID must be provided in constructor options or ELASTIC_CLOUD_ID environment variable");
889
- }
890
- if (!this.apiKey) {
891
- throw new Error("API Key must be provided in constructor options or ELASTIC_API_KEY environment variable");
895
+ if (options.configs) {
896
+ this._configs = options.configs;
897
+ } else if (options.cloudId && options.apiKey) {
898
+ this._legacyConfig = { cloudId: options.cloudId, apiKey: options.apiKey };
899
+ } else {
900
+ throw new Error("ElasticSearchConnector: provide either { configs } for multi-env or { cloudId, apiKey } for single-env");
892
901
  }
902
+ _ElasticSearchConnector.instance = this;
893
903
  }
894
904
  /**
895
- * Initialize Elasticsearch client
905
+ * Initialize Elasticsearch client(s).
906
+ * Multi-env: connects to all configured envs.
907
+ * Legacy: connects a single client.
896
908
  */
897
909
  connect() {
898
- this.client = new Client({
899
- cloud: {
900
- id: this.cloudId
901
- },
902
- auth: {
903
- apiKey: this.apiKey
910
+ if (this._configs) {
911
+ for (const [env, conf] of Object.entries(this._configs)) {
912
+ if (!conf.cloudId || !conf.apiKey) {
913
+ console.log(`[ES] Skipping env "${env}" \u2014 missing cloudId or apiKey`);
914
+ continue;
915
+ }
916
+ this.clients[env] = new Client({
917
+ cloud: { id: conf.cloudId },
918
+ auth: { apiKey: conf.apiKey }
919
+ });
904
920
  }
905
- });
906
- console.log("\u2705 Elasticsearch client initialized");
921
+ this.client = this.clients[this.env] || null;
922
+ console.log(`\u2705 Elasticsearch clients initialized for envs: ${Object.keys(this.clients).join(", ")}`);
923
+ } else {
924
+ this.client = new Client({
925
+ cloud: { id: this._legacyConfig.cloudId },
926
+ auth: { apiKey: this._legacyConfig.apiKey }
927
+ });
928
+ console.log("\u2705 Elasticsearch client initialized");
929
+ }
907
930
  return this.client;
908
931
  }
909
932
  // Static method to get the instance
@@ -913,22 +936,43 @@ var require_ElasticSearchConnector = __commonJS({
913
936
  }
914
937
  return _ElasticSearchConnector.instance;
915
938
  }
916
- // Static method to get the client
917
- static getClient() {
918
- if (!_ElasticSearchConnector.instance || !_ElasticSearchConnector.instance.client) {
919
- throw new Error("ElasticSearchConnector not initialized or client not connected");
939
+ /**
940
+ * Get an Elasticsearch client.
941
+ * @param {string} [env] - Optional env to get a specific env's client.
942
+ * If omitted, returns the current env's client (backwards compat).
943
+ */
944
+ static getClient(env) {
945
+ const inst = _ElasticSearchConnector.instance;
946
+ if (!inst) {
947
+ throw new Error("ElasticSearchConnector not initialized");
948
+ }
949
+ if (env && inst.clients[env]) {
950
+ return inst.clients[env];
920
951
  }
921
- return _ElasticSearchConnector.instance.client;
952
+ if (inst.client) {
953
+ return inst.client;
954
+ }
955
+ throw new Error("ElasticSearchConnector not initialized or client not connected");
956
+ }
957
+ static getEnv() {
958
+ return _ElasticSearchConnector.instance?.env;
922
959
  }
923
960
  /**
924
- * Close the Elasticsearch client
961
+ * Close all Elasticsearch clients.
925
962
  */
926
963
  async close() {
927
- if (this.client) {
964
+ for (const [env, client] of Object.entries(this.clients)) {
965
+ try {
966
+ await client.close();
967
+ } catch (_) {
968
+ }
969
+ }
970
+ if (this.client && !Object.values(this.clients).includes(this.client)) {
928
971
  await this.client.close();
929
- console.log("\u2705 Elasticsearch client closed");
930
- this.client = null;
931
972
  }
973
+ this.clients = {};
974
+ this.client = null;
975
+ console.log("\u2705 Elasticsearch client(s) closed");
932
976
  }
933
977
  };
934
978
  ElasticSearchConnector2.instance = null;
@@ -1240,6 +1284,36 @@ var init_SecretManagerConnector = __esm({
1240
1284
  const configs = _SecretManagerConnector.getSecret("envSpecificConfigs");
1241
1285
  return env ? configs[env] : configs;
1242
1286
  }
1287
+ /**
1288
+ * Get Redis configs for all envs, structured for RedisCacheConnector multi-env mode.
1289
+ * @returns {{ dev: { host, port, password }, staging: { host, port, password }, prod: { host, port, password } }}
1290
+ */
1291
+ static getRedisConfigsForAllEnvs() {
1292
+ const all = _SecretManagerConnector.getEnvSpecificConfigs();
1293
+ const result = {};
1294
+ for (const env of Object.keys(all)) {
1295
+ const c = all[env];
1296
+ if (c?.REDIS_HOST) {
1297
+ result[env] = { host: c.REDIS_HOST, port: c.REDIS_PORT, password: c.REDIS_PASSWORD };
1298
+ }
1299
+ }
1300
+ return result;
1301
+ }
1302
+ /**
1303
+ * Get Elasticsearch configs for all envs, structured for ElasticSearchConnector multi-env mode.
1304
+ * @returns {{ dev: { cloudId, apiKey }, staging: { cloudId, apiKey }, prod: { cloudId, apiKey } }}
1305
+ */
1306
+ static getElasticConfigsForAllEnvs() {
1307
+ const all = _SecretManagerConnector.getEnvSpecificConfigs();
1308
+ const result = {};
1309
+ for (const env of Object.keys(all)) {
1310
+ const c = all[env];
1311
+ if (c?.ELASTIC_CLOUD_ID) {
1312
+ result[env] = { cloudId: c.ELASTIC_CLOUD_ID, apiKey: c.ELASTIC_API_KEY };
1313
+ }
1314
+ }
1315
+ return result;
1316
+ }
1243
1317
  static async addSecretVersion(secretName, data) {
1244
1318
  const instance = _SecretManagerConnector.instance;
1245
1319
  const payload = Buffer.from(JSON.stringify(data, null, 2));
@@ -3271,24 +3345,56 @@ var BASE_SETTINGS_FOR_CONFIGS_CACHE = [
3271
3345
  }
3272
3346
  ];
3273
3347
  var RedisCacheConnector = class _RedisCacheConnector {
3348
+ /**
3349
+ * @param {Object} options
3350
+ *
3351
+ * Multi-env mode (preferred):
3352
+ * { env: 'dev', configs: { dev: { host, port, password }, staging: { host, port, password }, prod: { host, port, password } } }
3353
+ *
3354
+ * Legacy single-env mode (backwards compat):
3355
+ * { host: '...', port: 6379, password: '...', env: 'dev' }
3356
+ */
3274
3357
  constructor(options = {}) {
3275
3358
  /**
3276
- * Initialize Redis client
3359
+ * Initialize Redis client(s).
3360
+ * Multi-env: connects to all configured envs.
3361
+ * Legacy: connects a single client.
3277
3362
  */
3278
3363
  __publicField(this, "connect", async () => {
3279
3364
  try {
3280
- this.client = new Redis({
3281
- host: this.host,
3282
- port: this.port,
3283
- password: this.password
3284
- });
3285
- this.client.on("connect", () => {
3286
- console.log("\u2705 Connected to our redis cache instance!");
3287
- });
3288
- await new Promise((resolve, reject) => {
3289
- this.client.on("ready", resolve);
3290
- this.client.on("error", reject);
3291
- });
3365
+ if (this._configs) {
3366
+ for (const [env, conf] of Object.entries(this._configs)) {
3367
+ if (!conf.host || !conf.port || !conf.password) {
3368
+ console.log(`[Redis] Skipping env "${env}" \u2014 missing config`);
3369
+ continue;
3370
+ }
3371
+ const redisClient = new Redis({
3372
+ host: conf.host,
3373
+ port: conf.port,
3374
+ password: conf.password
3375
+ });
3376
+ await new Promise((resolve, reject) => {
3377
+ redisClient.on("ready", resolve);
3378
+ redisClient.on("error", reject);
3379
+ });
3380
+ this.clients[env] = redisClient;
3381
+ }
3382
+ this.client = this.clients[this.env] || null;
3383
+ console.log(`\u2705 Redis clients initialized for envs: ${Object.keys(this.clients).join(", ")}`);
3384
+ } else {
3385
+ this.client = new Redis({
3386
+ host: this._legacyConfig.host,
3387
+ port: this._legacyConfig.port,
3388
+ password: this._legacyConfig.password
3389
+ });
3390
+ this.client.on("connect", () => {
3391
+ console.log("\u2705 Connected to our redis cache instance!");
3392
+ });
3393
+ await new Promise((resolve, reject) => {
3394
+ this.client.on("ready", resolve);
3395
+ this.client.on("error", reject);
3396
+ });
3397
+ }
3292
3398
  return this.client;
3293
3399
  } catch (err) {
3294
3400
  console.error(err.message);
@@ -3300,24 +3406,20 @@ var RedisCacheConnector = class _RedisCacheConnector {
3300
3406
  "RedisCacheConnector instance already exists. Use RedisCacheConnector.getInstance() instead."
3301
3407
  );
3302
3408
  }
3303
- this.client = null;
3304
- this.host = options.host;
3305
3409
  this.env = options.env;
3306
- this.port = options.port;
3307
- this.password = options.password;
3308
- _RedisCacheConnector.instance = this;
3309
- if (!this.host) {
3310
- throw new Error("Host must be provided in constructor options");
3311
- }
3312
- if (!this.port) {
3313
- throw new Error("Port must be provided in constructor options");
3314
- }
3315
- if (!this.password) {
3316
- throw new Error("Password must be provided in constructor options");
3410
+ this.clients = {};
3411
+ this.client = null;
3412
+ if (options.configs) {
3413
+ this._configs = options.configs;
3414
+ } else if (options.host && options.port && options.password) {
3415
+ this._legacyConfig = { host: options.host, port: options.port, password: options.password };
3416
+ } else {
3417
+ throw new Error("RedisCacheConnector: provide either { configs } for multi-env or { host, port, password } for single-env");
3317
3418
  }
3318
3419
  if (!this.env) {
3319
3420
  throw new Error("Env must be provided in constructor options");
3320
3421
  }
3422
+ _RedisCacheConnector.instance = this;
3321
3423
  }
3322
3424
  static getEnv() {
3323
3425
  if (!_RedisCacheConnector.instance) {
@@ -3332,14 +3434,23 @@ var RedisCacheConnector = class _RedisCacheConnector {
3332
3434
  }
3333
3435
  return _RedisCacheConnector.instance;
3334
3436
  }
3335
- // Static method to get the client
3336
- static getClient() {
3337
- if (!_RedisCacheConnector.instance || !_RedisCacheConnector.instance.client) {
3338
- throw new Error(
3339
- "RedisCacheConnector not initialized or client not connected"
3340
- );
3437
+ /**
3438
+ * Get a Redis client.
3439
+ * @param {string} [env] - Optional env to get a specific env's client.
3440
+ * If omitted, returns the current env's client (backwards compat).
3441
+ */
3442
+ static getClient(env) {
3443
+ const inst = _RedisCacheConnector.instance;
3444
+ if (!inst) {
3445
+ throw new Error("RedisCacheConnector not initialized or client not connected");
3341
3446
  }
3342
- return _RedisCacheConnector.instance.client;
3447
+ if (env && inst.clients[env]) {
3448
+ return inst.clients[env];
3449
+ }
3450
+ if (inst.client) {
3451
+ return inst.client;
3452
+ }
3453
+ throw new Error("RedisCacheConnector not initialized or client not connected");
3343
3454
  }
3344
3455
  /**
3345
3456
  * Find documents in Redis cache
@@ -3353,8 +3464,8 @@ var RedisCacheConnector = class _RedisCacheConnector {
3353
3464
  */
3354
3465
  static async findConfigsInCache({ tenant, modelName, type, env }) {
3355
3466
  try {
3356
- const client = this.getClient();
3357
3467
  const environment = env || this.getEnv();
3468
+ const client = this.getClient(environment);
3358
3469
  const keyPrefix = `${environment}:${tenant}:${modelName}:`;
3359
3470
  const keys = await client.keys(`${keyPrefix}${type || "*"}`);
3360
3471
  if (keys.length === 0) {
@@ -3419,12 +3530,6 @@ var RedisCacheConnector = class _RedisCacheConnector {
3419
3530
  /**
3420
3531
  * Generate Redis key for config caching
3421
3532
  * @private
3422
- * @param {Object} params - Parameters for key generation
3423
- * @param {string} params.tenant - The tenant identifier
3424
- * @param {'platformConfigs'|'tpl'} params.modelName - The model/collection name
3425
- * @param {string} params.type - The document type
3426
- * @param {string} [params.env] - Environment (defaults to current env)
3427
- * @returns {string} The Redis key
3428
3533
  */
3429
3534
  static _getRedisKeyForConfig({ tenant, modelName, type, env }) {
3430
3535
  const environment = env || this.getEnv();
@@ -3442,12 +3547,13 @@ var RedisCacheConnector = class _RedisCacheConnector {
3442
3547
  * @see {platformConfigTypes} for valid platformConfigs type values
3443
3548
  */
3444
3549
  static async setOneConfigInCache({ tenant, modelName, type, val, env }) {
3445
- const client = this.getClient();
3550
+ const environment = env || this.getEnv();
3551
+ const client = this.getClient(environment);
3446
3552
  const cacheKey = this._getRedisKeyForConfig({
3447
3553
  tenant,
3448
3554
  modelName,
3449
3555
  type,
3450
- env
3556
+ env: environment
3451
3557
  });
3452
3558
  await client.set(cacheKey, JSON.stringify(val));
3453
3559
  }
@@ -3473,12 +3579,13 @@ var RedisCacheConnector = class _RedisCacheConnector {
3473
3579
  newVal,
3474
3580
  env
3475
3581
  }) {
3476
- const client = this.getClient();
3582
+ const environment = env || this.getEnv();
3583
+ const client = this.getClient(environment);
3477
3584
  const cacheKey = this._getRedisKeyForConfig({
3478
3585
  tenant,
3479
3586
  modelName,
3480
3587
  type,
3481
- env
3588
+ env: environment
3482
3589
  });
3483
3590
  const delResult = await client.del(cacheKey);
3484
3591
  let setResult;
@@ -3503,8 +3610,8 @@ var RedisCacheConnector = class _RedisCacheConnector {
3503
3610
  */
3504
3611
  static async loadTplsAndPlatformConfigsToCache({ tenant }) {
3505
3612
  try {
3506
- const client = this.getClient();
3507
3613
  const environment = this.getEnv();
3614
+ const client = this.getClient(environment);
3508
3615
  if (!tenant) throw new Error("No tenant/s defined to recache");
3509
3616
  console.log(`Loading configs and templates into cache...`);
3510
3617
  const tenantToClusterMapping = import_MongoConnector2.MongoConnector.getTenantToClusterMapping();
@@ -3554,14 +3661,21 @@ var RedisCacheConnector = class _RedisCacheConnector {
3554
3661
  }
3555
3662
  }
3556
3663
  /**
3557
- * Close the Redis client
3664
+ * Close all Redis clients.
3558
3665
  */
3559
3666
  async close() {
3560
- if (this.client) {
3667
+ for (const [env, client] of Object.entries(this.clients)) {
3668
+ try {
3669
+ await client.quit();
3670
+ } catch (_) {
3671
+ }
3672
+ }
3673
+ if (this.client && !Object.values(this.clients).includes(this.client)) {
3561
3674
  await this.client.quit();
3562
- console.log("\u2705 Redis client closed");
3563
- this.client = null;
3564
3675
  }
3676
+ this.clients = {};
3677
+ this.client = null;
3678
+ console.log("\u2705 Redis client closed");
3565
3679
  }
3566
3680
  };
3567
3681
  RedisCacheConnector.instance = null;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.26.1",
6
+ "version": "1.26.2",
7
7
  "description": "Utility functions for both browser and Node.js",
8
8
  "main": "dist/index.js",
9
9
  "module": "dist/index.mjs",