service-call-library-dev 0.1.0
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/index.cjs +1122 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +92 -0
- package/dist/index.d.ts +92 -0
- package/dist/index.js +1094 -0
- package/dist/index.js.map +1 -0
- package/package.json +45 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,1122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __esm = (fn, res) => function __init() {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
};
|
|
11
|
+
var __export = (target, all) => {
|
|
12
|
+
for (var name in all)
|
|
13
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
14
|
+
};
|
|
15
|
+
var __copyProps = (to, from, except, desc) => {
|
|
16
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
17
|
+
for (let key of __getOwnPropNames(from))
|
|
18
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
19
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
24
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
25
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
26
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
27
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
28
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
29
|
+
mod
|
|
30
|
+
));
|
|
31
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
33
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
34
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
35
|
+
if (decorator = decorators[i])
|
|
36
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
37
|
+
if (kind && result) __defProp(target, key, result);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
|
|
41
|
+
|
|
42
|
+
// src/logging/logger.service.ts
|
|
43
|
+
var import_winston, LoggerService;
|
|
44
|
+
var init_logger_service = __esm({
|
|
45
|
+
"src/logging/logger.service.ts"() {
|
|
46
|
+
"use strict";
|
|
47
|
+
import_winston = __toESM(require("winston"), 1);
|
|
48
|
+
LoggerService = class {
|
|
49
|
+
static {
|
|
50
|
+
this.logger = import_winston.default.createLogger({
|
|
51
|
+
level: process.env.LOG_LEVEL ?? "info",
|
|
52
|
+
format: import_winston.default.format.combine(
|
|
53
|
+
import_winston.default.format.timestamp(),
|
|
54
|
+
import_winston.default.format.errors({ stack: true }),
|
|
55
|
+
import_winston.default.format.json()
|
|
56
|
+
),
|
|
57
|
+
transports: [new import_winston.default.transports.Console()]
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
static info(message, meta) {
|
|
61
|
+
this.logger.info(message, meta);
|
|
62
|
+
}
|
|
63
|
+
static error(message, meta) {
|
|
64
|
+
this.logger.error(message, meta);
|
|
65
|
+
}
|
|
66
|
+
static warn(message, meta) {
|
|
67
|
+
this.logger.warn(message, meta);
|
|
68
|
+
}
|
|
69
|
+
static debug(message, meta) {
|
|
70
|
+
this.logger.debug(message, meta);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// src/utils/zookeeperConfig.ts
|
|
77
|
+
var getZooKeeperConfig;
|
|
78
|
+
var init_zookeeperConfig = __esm({
|
|
79
|
+
"src/utils/zookeeperConfig.ts"() {
|
|
80
|
+
"use strict";
|
|
81
|
+
getZooKeeperConfig = () => {
|
|
82
|
+
const config = {
|
|
83
|
+
connectionString: process.env.ZOOKEEPER_CONNECTION_STRING,
|
|
84
|
+
infraPath: process.env.ZOOKEEPER_INFRA_PATH,
|
|
85
|
+
servicePath: process.env.ZOOKEEPER_SERVICE_PATH,
|
|
86
|
+
user: process.env.ZOOKEEPER_USER,
|
|
87
|
+
password: process.env.ZOOKEEPER_PASSWORD
|
|
88
|
+
};
|
|
89
|
+
if (!config.connectionString) {
|
|
90
|
+
throw new Error("ZOOKEEPER_CONNECTION_STRING is required");
|
|
91
|
+
}
|
|
92
|
+
return config;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// src/utils/zookeeperCrypto.ts
|
|
98
|
+
var import_crypto, fs, path, LOG_PREFIX, INFRA_VALUE_REGEX, parseInfraValue, getPrivateKeyPath, decryptWithAlias, getServicePrivateKeyPath, decryptWithPrivateKey;
|
|
99
|
+
var init_zookeeperCrypto = __esm({
|
|
100
|
+
"src/utils/zookeeperCrypto.ts"() {
|
|
101
|
+
"use strict";
|
|
102
|
+
import_crypto = __toESM(require("crypto"), 1);
|
|
103
|
+
fs = __toESM(require("fs"), 1);
|
|
104
|
+
path = __toESM(require("path"), 1);
|
|
105
|
+
init_logger_service();
|
|
106
|
+
LOG_PREFIX = "[ZK] ";
|
|
107
|
+
INFRA_VALUE_REGEX = /^devEnc:([A-Za-z0-9+/=_-]+):([A-Za-z0-9-_]+)$/;
|
|
108
|
+
parseInfraValue = (value) => {
|
|
109
|
+
const match = value.match(INFRA_VALUE_REGEX);
|
|
110
|
+
if (!match) return null;
|
|
111
|
+
return {
|
|
112
|
+
prefix: "devEnc",
|
|
113
|
+
encryptedData: match[1],
|
|
114
|
+
alias: match[2]
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
getPrivateKeyPath = (alias) => {
|
|
118
|
+
const baseDir = process.env.PRIVATE_KEY_DIR || path.join(process.cwd(), "keys");
|
|
119
|
+
return path.join(baseDir, `private_key_${alias}.pem`);
|
|
120
|
+
};
|
|
121
|
+
decryptWithAlias = (encryptedData, alias) => {
|
|
122
|
+
try {
|
|
123
|
+
const privateKeyPath = getPrivateKeyPath(alias);
|
|
124
|
+
if (!fs.existsSync(privateKeyPath)) {
|
|
125
|
+
throw new Error(`Private key file not found for alias '${alias}': ${privateKeyPath}`);
|
|
126
|
+
}
|
|
127
|
+
const privateKey = fs.readFileSync(privateKeyPath, "utf8");
|
|
128
|
+
const buffer = Buffer.from(encryptedData, "base64");
|
|
129
|
+
const attempts = [
|
|
130
|
+
{
|
|
131
|
+
key: privateKey,
|
|
132
|
+
padding: import_crypto.default.constants.RSA_PKCS1_OAEP_PADDING,
|
|
133
|
+
oaepHash: "sha256"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
key: privateKey,
|
|
137
|
+
padding: import_crypto.default.constants.RSA_PKCS1_OAEP_PADDING,
|
|
138
|
+
oaepHash: "sha1"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
key: privateKey,
|
|
142
|
+
padding: import_crypto.default.constants.RSA_PKCS1_PADDING
|
|
143
|
+
}
|
|
144
|
+
];
|
|
145
|
+
let lastError = null;
|
|
146
|
+
for (const options of attempts) {
|
|
147
|
+
try {
|
|
148
|
+
const out = import_crypto.default.privateDecrypt(options, buffer);
|
|
149
|
+
return out.toString("utf-8");
|
|
150
|
+
} catch (error) {
|
|
151
|
+
lastError = error;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
LoggerService.error(`${LOG_PREFIX}RSA decryption failed with alias '${alias}'`, {
|
|
155
|
+
error: lastError
|
|
156
|
+
});
|
|
157
|
+
throw new Error(`Decryption failed for alias '${alias}'`);
|
|
158
|
+
} catch (error) {
|
|
159
|
+
LoggerService.error(`${LOG_PREFIX}failed to decrypt with alias '${alias}'`, {
|
|
160
|
+
error: error?.message || error
|
|
161
|
+
});
|
|
162
|
+
throw new Error(`Decryption failed for alias '${alias}': ${error.message}`);
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
getServicePrivateKeyPath = () => {
|
|
166
|
+
const baseDir = process.env.PRIVATE_KEY_DIR || path.join(process.cwd(), "keys");
|
|
167
|
+
return path.join(baseDir, "private.pem");
|
|
168
|
+
};
|
|
169
|
+
decryptWithPrivateKey = (encryptedData) => {
|
|
170
|
+
try {
|
|
171
|
+
const privateKeyPath = getServicePrivateKeyPath();
|
|
172
|
+
if (!fs.existsSync(privateKeyPath)) {
|
|
173
|
+
throw new Error(`Private key file not found: ${privateKeyPath}`);
|
|
174
|
+
}
|
|
175
|
+
const privateKey = fs.readFileSync(privateKeyPath, "utf8");
|
|
176
|
+
const buffer = Buffer.from(encryptedData, "base64");
|
|
177
|
+
const attempts = [
|
|
178
|
+
{
|
|
179
|
+
key: privateKey,
|
|
180
|
+
padding: import_crypto.default.constants.RSA_PKCS1_OAEP_PADDING,
|
|
181
|
+
oaepHash: "sha256"
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
key: privateKey,
|
|
185
|
+
padding: import_crypto.default.constants.RSA_PKCS1_OAEP_PADDING,
|
|
186
|
+
oaepHash: "sha1"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
key: privateKey,
|
|
190
|
+
padding: import_crypto.default.constants.RSA_PKCS1_PADDING
|
|
191
|
+
}
|
|
192
|
+
];
|
|
193
|
+
let lastError = null;
|
|
194
|
+
for (const options of attempts) {
|
|
195
|
+
try {
|
|
196
|
+
const out = import_crypto.default.privateDecrypt(options, buffer);
|
|
197
|
+
return out.toString("utf-8");
|
|
198
|
+
} catch (error) {
|
|
199
|
+
lastError = error;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
LoggerService.error(`${LOG_PREFIX}RSA decryption failed with private.pem`, {
|
|
203
|
+
error: lastError
|
|
204
|
+
});
|
|
205
|
+
throw new Error("All decryption attempts failed");
|
|
206
|
+
} catch (error) {
|
|
207
|
+
LoggerService.error(`${LOG_PREFIX}failed to decrypt with private.pem`, {
|
|
208
|
+
error: error?.message || error
|
|
209
|
+
});
|
|
210
|
+
throw new Error(`Decryption failed: ${error.message}`);
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// src/utils/zookeeper.ts
|
|
217
|
+
var zookeeper_exports = {};
|
|
218
|
+
__export(zookeeper_exports, {
|
|
219
|
+
default: () => zookeeper_default,
|
|
220
|
+
registerRestartCallback: () => registerRestartCallback
|
|
221
|
+
});
|
|
222
|
+
var import_node_zookeeper_client, process2, SESSION_TIMEOUT, CONNECT_TIMEOUT, LOG_PREFIX2, isInfraDataBeingProcessed, isServiceDataBeingProcessed, hasLoadedInfraOnce, hasLoadedServiceOnce, currentClient, connectWatchdog, hasInfraPath, hasServicePath, restartCallback, registerRestartCallback, processEnvironmentData, decryptInfraValue, decryptServiceValue, handleZooKeeperData, connectToPath, cleanupClient, startZooKeeperClient, zookeeper_default;
|
|
223
|
+
var init_zookeeper = __esm({
|
|
224
|
+
"src/utils/zookeeper.ts"() {
|
|
225
|
+
"use strict";
|
|
226
|
+
import_node_zookeeper_client = __toESM(require("node-zookeeper-client"), 1);
|
|
227
|
+
process2 = __toESM(require("process"), 1);
|
|
228
|
+
init_zookeeperConfig();
|
|
229
|
+
init_zookeeperCrypto();
|
|
230
|
+
SESSION_TIMEOUT = 3e7;
|
|
231
|
+
CONNECT_TIMEOUT = 1e7;
|
|
232
|
+
LOG_PREFIX2 = "[ZK] ";
|
|
233
|
+
isInfraDataBeingProcessed = false;
|
|
234
|
+
isServiceDataBeingProcessed = false;
|
|
235
|
+
hasLoadedInfraOnce = false;
|
|
236
|
+
hasLoadedServiceOnce = false;
|
|
237
|
+
currentClient = null;
|
|
238
|
+
connectWatchdog = null;
|
|
239
|
+
hasInfraPath = false;
|
|
240
|
+
hasServicePath = false;
|
|
241
|
+
restartCallback = null;
|
|
242
|
+
registerRestartCallback = (callback) => {
|
|
243
|
+
restartCallback = callback;
|
|
244
|
+
};
|
|
245
|
+
processEnvironmentData = (data, isInfraPath) => {
|
|
246
|
+
const pathType = isInfraPath ? "infra" : "service";
|
|
247
|
+
const lines = data.split("\n");
|
|
248
|
+
let processedCount = 0;
|
|
249
|
+
let encryptedCount = 0;
|
|
250
|
+
let errorCount = 0;
|
|
251
|
+
const errors = [];
|
|
252
|
+
for (const line of lines) {
|
|
253
|
+
if (!line.trim()) continue;
|
|
254
|
+
const firstEqualIndex = line.indexOf("=");
|
|
255
|
+
if (firstEqualIndex === -1) continue;
|
|
256
|
+
const key = line.slice(0, firstEqualIndex).trim();
|
|
257
|
+
const value = line.slice(firstEqualIndex + 1).trim();
|
|
258
|
+
if (!key || value.length === 0) continue;
|
|
259
|
+
try {
|
|
260
|
+
if (value.startsWith("devEnc:") && isInfraPath) {
|
|
261
|
+
encryptedCount++;
|
|
262
|
+
let decryptedValue = decryptInfraValue(value);
|
|
263
|
+
decryptedValue = decryptedValue.replace(/(\r?\n)$/, "");
|
|
264
|
+
process2.env[key] = decryptedValue;
|
|
265
|
+
} else if (value.startsWith("devEnc:")) {
|
|
266
|
+
encryptedCount++;
|
|
267
|
+
let decryptedValue = decryptServiceValue(value);
|
|
268
|
+
decryptedValue = decryptedValue.replace(/(\r?\n)$/, "");
|
|
269
|
+
process2.env[key] = decryptedValue;
|
|
270
|
+
} else {
|
|
271
|
+
process2.env[key] = value;
|
|
272
|
+
}
|
|
273
|
+
processedCount++;
|
|
274
|
+
} catch (error) {
|
|
275
|
+
errorCount++;
|
|
276
|
+
errors.push({
|
|
277
|
+
key,
|
|
278
|
+
error: error?.message || "Unknown decryption error"
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (errorCount > 0) {
|
|
283
|
+
console.log(
|
|
284
|
+
JSON.stringify({
|
|
285
|
+
type: "ZK",
|
|
286
|
+
message: `${LOG_PREFIX2}errors processing environment variables`,
|
|
287
|
+
pathType,
|
|
288
|
+
processedCount,
|
|
289
|
+
encryptedCount,
|
|
290
|
+
errorCount,
|
|
291
|
+
errors: errors.slice(0, 10),
|
|
292
|
+
totalErrors: errors.length,
|
|
293
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
294
|
+
})
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
decryptInfraValue = (value) => {
|
|
299
|
+
const encryptedValue = parseInfraValue(value);
|
|
300
|
+
if (!encryptedValue) {
|
|
301
|
+
throw new Error("Invalid encrypted value format");
|
|
302
|
+
}
|
|
303
|
+
const decryptedValue = decryptWithAlias(
|
|
304
|
+
encryptedValue.encryptedData,
|
|
305
|
+
encryptedValue.alias
|
|
306
|
+
);
|
|
307
|
+
return decryptedValue;
|
|
308
|
+
};
|
|
309
|
+
decryptServiceValue = (value) => {
|
|
310
|
+
const cleanValue = value.replace("devEnc:", "");
|
|
311
|
+
const encryptedValue = decryptWithPrivateKey(cleanValue);
|
|
312
|
+
return encryptedValue;
|
|
313
|
+
};
|
|
314
|
+
handleZooKeeperData = (client, zkPath, isInfraPath, resolve, reject) => {
|
|
315
|
+
const pathType = isInfraPath ? "infra" : "service";
|
|
316
|
+
const isBeingProcessed = isInfraPath ? isInfraDataBeingProcessed : isServiceDataBeingProcessed;
|
|
317
|
+
if (isBeingProcessed) return;
|
|
318
|
+
if (isInfraPath) {
|
|
319
|
+
isInfraDataBeingProcessed = true;
|
|
320
|
+
} else {
|
|
321
|
+
isServiceDataBeingProcessed = true;
|
|
322
|
+
}
|
|
323
|
+
client.getData(
|
|
324
|
+
zkPath,
|
|
325
|
+
(event) => {
|
|
326
|
+
if (event.type === import_node_zookeeper_client.default.Event.NODE_DATA_CHANGED) {
|
|
327
|
+
console.log(
|
|
328
|
+
JSON.stringify({
|
|
329
|
+
type: "ZK",
|
|
330
|
+
message: `${LOG_PREFIX2}Config changed detected, restarting application`,
|
|
331
|
+
pathType: isInfraPath ? "infra" : "service",
|
|
332
|
+
path: zkPath,
|
|
333
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
334
|
+
})
|
|
335
|
+
);
|
|
336
|
+
if (restartCallback) {
|
|
337
|
+
restartCallback().catch((error) => {
|
|
338
|
+
console.log(
|
|
339
|
+
JSON.stringify({
|
|
340
|
+
type: "ZK",
|
|
341
|
+
message: `${LOG_PREFIX2}Error during restart`,
|
|
342
|
+
error: {
|
|
343
|
+
message: error?.message || "Unknown error",
|
|
344
|
+
stack: error?.stack
|
|
345
|
+
},
|
|
346
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
347
|
+
})
|
|
348
|
+
);
|
|
349
|
+
process2.exit(0);
|
|
350
|
+
});
|
|
351
|
+
} else {
|
|
352
|
+
console.log(
|
|
353
|
+
JSON.stringify({
|
|
354
|
+
type: "ZK",
|
|
355
|
+
message: `${LOG_PREFIX2}No restart callback registered, exiting process`,
|
|
356
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
357
|
+
})
|
|
358
|
+
);
|
|
359
|
+
process2.exit(0);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
},
|
|
363
|
+
(error, data) => {
|
|
364
|
+
if (isInfraPath) {
|
|
365
|
+
isInfraDataBeingProcessed = false;
|
|
366
|
+
} else {
|
|
367
|
+
isServiceDataBeingProcessed = false;
|
|
368
|
+
}
|
|
369
|
+
if (error) {
|
|
370
|
+
const errorMsg = `${LOG_PREFIX2}getData failed for ${pathType} path: ${zkPath}`;
|
|
371
|
+
console.log(
|
|
372
|
+
JSON.stringify({
|
|
373
|
+
type: "ZK",
|
|
374
|
+
message: errorMsg,
|
|
375
|
+
pathType,
|
|
376
|
+
path: zkPath,
|
|
377
|
+
error: {
|
|
378
|
+
message: error?.message || "Unknown error",
|
|
379
|
+
code: error?.code,
|
|
380
|
+
name: error?.name,
|
|
381
|
+
stack: error?.stack,
|
|
382
|
+
errno: error?.errno
|
|
383
|
+
},
|
|
384
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
385
|
+
})
|
|
386
|
+
);
|
|
387
|
+
reject(new Error(errorMsg));
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
if (!data) {
|
|
391
|
+
reject(
|
|
392
|
+
new Error(
|
|
393
|
+
`${LOG_PREFIX2}No data received for ${pathType} path: ${zkPath}`
|
|
394
|
+
)
|
|
395
|
+
);
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
try {
|
|
399
|
+
const rawData = data.toString("utf8");
|
|
400
|
+
processEnvironmentData(rawData, isInfraPath);
|
|
401
|
+
if (isInfraPath) {
|
|
402
|
+
hasInfraPath = true;
|
|
403
|
+
} else {
|
|
404
|
+
hasServicePath = true;
|
|
405
|
+
}
|
|
406
|
+
if (isInfraPath) {
|
|
407
|
+
if (!hasLoadedInfraOnce) {
|
|
408
|
+
hasLoadedInfraOnce = true;
|
|
409
|
+
console.log(
|
|
410
|
+
JSON.stringify({
|
|
411
|
+
type: "ZK",
|
|
412
|
+
message: `${LOG_PREFIX2}loaded infra environment variables`,
|
|
413
|
+
path: zkPath
|
|
414
|
+
})
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
} else {
|
|
418
|
+
if (!hasLoadedServiceOnce) {
|
|
419
|
+
hasLoadedServiceOnce = true;
|
|
420
|
+
console.log(
|
|
421
|
+
JSON.stringify({
|
|
422
|
+
type: "ZK",
|
|
423
|
+
message: `${LOG_PREFIX2}loaded service environment variables`,
|
|
424
|
+
path: zkPath
|
|
425
|
+
})
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
if (hasInfraPath && hasServicePath) {
|
|
430
|
+
resolve();
|
|
431
|
+
}
|
|
432
|
+
} catch (error2) {
|
|
433
|
+
const errorMsg = `${LOG_PREFIX2}error processing data for ${pathType} path: ${zkPath}`;
|
|
434
|
+
console.log(
|
|
435
|
+
JSON.stringify({
|
|
436
|
+
type: "ZK",
|
|
437
|
+
message: errorMsg,
|
|
438
|
+
pathType,
|
|
439
|
+
path: zkPath,
|
|
440
|
+
error: {
|
|
441
|
+
message: error2?.message || "Unknown error",
|
|
442
|
+
code: error2?.code,
|
|
443
|
+
name: error2?.name,
|
|
444
|
+
stack: error2?.stack
|
|
445
|
+
},
|
|
446
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
447
|
+
})
|
|
448
|
+
);
|
|
449
|
+
reject(new Error(errorMsg));
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
);
|
|
453
|
+
};
|
|
454
|
+
connectToPath = (client, zkPath, isInfraPath, resolve, reject) => {
|
|
455
|
+
const pathType = isInfraPath ? "infra" : "service";
|
|
456
|
+
client.exists(
|
|
457
|
+
zkPath,
|
|
458
|
+
() => {
|
|
459
|
+
},
|
|
460
|
+
(error, stat) => {
|
|
461
|
+
if (error) {
|
|
462
|
+
const errorMsg = `${LOG_PREFIX2}exists check failed for ${pathType} path: ${zkPath}`;
|
|
463
|
+
console.log(
|
|
464
|
+
JSON.stringify({
|
|
465
|
+
type: "ZK",
|
|
466
|
+
message: errorMsg,
|
|
467
|
+
pathType,
|
|
468
|
+
path: zkPath,
|
|
469
|
+
error: {
|
|
470
|
+
message: error?.message || "Unknown error",
|
|
471
|
+
code: error?.code,
|
|
472
|
+
name: error?.name,
|
|
473
|
+
stack: error?.stack,
|
|
474
|
+
errno: error?.errno
|
|
475
|
+
},
|
|
476
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
477
|
+
})
|
|
478
|
+
);
|
|
479
|
+
reject(new Error(errorMsg));
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
if (stat) {
|
|
483
|
+
handleZooKeeperData(client, zkPath, isInfraPath, resolve, reject);
|
|
484
|
+
} else {
|
|
485
|
+
const errorMsg = `${LOG_PREFIX2}path does not exist: ${zkPath}`;
|
|
486
|
+
console.log(
|
|
487
|
+
JSON.stringify({
|
|
488
|
+
type: "ZK",
|
|
489
|
+
message: errorMsg,
|
|
490
|
+
pathType,
|
|
491
|
+
path: zkPath,
|
|
492
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
493
|
+
})
|
|
494
|
+
);
|
|
495
|
+
reject(new Error(errorMsg));
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
);
|
|
499
|
+
};
|
|
500
|
+
cleanupClient = () => {
|
|
501
|
+
try {
|
|
502
|
+
if (currentClient?.close) currentClient.close();
|
|
503
|
+
} catch (e) {
|
|
504
|
+
if (e?.message) {
|
|
505
|
+
console.log(
|
|
506
|
+
JSON.stringify({
|
|
507
|
+
type: "ZK",
|
|
508
|
+
message: `${LOG_PREFIX2}error closing client`,
|
|
509
|
+
error: {
|
|
510
|
+
message: e?.message,
|
|
511
|
+
stack: e?.stack
|
|
512
|
+
},
|
|
513
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
514
|
+
})
|
|
515
|
+
);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
currentClient = null;
|
|
519
|
+
if (connectWatchdog) {
|
|
520
|
+
clearTimeout(connectWatchdog);
|
|
521
|
+
connectWatchdog = null;
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
startZooKeeperClient = () => {
|
|
525
|
+
return new Promise((resolve, reject) => {
|
|
526
|
+
let resolved = false;
|
|
527
|
+
const safeResolve = () => {
|
|
528
|
+
if (!resolved) {
|
|
529
|
+
resolved = true;
|
|
530
|
+
resolve();
|
|
531
|
+
}
|
|
532
|
+
};
|
|
533
|
+
try {
|
|
534
|
+
const config = getZooKeeperConfig();
|
|
535
|
+
console.log(
|
|
536
|
+
JSON.stringify({
|
|
537
|
+
type: "ZK",
|
|
538
|
+
message: `${LOG_PREFIX2}initializing`,
|
|
539
|
+
config: {
|
|
540
|
+
connectionString: config.connectionString,
|
|
541
|
+
infraPath: config.infraPath,
|
|
542
|
+
servicePath: config.servicePath,
|
|
543
|
+
hasAuth: !!(config.user && config.password),
|
|
544
|
+
user: config.user || null,
|
|
545
|
+
sessionTimeout: SESSION_TIMEOUT
|
|
546
|
+
}
|
|
547
|
+
})
|
|
548
|
+
);
|
|
549
|
+
cleanupClient();
|
|
550
|
+
hasInfraPath = false;
|
|
551
|
+
hasServicePath = false;
|
|
552
|
+
hasLoadedInfraOnce = false;
|
|
553
|
+
hasLoadedServiceOnce = false;
|
|
554
|
+
isInfraDataBeingProcessed = false;
|
|
555
|
+
isServiceDataBeingProcessed = false;
|
|
556
|
+
const client = import_node_zookeeper_client.default.createClient(config.connectionString, {
|
|
557
|
+
sessionTimeout: SESSION_TIMEOUT,
|
|
558
|
+
retries: 0
|
|
559
|
+
// No retries - fail fast
|
|
560
|
+
});
|
|
561
|
+
currentClient = client;
|
|
562
|
+
if (config.user && config.password) {
|
|
563
|
+
client.addAuthInfo(
|
|
564
|
+
"digest",
|
|
565
|
+
Buffer.from(`${config.user}:${config.password}`)
|
|
566
|
+
);
|
|
567
|
+
}
|
|
568
|
+
connectWatchdog = setTimeout(() => {
|
|
569
|
+
if (currentClient === client) {
|
|
570
|
+
cleanupClient();
|
|
571
|
+
const errorMsg = `${LOG_PREFIX2}Connection timeout after ${CONNECT_TIMEOUT}ms`;
|
|
572
|
+
console.log(
|
|
573
|
+
JSON.stringify({
|
|
574
|
+
type: "ZK",
|
|
575
|
+
message: errorMsg,
|
|
576
|
+
config: {
|
|
577
|
+
connectionString: config.connectionString
|
|
578
|
+
},
|
|
579
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
580
|
+
})
|
|
581
|
+
);
|
|
582
|
+
reject(new Error(errorMsg));
|
|
583
|
+
}
|
|
584
|
+
}, CONNECT_TIMEOUT);
|
|
585
|
+
client.on("connected", () => {
|
|
586
|
+
console.log(
|
|
587
|
+
JSON.stringify({
|
|
588
|
+
type: "ZK",
|
|
589
|
+
message: `${LOG_PREFIX2}connected`,
|
|
590
|
+
config: {
|
|
591
|
+
connectionString: config.connectionString,
|
|
592
|
+
infraPath: config.infraPath,
|
|
593
|
+
servicePath: config.servicePath,
|
|
594
|
+
user: config.user,
|
|
595
|
+
password: config.password
|
|
596
|
+
}
|
|
597
|
+
})
|
|
598
|
+
);
|
|
599
|
+
if (connectWatchdog) {
|
|
600
|
+
clearTimeout(connectWatchdog);
|
|
601
|
+
connectWatchdog = null;
|
|
602
|
+
}
|
|
603
|
+
connectToPath(client, config.infraPath, true, safeResolve, reject);
|
|
604
|
+
connectToPath(client, config.servicePath, false, safeResolve, reject);
|
|
605
|
+
});
|
|
606
|
+
client.on("disconnected", () => {
|
|
607
|
+
console.log(
|
|
608
|
+
JSON.stringify({
|
|
609
|
+
type: "ZK",
|
|
610
|
+
message: `${LOG_PREFIX2}disconnected`,
|
|
611
|
+
config: {
|
|
612
|
+
connectionString: config.connectionString
|
|
613
|
+
}
|
|
614
|
+
})
|
|
615
|
+
);
|
|
616
|
+
cleanupClient();
|
|
617
|
+
reject(new Error(`${LOG_PREFIX2}Disconnected from ZooKeeper`));
|
|
618
|
+
});
|
|
619
|
+
client.on("expired", () => {
|
|
620
|
+
console.log(
|
|
621
|
+
JSON.stringify({
|
|
622
|
+
type: "ZK",
|
|
623
|
+
message: `${LOG_PREFIX2}session expired`,
|
|
624
|
+
config: {
|
|
625
|
+
connectionString: config.connectionString
|
|
626
|
+
}
|
|
627
|
+
})
|
|
628
|
+
);
|
|
629
|
+
cleanupClient();
|
|
630
|
+
reject(new Error(`${LOG_PREFIX2}ZooKeeper session expired`));
|
|
631
|
+
});
|
|
632
|
+
client.on("error", (error) => {
|
|
633
|
+
console.log(
|
|
634
|
+
JSON.stringify({
|
|
635
|
+
type: "ZK",
|
|
636
|
+
message: `${LOG_PREFIX2}error`,
|
|
637
|
+
error: {
|
|
638
|
+
message: error?.message || "Unknown error",
|
|
639
|
+
code: error?.code,
|
|
640
|
+
name: error?.name,
|
|
641
|
+
stack: error?.stack,
|
|
642
|
+
errno: error?.errno,
|
|
643
|
+
syscall: error?.syscall,
|
|
644
|
+
address: error?.address,
|
|
645
|
+
port: error?.port
|
|
646
|
+
},
|
|
647
|
+
config: {
|
|
648
|
+
connectionString: config.connectionString
|
|
649
|
+
},
|
|
650
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
651
|
+
})
|
|
652
|
+
);
|
|
653
|
+
cleanupClient();
|
|
654
|
+
reject(
|
|
655
|
+
new Error(
|
|
656
|
+
`${LOG_PREFIX2}ZooKeeper error: ${error?.message || "Unknown error"}`
|
|
657
|
+
)
|
|
658
|
+
);
|
|
659
|
+
});
|
|
660
|
+
client.connect();
|
|
661
|
+
} catch (error) {
|
|
662
|
+
const config = getZooKeeperConfig();
|
|
663
|
+
console.log(
|
|
664
|
+
JSON.stringify({
|
|
665
|
+
type: "ZK",
|
|
666
|
+
message: `${LOG_PREFIX2}initialization failed`,
|
|
667
|
+
error: {
|
|
668
|
+
message: error?.message || "Unknown error",
|
|
669
|
+
code: error?.code,
|
|
670
|
+
name: error?.name,
|
|
671
|
+
stack: error?.stack,
|
|
672
|
+
errno: error?.errno,
|
|
673
|
+
syscall: error?.syscall
|
|
674
|
+
},
|
|
675
|
+
config: {
|
|
676
|
+
connectionString: config.connectionString,
|
|
677
|
+
infraPath: config.infraPath,
|
|
678
|
+
servicePath: config.servicePath,
|
|
679
|
+
hasAuth: !!(config.user && config.password)
|
|
680
|
+
},
|
|
681
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
682
|
+
})
|
|
683
|
+
);
|
|
684
|
+
cleanupClient();
|
|
685
|
+
reject(
|
|
686
|
+
new Error(
|
|
687
|
+
`${LOG_PREFIX2}Initialization exception: ${error?.message || "Unknown error"}`
|
|
688
|
+
)
|
|
689
|
+
);
|
|
690
|
+
}
|
|
691
|
+
});
|
|
692
|
+
};
|
|
693
|
+
zookeeper_default = startZooKeeperClient;
|
|
694
|
+
}
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
// src/index.ts
|
|
698
|
+
var index_exports = {};
|
|
699
|
+
__export(index_exports, {
|
|
700
|
+
ServiceCallLibrary: () => ServiceCallLibrary,
|
|
701
|
+
TYPES: () => TYPES
|
|
702
|
+
});
|
|
703
|
+
module.exports = __toCommonJS(index_exports);
|
|
704
|
+
var import_reflect_metadata = require("reflect-metadata");
|
|
705
|
+
|
|
706
|
+
// src/inversify.container.ts
|
|
707
|
+
var import_inversify7 = require("inversify");
|
|
708
|
+
|
|
709
|
+
// src/configs/redis-client.ts
|
|
710
|
+
var import_redis = require("redis");
|
|
711
|
+
init_logger_service();
|
|
712
|
+
var RedisClient = class _RedisClient {
|
|
713
|
+
constructor() {
|
|
714
|
+
this.reconnectAttempts = 0;
|
|
715
|
+
this.maxReconnectAttempts = 2;
|
|
716
|
+
this.connectPromise = null;
|
|
717
|
+
this.client = (0, import_redis.createClient)({
|
|
718
|
+
socket: {
|
|
719
|
+
host: process.env.REDIS_HOST ?? "127.0.0.1",
|
|
720
|
+
port: Number(process.env.REDIS_PORT) || 6379,
|
|
721
|
+
reconnectStrategy: (retries) => {
|
|
722
|
+
this.reconnectAttempts = retries;
|
|
723
|
+
if (retries > this.maxReconnectAttempts) {
|
|
724
|
+
LoggerService.error("Redis reconnect attempts exceeded", {
|
|
725
|
+
retries,
|
|
726
|
+
host: process.env.REDIS_HOST ?? "127.0.0.1",
|
|
727
|
+
port: Number(process.env.REDIS_PORT) || 6379
|
|
728
|
+
});
|
|
729
|
+
return new Error("Redis reconnect attempts exceeded");
|
|
730
|
+
}
|
|
731
|
+
return 1e3;
|
|
732
|
+
}
|
|
733
|
+
},
|
|
734
|
+
password: process.env.REDIS_PASSWORD || void 0
|
|
735
|
+
});
|
|
736
|
+
this.client.on("error", (err) => {
|
|
737
|
+
LoggerService.error("Redis error", {
|
|
738
|
+
error: err?.message || err,
|
|
739
|
+
reconnectAttempts: this.reconnectAttempts
|
|
740
|
+
});
|
|
741
|
+
});
|
|
742
|
+
this.client.on("connect", () => {
|
|
743
|
+
LoggerService.info("Redis connected", {
|
|
744
|
+
host: process.env.REDIS_HOST ?? "127.0.0.1",
|
|
745
|
+
port: Number(process.env.REDIS_PORT) || 6379
|
|
746
|
+
});
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
static getInstance() {
|
|
750
|
+
if (!_RedisClient.instance) {
|
|
751
|
+
_RedisClient.instance = new _RedisClient();
|
|
752
|
+
}
|
|
753
|
+
return _RedisClient.instance;
|
|
754
|
+
}
|
|
755
|
+
async connect() {
|
|
756
|
+
if (this.client.isOpen) {
|
|
757
|
+
return this.client;
|
|
758
|
+
}
|
|
759
|
+
if (!this.connectPromise) {
|
|
760
|
+
this.connectPromise = this.client.connect().catch((err) => {
|
|
761
|
+
LoggerService.error("Redis initial connect error", {
|
|
762
|
+
error: err?.message || err
|
|
763
|
+
});
|
|
764
|
+
this.connectPromise = null;
|
|
765
|
+
throw err;
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
return await this.connectPromise;
|
|
769
|
+
}
|
|
770
|
+
getClient() {
|
|
771
|
+
return this.client;
|
|
772
|
+
}
|
|
773
|
+
async disconnect() {
|
|
774
|
+
if (this.client.isOpen) {
|
|
775
|
+
await this.client.quit();
|
|
776
|
+
LoggerService.info("Redis disconnected");
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
isConnected() {
|
|
780
|
+
return this.client.isOpen;
|
|
781
|
+
}
|
|
782
|
+
};
|
|
783
|
+
var redis_client_default = RedisClient.getInstance();
|
|
784
|
+
|
|
785
|
+
// src/modules/cache/cacheService.ts
|
|
786
|
+
var import_inversify = require("inversify");
|
|
787
|
+
var CacheService = class {
|
|
788
|
+
constructor() {
|
|
789
|
+
this.client = redis_client_default.getClient();
|
|
790
|
+
}
|
|
791
|
+
async setValue(key, value, ttlInSeconds) {
|
|
792
|
+
const payload = JSON.stringify(value);
|
|
793
|
+
if (ttlInSeconds && ttlInSeconds > 0) {
|
|
794
|
+
await this.client.setEx(key, ttlInSeconds, payload);
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
797
|
+
const result = await this.client.set(key, payload);
|
|
798
|
+
return result === null ? void 0 : result;
|
|
799
|
+
}
|
|
800
|
+
async getValue(key) {
|
|
801
|
+
const result = await this.client.get(key);
|
|
802
|
+
return result ? JSON.parse(result) : null;
|
|
803
|
+
}
|
|
804
|
+
async deleteValue(key) {
|
|
805
|
+
await this.client.del(key);
|
|
806
|
+
}
|
|
807
|
+
async hSet(key, hash) {
|
|
808
|
+
return this.client.hSet(key, hash);
|
|
809
|
+
}
|
|
810
|
+
async hmGet(key, ...fields) {
|
|
811
|
+
return this.client.hmGet(key, fields);
|
|
812
|
+
}
|
|
813
|
+
async hGetAll(key) {
|
|
814
|
+
return this.client.hGetAll(key);
|
|
815
|
+
}
|
|
816
|
+
async expire(key, ttlSeconds) {
|
|
817
|
+
return this.client.expire(key, ttlSeconds);
|
|
818
|
+
}
|
|
819
|
+
async sAdd(key, ...members) {
|
|
820
|
+
return this.client.sAdd(key, members);
|
|
821
|
+
}
|
|
822
|
+
async sMembers(key) {
|
|
823
|
+
return this.client.sMembers(key);
|
|
824
|
+
}
|
|
825
|
+
async sRem(key, ...members) {
|
|
826
|
+
return this.client.sRem(key, members);
|
|
827
|
+
}
|
|
828
|
+
async sCard(key) {
|
|
829
|
+
return this.client.sCard(key);
|
|
830
|
+
}
|
|
831
|
+
async del(...keys) {
|
|
832
|
+
return this.client.del(keys);
|
|
833
|
+
}
|
|
834
|
+
multi() {
|
|
835
|
+
return this.client.multi();
|
|
836
|
+
}
|
|
837
|
+
};
|
|
838
|
+
CacheService = __decorateClass([
|
|
839
|
+
(0, import_inversify.injectable)()
|
|
840
|
+
], CacheService);
|
|
841
|
+
|
|
842
|
+
// src/modules/cache/cacheController.ts
|
|
843
|
+
var import_inversify2 = require("inversify");
|
|
844
|
+
|
|
845
|
+
// src/inversify.types.ts
|
|
846
|
+
var TYPES = {
|
|
847
|
+
CacheService: /* @__PURE__ */ Symbol.for("CacheService"),
|
|
848
|
+
CacheController: /* @__PURE__ */ Symbol.for("CacheController"),
|
|
849
|
+
SsoController: /* @__PURE__ */ Symbol.for("SsoController"),
|
|
850
|
+
SsoService: /* @__PURE__ */ Symbol.for("SsoService")
|
|
851
|
+
};
|
|
852
|
+
|
|
853
|
+
// src/types/cache.types.ts
|
|
854
|
+
var REQUIRED_BIN_NAMES = ["bin1", "bin2", "bin3", "bin4", "bin5"];
|
|
855
|
+
|
|
856
|
+
// src/modules/cache/cacheController.ts
|
|
857
|
+
var SET_NAME_PREFIX = process.env.SCRIPT_SET_NAME_PREFIX ?? "scriptSet";
|
|
858
|
+
var DEFAULT_EXPIRE_TIME_MS = Number(
|
|
859
|
+
process.env.SCRIPT_PUT_CACHE_EXPIRE_TIME_MS ?? 6e5
|
|
860
|
+
);
|
|
861
|
+
var CacheController = class {
|
|
862
|
+
constructor(cacheService) {
|
|
863
|
+
this.cacheService = cacheService;
|
|
864
|
+
}
|
|
865
|
+
async putScriptRecord(setName, key, record, ttlSeconds) {
|
|
866
|
+
for (const bin of REQUIRED_BIN_NAMES) {
|
|
867
|
+
if (typeof record[bin] === "undefined") {
|
|
868
|
+
throw new Error(`Field ${bin} is required`);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
const safeRecord = {};
|
|
872
|
+
for (const bin of REQUIRED_BIN_NAMES) {
|
|
873
|
+
const value = record[bin];
|
|
874
|
+
if (typeof value !== "string") {
|
|
875
|
+
throw new Error(`Invalid value for ${bin}`);
|
|
876
|
+
}
|
|
877
|
+
safeRecord[bin] = value;
|
|
878
|
+
}
|
|
879
|
+
const redisKey = `${setName}:${key}`;
|
|
880
|
+
const ttl = typeof ttlSeconds === "number" ? ttlSeconds : Math.floor(DEFAULT_EXPIRE_TIME_MS / 1e3);
|
|
881
|
+
const multi = this.cacheService.multi();
|
|
882
|
+
const entries = Object.entries(safeRecord);
|
|
883
|
+
if (!entries.length) {
|
|
884
|
+
throw new Error("No record found to store in Redis");
|
|
885
|
+
}
|
|
886
|
+
for (const [field, value] of entries) {
|
|
887
|
+
multi.hSet(redisKey, field, value);
|
|
888
|
+
}
|
|
889
|
+
if (ttl > 0) {
|
|
890
|
+
multi.expire(redisKey, ttl);
|
|
891
|
+
}
|
|
892
|
+
for (const bin of REQUIRED_BIN_NAMES) {
|
|
893
|
+
const value = safeRecord[bin];
|
|
894
|
+
if (value) {
|
|
895
|
+
multi.sAdd(`index:${setName}:${bin}:${value}`, redisKey);
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
multi.sAdd(`set:${setName}:keys`, redisKey);
|
|
899
|
+
await multi.exec();
|
|
900
|
+
return { redisKey, ttl };
|
|
901
|
+
}
|
|
902
|
+
async getScriptRecord(setName, key) {
|
|
903
|
+
const redisKey = `${setName}:${key}`;
|
|
904
|
+
const values = await this.cacheService.hmGet(redisKey, ...REQUIRED_BIN_NAMES);
|
|
905
|
+
if (!values || values.every((v) => v === null)) {
|
|
906
|
+
return null;
|
|
907
|
+
}
|
|
908
|
+
const record = {};
|
|
909
|
+
REQUIRED_BIN_NAMES.forEach((bin, i) => {
|
|
910
|
+
record[bin] = values[i];
|
|
911
|
+
});
|
|
912
|
+
return record;
|
|
913
|
+
}
|
|
914
|
+
async equalScriptRecordsWithIndex(setName, binName, value) {
|
|
915
|
+
const indexKey = this.buildIndexKey(setName, binName, value);
|
|
916
|
+
const redisKeys = await this.cacheService.sMembers(indexKey);
|
|
917
|
+
if (!redisKeys.length) {
|
|
918
|
+
return [];
|
|
919
|
+
}
|
|
920
|
+
const multi = this.cacheService.multi();
|
|
921
|
+
for (const key of redisKeys) {
|
|
922
|
+
multi.hGetAll(key);
|
|
923
|
+
}
|
|
924
|
+
const responses = await multi.exec();
|
|
925
|
+
if (!responses) {
|
|
926
|
+
throw new Error("Pipeline execution failed");
|
|
927
|
+
}
|
|
928
|
+
return responses.map((record, idx) => {
|
|
929
|
+
const formattedRecord = {};
|
|
930
|
+
REQUIRED_BIN_NAMES.forEach((bin) => {
|
|
931
|
+
formattedRecord[bin] = record[bin] ?? null;
|
|
932
|
+
});
|
|
933
|
+
return {
|
|
934
|
+
redisKey: redisKeys[idx],
|
|
935
|
+
record: formattedRecord
|
|
936
|
+
};
|
|
937
|
+
});
|
|
938
|
+
}
|
|
939
|
+
async countScriptRecordsWithIndex(setName, binName, value) {
|
|
940
|
+
return this.cacheService.sCard(this.buildIndexKey(setName, binName, value));
|
|
941
|
+
}
|
|
942
|
+
async deleteScriptRecord(setName, key) {
|
|
943
|
+
const redisKey = `${setName}:${key}`;
|
|
944
|
+
const hash = await this.cacheService.hGetAll(redisKey);
|
|
945
|
+
if (!hash || !Object.keys(hash).length) {
|
|
946
|
+
return false;
|
|
947
|
+
}
|
|
948
|
+
const multi = this.cacheService.multi();
|
|
949
|
+
multi.del(redisKey);
|
|
950
|
+
for (const bin of REQUIRED_BIN_NAMES) {
|
|
951
|
+
const value = hash[bin];
|
|
952
|
+
if (value) {
|
|
953
|
+
multi.sRem(this.buildIndexKey(setName, bin, value), redisKey);
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
multi.sRem(`set:${setName}:keys`, redisKey);
|
|
957
|
+
await multi.exec();
|
|
958
|
+
return true;
|
|
959
|
+
}
|
|
960
|
+
async createBaseStructureForScript(totalSets = 5) {
|
|
961
|
+
const multi = this.cacheService.multi();
|
|
962
|
+
for (let s = 1; s <= totalSets; s++) {
|
|
963
|
+
const setName = `${SET_NAME_PREFIX}${s}`;
|
|
964
|
+
const keyStr = `${setName}_key`;
|
|
965
|
+
const redisKey = `${setName}:${keyStr}`;
|
|
966
|
+
const hashMap = {};
|
|
967
|
+
for (const bin of REQUIRED_BIN_NAMES) {
|
|
968
|
+
hashMap[bin] = "DUMMY";
|
|
969
|
+
}
|
|
970
|
+
for (const [field, val] of Object.entries(hashMap)) {
|
|
971
|
+
multi.hSet(redisKey, field, val);
|
|
972
|
+
}
|
|
973
|
+
multi.sAdd(`set:${setName}:keys`, redisKey);
|
|
974
|
+
for (const bin of REQUIRED_BIN_NAMES) {
|
|
975
|
+
multi.sAdd(this.buildIndexKey(setName, bin, hashMap[bin]), redisKey);
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
await multi.exec();
|
|
979
|
+
}
|
|
980
|
+
async setValue(key, value, ttlInSeconds) {
|
|
981
|
+
return this.cacheService.setValue(key, value, ttlInSeconds);
|
|
982
|
+
}
|
|
983
|
+
async getValue(key) {
|
|
984
|
+
return this.cacheService.getValue(key);
|
|
985
|
+
}
|
|
986
|
+
async deleteValue(key) {
|
|
987
|
+
await this.cacheService.deleteValue(key);
|
|
988
|
+
}
|
|
989
|
+
buildIndexKey(setName, binName, value) {
|
|
990
|
+
return `index:${setName}:${binName}:${value}`;
|
|
991
|
+
}
|
|
992
|
+
};
|
|
993
|
+
CacheController = __decorateClass([
|
|
994
|
+
(0, import_inversify2.injectable)(),
|
|
995
|
+
__decorateParam(0, (0, import_inversify2.inject)(TYPES.CacheService))
|
|
996
|
+
], CacheController);
|
|
997
|
+
|
|
998
|
+
// src/modules/sso/sso.controller.ts
|
|
999
|
+
var import_inversify4 = require("inversify");
|
|
1000
|
+
var SsoController = class {
|
|
1001
|
+
constructor(ssoService) {
|
|
1002
|
+
this.ssoService = ssoService;
|
|
1003
|
+
}
|
|
1004
|
+
async getUserByAccesstoken(AccessToken) {
|
|
1005
|
+
const getData = await this.ssoService.getUserByAccesstoken(AccessToken);
|
|
1006
|
+
return getData;
|
|
1007
|
+
}
|
|
1008
|
+
async getUserByIdentity(identity, identityType) {
|
|
1009
|
+
return await this.ssoService.getUserByIdentity(identity, identityType);
|
|
1010
|
+
}
|
|
1011
|
+
};
|
|
1012
|
+
SsoController = __decorateClass([
|
|
1013
|
+
(0, import_inversify4.injectable)(),
|
|
1014
|
+
__decorateParam(0, (0, import_inversify4.inject)(TYPES.SsoService))
|
|
1015
|
+
], SsoController);
|
|
1016
|
+
|
|
1017
|
+
// src/modules/sso/sso.service.ts
|
|
1018
|
+
var import_inversify6 = require("inversify");
|
|
1019
|
+
var SsoService = class {
|
|
1020
|
+
async getUserByAccesstoken(AccessToken) {
|
|
1021
|
+
let data = null;
|
|
1022
|
+
try {
|
|
1023
|
+
const response = await fetch(`${process.env.SsoUrl}/users`, {
|
|
1024
|
+
method: "GET",
|
|
1025
|
+
headers: {
|
|
1026
|
+
"accept": "application/json",
|
|
1027
|
+
"Accept-Language": "en",
|
|
1028
|
+
"Authorization": `Bearer ${AccessToken}`
|
|
1029
|
+
}
|
|
1030
|
+
});
|
|
1031
|
+
data = await response.json();
|
|
1032
|
+
if (!response.ok) {
|
|
1033
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
1034
|
+
}
|
|
1035
|
+
return {
|
|
1036
|
+
data,
|
|
1037
|
+
error: false,
|
|
1038
|
+
errorMessage: ""
|
|
1039
|
+
};
|
|
1040
|
+
} catch (error) {
|
|
1041
|
+
return {
|
|
1042
|
+
data,
|
|
1043
|
+
error: true,
|
|
1044
|
+
errorMessage: error.message
|
|
1045
|
+
};
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
async getUserByIdentity(identity, identityType) {
|
|
1049
|
+
const url = `http://sso-sandbox.sandpod.ir/social/POD/users/${identity}?identityType=${identityType}`;
|
|
1050
|
+
try {
|
|
1051
|
+
const response = await fetch(url, {
|
|
1052
|
+
method: "GET",
|
|
1053
|
+
headers: {
|
|
1054
|
+
"accept": "application/json",
|
|
1055
|
+
"Accept-Language": "en",
|
|
1056
|
+
"Authorization": `Bearer ${process.env.AuthToken}`
|
|
1057
|
+
}
|
|
1058
|
+
});
|
|
1059
|
+
const data = JSON.parse(await response.text());
|
|
1060
|
+
if (!response.ok) {
|
|
1061
|
+
throw new Error(`HTTP error! status: ${response.status} and error is ${data}`);
|
|
1062
|
+
}
|
|
1063
|
+
return {
|
|
1064
|
+
data,
|
|
1065
|
+
error: false,
|
|
1066
|
+
errorMessage: ""
|
|
1067
|
+
};
|
|
1068
|
+
} catch (error) {
|
|
1069
|
+
return {
|
|
1070
|
+
data: null,
|
|
1071
|
+
error: true,
|
|
1072
|
+
errorMessage: error
|
|
1073
|
+
};
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
};
|
|
1077
|
+
SsoService = __decorateClass([
|
|
1078
|
+
(0, import_inversify6.injectable)()
|
|
1079
|
+
], SsoService);
|
|
1080
|
+
|
|
1081
|
+
// src/inversify.container.ts
|
|
1082
|
+
function createContainer(_options = {}) {
|
|
1083
|
+
const container = new import_inversify7.Container();
|
|
1084
|
+
container.bind(TYPES.CacheService).to(CacheService).inSingletonScope();
|
|
1085
|
+
container.bind(TYPES.SsoService).to(SsoService).inSingletonScope();
|
|
1086
|
+
container.bind(TYPES.CacheController).to(CacheController).inSingletonScope();
|
|
1087
|
+
container.bind(TYPES.SsoController).to(SsoController).inSingletonScope();
|
|
1088
|
+
return container;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
// src/service-call-library.ts
|
|
1092
|
+
var ServiceCallLibrary = class {
|
|
1093
|
+
constructor(options = {}) {
|
|
1094
|
+
this.ready = null;
|
|
1095
|
+
this.container = createContainer(options);
|
|
1096
|
+
this.ssoController = this.container.get(TYPES.SsoController);
|
|
1097
|
+
this.cacheController = this.container.get(TYPES.CacheController);
|
|
1098
|
+
}
|
|
1099
|
+
async init() {
|
|
1100
|
+
if (!this.ready) {
|
|
1101
|
+
this.ready = this.bootstrap();
|
|
1102
|
+
}
|
|
1103
|
+
await this.ready;
|
|
1104
|
+
}
|
|
1105
|
+
async bootstrap() {
|
|
1106
|
+
await redis_client_default.connect();
|
|
1107
|
+
const { default: initZookeeper } = await Promise.resolve().then(() => (init_zookeeper(), zookeeper_exports));
|
|
1108
|
+
await initZookeeper();
|
|
1109
|
+
}
|
|
1110
|
+
get sso() {
|
|
1111
|
+
return this.ssoController;
|
|
1112
|
+
}
|
|
1113
|
+
get cache() {
|
|
1114
|
+
return this.cacheController;
|
|
1115
|
+
}
|
|
1116
|
+
};
|
|
1117
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1118
|
+
0 && (module.exports = {
|
|
1119
|
+
ServiceCallLibrary,
|
|
1120
|
+
TYPES
|
|
1121
|
+
});
|
|
1122
|
+
//# sourceMappingURL=index.cjs.map
|