eip-cloud-services 1.1.15 → 1.2.1

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/index.js CHANGED
@@ -3,4 +3,5 @@ exports.redis = require ( './src/redis' );
3
3
  exports.s3 = require ( './src/s3' );
4
4
  exports.cdn = require ( './src/cdn' );
5
5
  exports.lambda = require ( './src/lambda' );
6
- exports.mysql = require ( './src/mysql' );
6
+ exports.mysql = require ( './src/mysql' );
7
+ exports.mysql8 = require ( './src/mysql8' );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eip-cloud-services",
3
- "version": "1.1.15",
3
+ "version": "1.2.1",
4
4
  "description": "Houses a collection of helpers for connecting with Cloud services.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -22,6 +22,7 @@
22
22
  "google-auth-library": "^8.8.0",
23
23
  "ioredis": "^5.3.2",
24
24
  "mysql": "^2.18.1",
25
+ "mysql2": "^3.14.4",
25
26
  "redis": "^4.6.7"
26
27
  }
27
28
  }
package/src/mysql8.js ADDED
@@ -0,0 +1,141 @@
1
+ // eip-cloud-services/mysql8.js
2
+ 'use strict';
3
+
4
+ const fs = require('fs');
5
+ const mysql = require('mysql2/promise'); // Promise API (app code)
6
+ const mysqlCb = require('mysql2'); // Callback API (for migrations)
7
+
8
+ // Load config only if ./config exists
9
+ let config = {};
10
+ const configDirPath = `${process.cwd()}/config`;
11
+ if (fs.existsSync(configDirPath) && fs.statSync(configDirPath).isDirectory()) {
12
+ // eslint-disable-next-line global-require
13
+ config = require('config');
14
+ }
15
+
16
+ // Promise pools (existing)
17
+ const pools = {};
18
+ // NEW: Callback pools
19
+ const callbackPools = {};
20
+
21
+ /** Get promise pool (existing) */
22
+ function getPool(poolId = 'main') {
23
+ const poolConfig = (config.mysql && (config.mysql[poolId] || config.mysql)) || {};
24
+
25
+ if (!pools[poolId]) {
26
+ pools[poolId] = mysql.createPool({
27
+ host: poolConfig.host,
28
+ user: poolConfig.user,
29
+ password: poolConfig.password,
30
+ database: poolConfig.database || undefined,
31
+ connectionLimit: poolConfig.connectionLimit || 10,
32
+ multipleStatements: poolConfig.multipleStatements !== false,
33
+ waitForConnections: true,
34
+ queueLimit: 0,
35
+ // Works fine with MySQL 8's caching_sha2_password; add TLS in prod as needed
36
+ // ssl: { minVersion: 'TLSv1.2', rejectUnauthorized: false },
37
+ // allowPublicKeyRetrieval: true, // only needed for sha256_password without SSL
38
+ });
39
+ }
40
+ return pools[poolId];
41
+ }
42
+
43
+ /** NEW: Get callback-style pool (for tools like mysql-migrations) */
44
+ function getCallbackPool(poolId = 'main') {
45
+ const poolConfig = (config.mysql && (config.mysql[poolId] || config.mysql)) || {};
46
+
47
+ if (!callbackPools[poolId]) {
48
+ callbackPools[poolId] = mysqlCb.createPool({
49
+ host: poolConfig.host,
50
+ user: poolConfig.user,
51
+ password: poolConfig.password,
52
+ database: poolConfig.database || undefined,
53
+ connectionLimit: poolConfig.connectionLimit || 10,
54
+ multipleStatements: poolConfig.multipleStatements !== false,
55
+ waitForConnections: true,
56
+ queueLimit: 0,
57
+ // Same note re: TLS / allowPublicKeyRetrieval as above.
58
+ // ssl: { minVersion: 'TLSv1.2', rejectUnauthorized: false },
59
+ // allowPublicKeyRetrieval: true,
60
+ });
61
+ }
62
+ return callbackPools[poolId];
63
+ }
64
+
65
+ // ----- promise query helpers (existing) -----
66
+ async function runQuery(connection, query) {
67
+ try {
68
+ const [rows] = await connection.query(query);
69
+ return rows;
70
+ } catch (error) {
71
+ const MAX_ERROR_LENGTH = 500;
72
+ const MAX_QUERY_LENGTH = 300;
73
+ const raw = error && (error.stack || error.message || String(error));
74
+ const shortError = String(raw).slice(0, MAX_ERROR_LENGTH);
75
+ const shortQuery = String(query).slice(0, MAX_QUERY_LENGTH);
76
+ console.error('Query Error:', shortError);
77
+ console.error('Truncated Query:', shortQuery);
78
+ throw new Error(`There was a problem with query: ${shortError}`);
79
+ } finally {
80
+ try { if (connection?.release) connection.release(); } catch {}
81
+ }
82
+ }
83
+
84
+ exports.getPool = getPool;
85
+ exports.getCallbackPool = getCallbackPool; // <-- NEW EXPORT
86
+
87
+ exports.getConnection = async (poolId = 'main') => {
88
+ try {
89
+ const pool = getPool(poolId);
90
+ const connection = await pool.getConnection();
91
+ return connection;
92
+ } catch (error) {
93
+ console.error(error);
94
+ console.error('There was a problem getting a new database connection.');
95
+ throw new Error('There was a problem getting a new database connection.');
96
+ }
97
+ };
98
+
99
+ exports.query = async (queryString, poolId = 'main') => {
100
+ let sql = String(queryString || '');
101
+ if (!sql.endsWith(';')) sql += ';';
102
+ const connection = await exports.getConnection(poolId);
103
+ return runQuery(connection, sql);
104
+ };
105
+
106
+ /** Delete a promise pool */
107
+ exports.deletePool = async (poolId) => {
108
+ const pool = pools[poolId];
109
+ if (!pool) return;
110
+ await pool.end().catch(() => {});
111
+ delete pools[poolId];
112
+ };
113
+
114
+ /** NEW: Delete a callback pool */
115
+ exports.deleteCallbackPool = async (poolId) => {
116
+ const pool = callbackPools[poolId];
117
+ if (!pool) return;
118
+ await new Promise((res) => pool.end(res));
119
+ delete callbackPools[poolId];
120
+ };
121
+
122
+ /** Close all pools (promise + callback) */
123
+ exports.kill = async () => {
124
+ const p1 = Promise.all(
125
+ Object.keys(pools).map(async (id) => {
126
+ try { await pools[id].end(); } catch {}
127
+ delete pools[id];
128
+ })
129
+ );
130
+ const p2 = Promise.all(
131
+ Object.keys(callbackPools).map(
132
+ (id) =>
133
+ new Promise((res) => {
134
+ try { callbackPools[id].end(() => res()); }
135
+ catch { res(); }
136
+ finally { delete callbackPools[id]; }
137
+ })
138
+ )
139
+ );
140
+ await Promise.all([p1, p2]);
141
+ };
package/src/redis.js CHANGED
@@ -36,7 +36,10 @@ const getClient = async ( clientId = 'main' ) => {
36
36
  port: node.port
37
37
  } ) );
38
38
 
39
- redisClient = new Redis.Cluster ( clusterNodes );
39
+ redisClient = new Redis.Cluster ( clusterNodes, {
40
+ dnsLookup: (address, callback) => callback(null, address),
41
+ redisOptions: config?.redis?.options || {tls: {} }
42
+ } );
40
43
 
41
44
  // Await until the cluster is ready
42
45
  await new Promise ( ( resolve, reject ) => {