@orion-js/echoes 4.0.0-next.2 → 4.0.0-next.3
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/LICENSE +21 -0
- package/dist/index.cjs +70 -79
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +70 -81
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Orionjs Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.cjs
CHANGED
|
@@ -4,7 +4,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __getProtoOf = Object.getPrototypeOf;
|
|
6
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
8
7
|
var __export = (target, all) => {
|
|
9
8
|
for (var name in all)
|
|
10
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -63,19 +62,15 @@ function getEcho_default(method) {
|
|
|
63
62
|
}
|
|
64
63
|
return echo2;
|
|
65
64
|
}
|
|
66
|
-
__name(getEcho_default, "default");
|
|
67
65
|
|
|
68
66
|
// src/publish/serialize.ts
|
|
69
67
|
var import_serialize_javascript = __toESM(require("serialize-javascript"), 1);
|
|
70
68
|
var import_cloneDeep = __toESM(require("lodash/cloneDeep"), 1);
|
|
71
69
|
function serialize_default(data) {
|
|
72
70
|
const cloned = (0, import_cloneDeep.default)(data);
|
|
73
|
-
const serialized = (0, import_serialize_javascript.default)(cloned, {
|
|
74
|
-
ignoreFunction: true
|
|
75
|
-
});
|
|
71
|
+
const serialized = (0, import_serialize_javascript.default)(cloned, { ignoreFunction: true });
|
|
76
72
|
return serialized;
|
|
77
73
|
}
|
|
78
|
-
__name(serialize_default, "default");
|
|
79
74
|
|
|
80
75
|
// src/request/getSignature.ts
|
|
81
76
|
var import_jssha = __toESM(require("jssha"), 1);
|
|
@@ -83,14 +78,15 @@ var import_jssha = __toESM(require("jssha"), 1);
|
|
|
83
78
|
// src/request/getPassword.ts
|
|
84
79
|
var import_env = require("@orion-js/env");
|
|
85
80
|
function getEchoesPassword() {
|
|
86
|
-
var
|
|
87
|
-
const secret = ((_b = (
|
|
81
|
+
var _a, _b;
|
|
82
|
+
const secret = ((_b = (_a = config_default) == null ? void 0 : _a.requests) == null ? void 0 : _b.key) || (0, import_env.internalGetEnv)("echoes_password", "ECHOES_PASSWORD");
|
|
88
83
|
if (!secret) {
|
|
89
|
-
console.warn(
|
|
84
|
+
console.warn(
|
|
85
|
+
'Warning: no secret key found for echoes requests. Init echoes or set the env var "echoes_password" or process.env.ECHOES_PASSWORD'
|
|
86
|
+
);
|
|
90
87
|
}
|
|
91
88
|
return secret;
|
|
92
89
|
}
|
|
93
|
-
__name(getEchoesPassword, "getEchoesPassword");
|
|
94
90
|
|
|
95
91
|
// src/request/getSignature.ts
|
|
96
92
|
function getSignature_default(body) {
|
|
@@ -100,7 +96,6 @@ function getSignature_default(body) {
|
|
|
100
96
|
shaObj.update(body);
|
|
101
97
|
return shaObj.getHMAC("HEX");
|
|
102
98
|
}
|
|
103
|
-
__name(getSignature_default, "default");
|
|
104
99
|
|
|
105
100
|
// src/requestsHandler/checkSignature.ts
|
|
106
101
|
function checkSignature_default(body, signature) {
|
|
@@ -109,11 +104,10 @@ function checkSignature_default(body, signature) {
|
|
|
109
104
|
throw new Error("Echoes invalid signature");
|
|
110
105
|
}
|
|
111
106
|
}
|
|
112
|
-
__name(checkSignature_default, "default");
|
|
113
107
|
|
|
114
108
|
// src/requestsHandler/index.ts
|
|
115
109
|
var import_http = require("@orion-js/http");
|
|
116
|
-
var requestsHandler_default =
|
|
110
|
+
var requestsHandler_default = (options) => (0, import_http.route)({
|
|
117
111
|
method: "post",
|
|
118
112
|
path: options.requests.handlerPath || "/echoes-services",
|
|
119
113
|
bodyParser: "json",
|
|
@@ -146,7 +140,7 @@ var requestsHandler_default = /* @__PURE__ */ __name((options) => (0, import_htt
|
|
|
146
140
|
};
|
|
147
141
|
}
|
|
148
142
|
}
|
|
149
|
-
})
|
|
143
|
+
});
|
|
150
144
|
|
|
151
145
|
// src/startService/KafkaManager.ts
|
|
152
146
|
var import_kafkajs = require("kafkajs");
|
|
@@ -154,8 +148,7 @@ var HEARTBEAT_INTERVAL_SECONDS = 5;
|
|
|
154
148
|
var CHECK_JOIN_CONSUMER_INTERVAL_SECONDS = 30;
|
|
155
149
|
var DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY = 4;
|
|
156
150
|
var DEFAULT_MEMBERS_TO_PARTITIONS_RATIO = 1;
|
|
157
|
-
var
|
|
158
|
-
var KafkaManager = (_a = class {
|
|
151
|
+
var KafkaManager = class {
|
|
159
152
|
kafka;
|
|
160
153
|
options;
|
|
161
154
|
producer;
|
|
@@ -168,29 +161,34 @@ var KafkaManager = (_a = class {
|
|
|
168
161
|
this.options = options;
|
|
169
162
|
this.producer = this.kafka.producer(options.producer);
|
|
170
163
|
this.consumer = this.kafka.consumer(options.consumer);
|
|
171
|
-
this.topics = Object.keys(options.echoes).filter(
|
|
164
|
+
this.topics = Object.keys(options.echoes).filter(
|
|
165
|
+
(key) => options.echoes[key].type === types_default.event
|
|
166
|
+
);
|
|
172
167
|
}
|
|
173
168
|
async checkJoinConsumerGroupConditions() {
|
|
174
169
|
const admin = this.kafka.admin();
|
|
175
170
|
try {
|
|
176
171
|
await admin.connect();
|
|
177
|
-
const groupDescriptions = await admin.describeGroups([
|
|
178
|
-
this.options.consumer.groupId
|
|
179
|
-
]);
|
|
172
|
+
const groupDescriptions = await admin.describeGroups([this.options.consumer.groupId]);
|
|
180
173
|
const group = groupDescriptions.groups[0];
|
|
181
174
|
if (group.state === "Empty") {
|
|
182
175
|
console.info(`Echoes: Consumer group ${this.options.consumer.groupId} is empty, joining`);
|
|
183
176
|
return true;
|
|
184
177
|
}
|
|
185
|
-
const topicsMetadata = await admin.fetchTopicMetadata({
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
178
|
+
const topicsMetadata = await admin.fetchTopicMetadata({ topics: this.topics });
|
|
179
|
+
const totalPartitions = topicsMetadata.topics.reduce(
|
|
180
|
+
(acc, topic) => acc + topic.partitions.length,
|
|
181
|
+
0
|
|
182
|
+
);
|
|
183
|
+
console.info(
|
|
184
|
+
`Echoes: Consumer group ${this.options.consumer.groupId} has ${group.members.length} members and ${totalPartitions} partitions`
|
|
185
|
+
);
|
|
190
186
|
const partitionsRatio = this.options.membersToPartitionsRatio || DEFAULT_MEMBERS_TO_PARTITIONS_RATIO;
|
|
191
187
|
const partitionsThreshold = Math.ceil(totalPartitions * partitionsRatio);
|
|
192
188
|
if (partitionsThreshold > group.members.length) {
|
|
193
|
-
console.info(
|
|
189
|
+
console.info(
|
|
190
|
+
`Echoes: Consumer group ${this.options.consumer.groupId} has room for more members ${group.members.length}/${partitionsThreshold}, joining`
|
|
191
|
+
);
|
|
194
192
|
return true;
|
|
195
193
|
}
|
|
196
194
|
} catch (error) {
|
|
@@ -204,12 +202,10 @@ var KafkaManager = (_a = class {
|
|
|
204
202
|
}
|
|
205
203
|
async joinConsumerGroup() {
|
|
206
204
|
await this.consumer.connect();
|
|
207
|
-
await this.consumer.subscribe({
|
|
208
|
-
topics: this.topics
|
|
209
|
-
});
|
|
205
|
+
await this.consumer.subscribe({ topics: this.topics });
|
|
210
206
|
await this.consumer.run({
|
|
211
207
|
partitionsConsumedConcurrently: this.options.partitionsConsumedConcurrently || DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY,
|
|
212
|
-
eachMessage:
|
|
208
|
+
eachMessage: (params) => this.handleMessage(params)
|
|
213
209
|
});
|
|
214
210
|
}
|
|
215
211
|
async conditionalStart() {
|
|
@@ -248,7 +244,9 @@ var KafkaManager = (_a = class {
|
|
|
248
244
|
});
|
|
249
245
|
intervalsCount++;
|
|
250
246
|
if (intervalsCount * HEARTBEAT_INTERVAL_SECONDS % 30 === 0) {
|
|
251
|
-
console.warn(
|
|
247
|
+
console.warn(
|
|
248
|
+
`Echoes: Event is taking too long to process: ${params.topic} ${intervalsCount * HEARTBEAT_INTERVAL_SECONDS}s`
|
|
249
|
+
);
|
|
252
250
|
}
|
|
253
251
|
}, HEARTBEAT_INTERVAL_SECONDS * 1e3);
|
|
254
252
|
try {
|
|
@@ -261,9 +259,9 @@ var KafkaManager = (_a = class {
|
|
|
261
259
|
}
|
|
262
260
|
}
|
|
263
261
|
async handleRetries(echo2, params, error) {
|
|
264
|
-
var
|
|
262
|
+
var _a, _b;
|
|
265
263
|
const { message, topic } = params;
|
|
266
|
-
const retries = Number.parseInt(((_b = (
|
|
264
|
+
const retries = Number.parseInt(((_b = (_a = message == null ? void 0 : message.headers) == null ? void 0 : _a.retries) == null ? void 0 : _b.toString()) || "0", 10);
|
|
267
265
|
if (echo2.attemptsBeforeDeadLetter === void 0 || echo2.attemptsBeforeDeadLetter === null) {
|
|
268
266
|
throw error;
|
|
269
267
|
}
|
|
@@ -283,12 +281,16 @@ var KafkaManager = (_a = class {
|
|
|
283
281
|
]
|
|
284
282
|
});
|
|
285
283
|
if (exceededMaxRetries) {
|
|
286
|
-
console.error(
|
|
284
|
+
console.error(
|
|
285
|
+
`Echoes: a message has reached the maximum number of retries, sending it to DLQ: ${nextTopic}`
|
|
286
|
+
);
|
|
287
287
|
} else {
|
|
288
|
-
console.warn(
|
|
288
|
+
console.warn(
|
|
289
|
+
`Echoes: a retryable message failed "${error.message}", re-sending it to topic: ${nextTopic}`
|
|
290
|
+
);
|
|
289
291
|
}
|
|
290
292
|
}
|
|
291
|
-
}
|
|
293
|
+
};
|
|
292
294
|
var KafkaManager_default = KafkaManager;
|
|
293
295
|
|
|
294
296
|
// src/startService/index.ts
|
|
@@ -307,7 +309,6 @@ async function startService(options) {
|
|
|
307
309
|
config_default.consumer = kafkaManager.consumer;
|
|
308
310
|
}
|
|
309
311
|
}
|
|
310
|
-
__name(startService, "startService");
|
|
311
312
|
async function stopService() {
|
|
312
313
|
if (kafkaManager) {
|
|
313
314
|
console.info("Stoping echoes...");
|
|
@@ -315,7 +316,6 @@ async function stopService() {
|
|
|
315
316
|
console.info("Echoes stopped");
|
|
316
317
|
}
|
|
317
318
|
}
|
|
318
|
-
__name(stopService, "stopService");
|
|
319
319
|
|
|
320
320
|
// src/publish/index.ts
|
|
321
321
|
async function publish(options) {
|
|
@@ -336,7 +336,6 @@ async function publish(options) {
|
|
|
336
336
|
]
|
|
337
337
|
});
|
|
338
338
|
}
|
|
339
|
-
__name(publish, "publish");
|
|
340
339
|
|
|
341
340
|
// src/echo/deserialize.ts
|
|
342
341
|
function deserialize_default(serializedJavascript) {
|
|
@@ -346,13 +345,12 @@ function deserialize_default(serializedJavascript) {
|
|
|
346
345
|
throw new Error("Error deserializing echo message");
|
|
347
346
|
}
|
|
348
347
|
}
|
|
349
|
-
__name(deserialize_default, "default");
|
|
350
348
|
|
|
351
349
|
// src/echo/index.ts
|
|
352
|
-
var echo =
|
|
350
|
+
var echo = function createNewEcho(options) {
|
|
353
351
|
return {
|
|
354
352
|
...options,
|
|
355
|
-
onMessage:
|
|
353
|
+
onMessage: async (messageData) => {
|
|
356
354
|
const { message } = messageData;
|
|
357
355
|
const data = deserialize_default(message.value.toString());
|
|
358
356
|
const context = {
|
|
@@ -360,68 +358,66 @@ var echo = /* @__PURE__ */ __name(function createNewEcho(options) {
|
|
|
360
358
|
data
|
|
361
359
|
};
|
|
362
360
|
await options.resolve(data.params || {}, context);
|
|
363
|
-
},
|
|
364
|
-
onRequest:
|
|
361
|
+
},
|
|
362
|
+
onRequest: async (serializedParams) => {
|
|
365
363
|
const context = {};
|
|
366
364
|
const params = deserialize_default(serializedParams);
|
|
367
365
|
const result = await options.resolve(params || {}, context);
|
|
368
366
|
return result;
|
|
369
|
-
}
|
|
367
|
+
}
|
|
370
368
|
};
|
|
371
|
-
}
|
|
369
|
+
};
|
|
372
370
|
echo.types = types_default;
|
|
373
371
|
var echo_default = echo;
|
|
374
372
|
|
|
375
373
|
// src/request/getURL.ts
|
|
376
374
|
function getURL_default(serviceName) {
|
|
377
|
-
var
|
|
375
|
+
var _a, _b;
|
|
378
376
|
if (serviceName.startsWith("http")) return serviceName;
|
|
379
|
-
const url = (_b = (
|
|
377
|
+
const url = (_b = (_a = config_default) == null ? void 0 : _a.requests) == null ? void 0 : _b.services[serviceName];
|
|
380
378
|
if (!url) {
|
|
381
379
|
throw new Error(`No URL found in echoes config for service ${serviceName}`);
|
|
382
380
|
}
|
|
383
381
|
return url;
|
|
384
382
|
}
|
|
385
|
-
__name(getURL_default, "default");
|
|
386
383
|
|
|
387
384
|
// src/request/makeRequest.ts
|
|
388
385
|
var import_axios = __toESM(require("axios"), 1);
|
|
389
386
|
var import_helpers = require("@orion-js/helpers");
|
|
390
|
-
var makeRequest =
|
|
391
|
-
const result = await (0, import_helpers.executeWithRetries)(
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
387
|
+
var makeRequest = async (options) => {
|
|
388
|
+
const result = await (0, import_helpers.executeWithRetries)(
|
|
389
|
+
async () => {
|
|
390
|
+
return await (0, import_axios.default)({
|
|
391
|
+
method: "post",
|
|
392
|
+
url: options.url,
|
|
393
|
+
timeout: options.timeout,
|
|
394
|
+
headers: {
|
|
395
|
+
"User-Agent": "Orionjs-Echoes/1.1"
|
|
396
|
+
},
|
|
397
|
+
data: options.data
|
|
398
|
+
});
|
|
399
|
+
},
|
|
400
|
+
options.retries,
|
|
401
|
+
200
|
|
402
|
+
);
|
|
402
403
|
return {
|
|
403
404
|
data: result.data,
|
|
404
405
|
statusCode: result.status
|
|
405
406
|
};
|
|
406
|
-
}
|
|
407
|
+
};
|
|
407
408
|
|
|
408
409
|
// src/request/index.ts
|
|
409
410
|
var import_schema = require("@orion-js/schema");
|
|
410
411
|
var import_helpers2 = require("@orion-js/helpers");
|
|
411
412
|
async function request(options) {
|
|
412
|
-
var
|
|
413
|
+
var _a, _b;
|
|
413
414
|
const { method, service, params } = options;
|
|
414
415
|
const serializedParams = serialize_default(params);
|
|
415
416
|
const date = /* @__PURE__ */ new Date();
|
|
416
|
-
const body = {
|
|
417
|
-
method,
|
|
418
|
-
service,
|
|
419
|
-
serializedParams,
|
|
420
|
-
date
|
|
421
|
-
};
|
|
417
|
+
const body = { method, service, serializedParams, date };
|
|
422
418
|
const signature = getSignature_default(body);
|
|
423
419
|
try {
|
|
424
|
-
const requestMaker = ((_b = (
|
|
420
|
+
const requestMaker = ((_b = (_a = config_default) == null ? void 0 : _a.requests) == null ? void 0 : _b.makeRequest) || makeRequest;
|
|
425
421
|
const requestOptions = {
|
|
426
422
|
url: getURL_default(service),
|
|
427
423
|
retries: options.retries,
|
|
@@ -455,7 +451,6 @@ async function request(options) {
|
|
|
455
451
|
throw new Error(`Echoes request network error calling ${service}/${method}: ${error.message}`);
|
|
456
452
|
}
|
|
457
453
|
}
|
|
458
|
-
__name(request, "request");
|
|
459
454
|
|
|
460
455
|
// src/service/index.ts
|
|
461
456
|
var import_services = require("@orion-js/services");
|
|
@@ -465,7 +460,6 @@ function Echoes() {
|
|
|
465
460
|
target.prototype.service = target;
|
|
466
461
|
};
|
|
467
462
|
}
|
|
468
|
-
__name(Echoes, "Echoes");
|
|
469
463
|
function EchoRequest(options = {}) {
|
|
470
464
|
return function(target, propertyKey, descriptor) {
|
|
471
465
|
if (!descriptor.value) throw new Error(`You must pass resolver function to ${propertyKey}`);
|
|
@@ -473,14 +467,13 @@ function EchoRequest(options = {}) {
|
|
|
473
467
|
target.echoes[propertyKey] = echo_default({
|
|
474
468
|
...options,
|
|
475
469
|
type: "request",
|
|
476
|
-
resolve:
|
|
470
|
+
resolve: async (params, viewer) => {
|
|
477
471
|
const instance = (0, import_services.getInstance)(target.service);
|
|
478
472
|
return await instance[propertyKey](params, viewer);
|
|
479
|
-
}
|
|
473
|
+
}
|
|
480
474
|
});
|
|
481
475
|
};
|
|
482
476
|
}
|
|
483
|
-
__name(EchoRequest, "EchoRequest");
|
|
484
477
|
function EchoEvent(options = {}) {
|
|
485
478
|
return function(target, propertyKey, descriptor) {
|
|
486
479
|
if (!descriptor.value) throw new Error(`You must pass resolver function to ${propertyKey}`);
|
|
@@ -488,21 +481,19 @@ function EchoEvent(options = {}) {
|
|
|
488
481
|
target.echoes[propertyKey] = echo_default({
|
|
489
482
|
...options,
|
|
490
483
|
type: "event",
|
|
491
|
-
resolve:
|
|
484
|
+
resolve: async (params, viewer) => {
|
|
492
485
|
const instance = (0, import_services.getInstance)(target.service);
|
|
493
486
|
return await instance[propertyKey](params, viewer);
|
|
494
|
-
}
|
|
487
|
+
}
|
|
495
488
|
});
|
|
496
489
|
};
|
|
497
490
|
}
|
|
498
|
-
__name(EchoEvent, "EchoEvent");
|
|
499
491
|
function getServiceEchoes(target) {
|
|
500
492
|
if (!target.prototype) {
|
|
501
493
|
throw new Error("You must pass a class to getServiceRoutes");
|
|
502
494
|
}
|
|
503
495
|
return target.prototype.echoes || {};
|
|
504
496
|
}
|
|
505
|
-
__name(getServiceEchoes, "getServiceEchoes");
|
|
506
497
|
// Annotate the CommonJS export names for ESM import in node:
|
|
507
498
|
0 && (module.exports = {
|
|
508
499
|
EchoEvent,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/echo/types.ts","../src/requestsHandler/getEcho.ts","../src/publish/serialize.ts","../src/request/getSignature.ts","../src/request/getPassword.ts","../src/requestsHandler/checkSignature.ts","../src/requestsHandler/index.ts","../src/startService/KafkaManager.ts","../src/startService/index.ts","../src/publish/index.ts","../src/echo/deserialize.ts","../src/echo/index.ts","../src/request/getURL.ts","../src/request/makeRequest.ts","../src/request/index.ts","../src/service/index.ts"],"sourcesContent":["import startService, {stopService} from './startService'\nimport publish from './publish'\nimport echo from './echo'\nimport request from './request'\n\nexport * from './types'\nexport * from './service'\n\nexport {publish, startService, stopService, echo, request}\n","import {EchoesConfigHandler} from './types'\n\nconst config: EchoesConfigHandler = {}\n\nexport default config\n","export default {\n event: 'event',\n request: 'request'\n}\n","import config from '../config'\nimport types from '../echo/types'\n\nexport default function (method: string) {\n const echo = config.echoes[method]\n\n if (!echo) {\n throw new Error(`Echo named ${method} not found in this service`)\n }\n\n if (echo.type !== types.request) {\n throw new Error(`Echo named ${method} is not of type request`)\n }\n\n return echo\n}\n","import serialize from 'serialize-javascript'\nimport cloneDeep from 'lodash/cloneDeep'\n\nexport default function (data: any): string {\n const cloned = cloneDeep(data)\n const serialized = serialize(cloned, {ignoreFunction: true})\n return serialized\n}\n","import JSSHA from 'jssha'\nimport {getEchoesPassword} from './getPassword'\n\nexport default function (body: any): string {\n const password = getEchoesPassword()\n const shaObj = new JSSHA('SHA-1', 'TEXT')\n shaObj.setHMACKey(password, 'TEXT')\n shaObj.update(body)\n return shaObj.getHMAC('HEX')\n}\n","import config from '../config'\nimport {internalGetEnv} from '@orion-js/env'\n\nexport function getEchoesPassword() {\n const secret = config?.requests?.key || internalGetEnv('echoes_password', 'ECHOES_PASSWORD')\n if (!secret) {\n console.warn(\n 'Warning: no secret key found for echoes requests. Init echoes or set the env var \"echoes_password\" or process.env.ECHOES_PASSWORD'\n )\n }\n\n return secret\n}\n","import getSignature from '../request/getSignature'\n\nexport default function (body: any, signature: string) {\n const generatedSignature = getSignature(body)\n if (generatedSignature !== signature) {\n throw new Error('Echoes invalid signature')\n }\n}\n","import getEcho from './getEcho'\nimport serialize from '../publish/serialize'\nimport checkSignature from './checkSignature'\nimport {route} from '@orion-js/http'\nimport {EchoesOptions} from '../types'\n\nexport default (options: EchoesOptions) =>\n route({\n method: 'post',\n path: options.requests.handlerPath || '/echoes-services',\n bodyParser: 'json',\n bodyParserOptions: {\n limit: '10mb',\n },\n async resolve(req) {\n try {\n const {body, signature} = req.body\n\n checkSignature(body, signature)\n\n const {method, serializedParams} = body\n\n const echo = getEcho(method)\n const result = await echo.onRequest(serializedParams)\n\n return {\n body: {\n result: serialize(result),\n },\n }\n } catch (error) {\n if (!error.getInfo) {\n console.error('Error at echo requests handler:', error)\n }\n\n return {\n body: {\n error: error.message,\n errorInfo: error.getInfo ? error.getInfo() : null,\n isValidationError: !!error.isValidationError,\n isUserError: !!error.isUserError,\n },\n }\n }\n },\n })\n","import {Kafka, EachMessagePayload, Producer, Consumer} from 'kafkajs'\nimport types from '../echo/types'\nimport {EchoesOptions, EchoType} from '../types'\n\nconst HEARTBEAT_INTERVAL_SECONDS = 5 // This value must be less than the kafkajs session timeout\nconst CHECK_JOIN_CONSUMER_INTERVAL_SECONDS = 30\nconst DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY = 4 // How many partitions to consume concurrently, adjust this with the members to partitions ratio to avoid idle consumers.\nconst DEFAULT_MEMBERS_TO_PARTITIONS_RATIO = 1 // How many members are in comparison to partitions, this is used to determine if the consumer group has room for more members. Numbers over 1 leads to idle consumers. Numbers under 1 needs partitionsConsumedConcurrently to be more than 1.\n\n/**\n * Manages the Kafka connection and the consumers.\n */\nclass KafkaManager {\n kafka: Kafka\n options: EchoesOptions\n producer: Producer\n consumer: Consumer\n topics: string[]\n started: boolean\n interval: NodeJS.Timer\n\n constructor(options: EchoesOptions) {\n this.kafka = new Kafka(options.client)\n this.options = options\n this.producer = this.kafka.producer(options.producer)\n this.consumer = this.kafka.consumer(options.consumer)\n this.topics = Object.keys(options.echoes).filter(\n key => options.echoes[key].type === types.event,\n )\n }\n\n async checkJoinConsumerGroupConditions(): Promise<boolean> {\n const admin = this.kafka.admin()\n try {\n await admin.connect()\n const groupDescriptions = await admin.describeGroups([this.options.consumer.groupId])\n const group = groupDescriptions.groups[0]\n if (group.state === 'Empty') {\n console.info(`Echoes: Consumer group ${this.options.consumer.groupId} is empty, joining`)\n return true\n }\n const topicsMetadata = await admin.fetchTopicMetadata({topics: this.topics})\n const totalPartitions = topicsMetadata.topics.reduce(\n (acc, topic) => acc + topic.partitions.length,\n 0,\n )\n console.info(\n `Echoes: Consumer group ${this.options.consumer.groupId} has ${group.members.length} members and ${totalPartitions} partitions`,\n )\n const partitionsRatio =\n this.options.membersToPartitionsRatio || DEFAULT_MEMBERS_TO_PARTITIONS_RATIO\n const partitionsThreshold = Math.ceil(totalPartitions * partitionsRatio)\n if (partitionsThreshold > group.members.length) {\n console.info(\n `Echoes: Consumer group ${this.options.consumer.groupId} has room for more members ${group.members.length}/${partitionsThreshold}, joining`,\n )\n return true\n }\n } catch (error) {\n console.error(`Echoes: Error checking consumer group conditions, join: ${error.message}`)\n return true\n } finally {\n await admin.disconnect().catch(error => {\n console.error(`Echoes: Error disconnecting admin client: ${error.message}`)\n })\n }\n }\n\n async joinConsumerGroup() {\n await this.consumer.connect()\n await this.consumer.subscribe({topics: this.topics})\n await this.consumer.run({\n partitionsConsumedConcurrently:\n this.options.partitionsConsumedConcurrently || DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY,\n eachMessage: params => this.handleMessage(params),\n })\n }\n\n async conditionalStart(): Promise<boolean> {\n if (await this.checkJoinConsumerGroupConditions()) {\n await this.joinConsumerGroup()\n return true\n }\n }\n\n async start() {\n if (this.started) return\n await this.producer.connect()\n this.started = await this.conditionalStart()\n if (this.started) return\n console.info('Echoes: Delaying consumer group join, waiting for conditions to be met')\n this.interval = setInterval(async () => {\n this.started = await this.conditionalStart()\n if (this.started) clearInterval(this.interval)\n }, CHECK_JOIN_CONSUMER_INTERVAL_SECONDS * 1000)\n }\n\n async stop() {\n console.warn('Echoes: Stopping echoes')\n if (this.interval) clearInterval(this.interval)\n if (this.consumer) await this.consumer.disconnect()\n if (this.producer) await this.producer.disconnect()\n }\n\n async handleMessage(params: EachMessagePayload) {\n const echo = this.options.echoes[params.topic]\n if (!echo || echo.type !== types.event) {\n console.warn(`Echoes: Received a message for an unknown topic: ${params.topic}, ignoring it`)\n return\n }\n\n let intervalsCount = 0\n const heartbeatInterval = setInterval(async () => {\n await params.heartbeat().catch(error => {\n console.warn(`Echoes: Error sending heartbeat: ${error.message}`)\n })\n intervalsCount++\n if ((intervalsCount * HEARTBEAT_INTERVAL_SECONDS) % 30 === 0) {\n console.warn(\n `Echoes: Event is taking too long to process: ${params.topic} ${intervalsCount * HEARTBEAT_INTERVAL_SECONDS}s`,\n )\n }\n }, HEARTBEAT_INTERVAL_SECONDS * 1000)\n\n try {\n await echo.onMessage(params).catch(error => this.handleRetries(echo, params, error))\n } catch (error) {\n console.error(`Echoes: error processing a message: ${params.topic} ${error.message}`)\n throw error\n } finally {\n clearInterval(heartbeatInterval)\n }\n }\n\n async handleRetries(echo: EchoType, params: EachMessagePayload, error: Error) {\n const {message, topic} = params\n const retries = Number.parseInt(message?.headers?.retries?.toString() || '0', 10)\n if (echo.attemptsBeforeDeadLetter === undefined || echo.attemptsBeforeDeadLetter === null) {\n throw error\n }\n const maxRetries = echo.attemptsBeforeDeadLetter || 0\n const exceededMaxRetries = retries >= maxRetries\n const nextTopic = exceededMaxRetries ? `DLQ-${topic}` : topic\n await this.producer.send({\n topic: nextTopic,\n messages: [\n {\n value: message.value.toString(),\n headers: {\n retries: String(retries + 1),\n error: error.message,\n },\n },\n ],\n })\n\n if (exceededMaxRetries) {\n console.error(\n `Echoes: a message has reached the maximum number of retries, sending it to DLQ: ${nextTopic}`,\n )\n } else {\n console.warn(\n `Echoes: a retryable message failed \"${error.message}\", re-sending it to topic: ${nextTopic}`,\n )\n }\n }\n}\n\nexport default KafkaManager\n","import config from '../config'\nimport requestsHandler from '../requestsHandler'\nimport {EchoesOptions} from '../types'\nimport KafkaManager from './KafkaManager'\nimport {registerRoute} from '@orion-js/http'\n\nlet kafkaManager: KafkaManager = null\n\nexport default async function startService(options: EchoesOptions) {\n config.echoes = options.echoes\n\n if (options.requests) {\n config.requests = options.requests\n registerRoute(requestsHandler(options))\n }\n\n if (options.client) {\n kafkaManager = new KafkaManager(options)\n await kafkaManager.start()\n config.producer = kafkaManager.producer\n config.consumer = kafkaManager.consumer\n }\n}\n\nexport async function stopService() {\n if (kafkaManager) {\n console.info('Stoping echoes...')\n await kafkaManager.stop()\n console.info('Echoes stopped')\n }\n}\n","import config from '../config'\nimport {PublishOptions} from '../types'\nimport serialize from './serialize'\n\n/**\n * Publish\n */\nexport default async function publish<TParams = any>(options: PublishOptions<TParams>) {\n if (!config.producer) {\n throw new Error('You must initialize echoes configruation to use publish')\n }\n\n const payload = {\n params: options.params,\n }\n\n return await config.producer.send({\n acks: options.acks,\n timeout: options.timeout,\n topic: options.topic,\n messages: [\n {\n value: serialize(payload),\n },\n ],\n })\n}\n","export default function (serializedJavascript: string): any {\n try {\n return eval('(' + serializedJavascript + ')')\n } catch (error) {\n throw new Error('Error deserializing echo message')\n }\n}\n","import {EachMessagePayload} from 'kafkajs'\nimport {EchoType, EchoConfig} from '../types'\nimport deserialize from './deserialize'\nimport types from './types'\n\nconst echo = function createNewEcho(options: EchoConfig): EchoType {\n return {\n ...options,\n onMessage: async (messageData: EachMessagePayload) => {\n const {message} = messageData\n\n const data = deserialize(message.value.toString())\n\n const context = {\n ...messageData,\n data\n }\n\n await options.resolve(data.params || {}, context)\n },\n onRequest: async (serializedParams: string) => {\n const context = {}\n const params = deserialize(serializedParams)\n const result = await options.resolve(params || {}, context)\n return result\n }\n }\n}\n\necho.types = types\n\nexport default echo\n","import config from '../config'\n\nexport default function (serviceName: string): string {\n if (serviceName.startsWith('http')) return serviceName\n\n const url = config?.requests?.services[serviceName]\n\n if (!url) {\n throw new Error(`No URL found in echoes config for service ${serviceName}`)\n }\n\n return url\n}\n","import axios from 'axios'\nimport {RequestMaker} from '../types'\nimport {executeWithRetries} from '@orion-js/helpers'\n\nexport const makeRequest: RequestMaker = async options => {\n const result = await executeWithRetries(\n async () => {\n return await axios({\n method: 'post',\n url: options.url,\n timeout: options.timeout,\n headers: {\n 'User-Agent': 'Orionjs-Echoes/1.1'\n },\n data: options.data\n })\n },\n options.retries,\n 200\n )\n\n return {\n data: result.data as object,\n statusCode: result.status\n }\n}\n","import getURL from './getURL'\nimport getSignature from './getSignature'\nimport serialize from '../publish/serialize'\nimport deserialize from '../echo/deserialize'\nimport type {\n MakeRequestParams,\n RequestHandlerResponse,\n RequestMaker,\n RequestOptions,\n} from '../types'\nimport config from '../config'\nimport {makeRequest} from './makeRequest'\nimport {ValidationError} from '@orion-js/schema'\nimport {UserError} from '@orion-js/helpers'\n\nexport default async function request<TData = any, TParams = any>(\n options: RequestOptions<TParams>,\n): Promise<TData> {\n const {method, service, params} = options\n const serializedParams = serialize(params)\n const date = new Date()\n const body = {method, service, serializedParams, date}\n const signature = getSignature(body)\n\n try {\n const requestMaker: RequestMaker = config?.requests?.makeRequest || makeRequest\n const requestOptions: MakeRequestParams = {\n url: getURL(service),\n retries: options.retries,\n timeout: options.timeout,\n data: {\n body,\n signature,\n },\n }\n const result = await requestMaker(requestOptions)\n\n if (result.statusCode !== 200) {\n throw new Error(`Wrong status code ${result.statusCode}`)\n }\n\n const data: RequestHandlerResponse = result.data\n\n if (data.error) {\n const info = data.errorInfo\n if (info) {\n if (data.isValidationError) {\n throw new ValidationError(info.validationErrors)\n }\n if (data.isUserError) {\n throw new UserError(info.error, info.message, info.extra)\n }\n }\n\n throw new Error(`${data.error}`)\n }\n\n const response = deserialize(data.result)\n return response\n } catch (error) {\n if (error.isOrionError) throw error\n\n throw new Error(`Echoes request network error calling ${service}/${method}: ${error.message}`)\n }\n}\n","import {getInstance, Service} from '@orion-js/services'\nimport echo from '../echo'\nimport {EchoConfig, EchoesMap} from '../types'\n\nexport function Echoes(): ClassDecorator {\n return function (target: any) {\n Service()(target)\n target.prototype.service = target\n }\n}\n\nexport interface EchoesPropertyDescriptor extends Omit<PropertyDecorator, 'value'> {\n value?: EchoConfig['resolve']\n}\n\nexport function EchoRequest(options: Omit<EchoConfig, 'resolve' | 'type'> = {}) {\n return function (target: any, propertyKey: string, descriptor: EchoesPropertyDescriptor) {\n if (!descriptor.value) throw new Error(`You must pass resolver function to ${propertyKey}`)\n\n target.echoes = target.echoes || {}\n target.echoes[propertyKey] = echo({\n ...options,\n type: 'request',\n resolve: async (params, viewer) => {\n const instance: any = getInstance(target.service)\n return await instance[propertyKey](params, viewer)\n }\n })\n }\n}\n\nexport function EchoEvent(options: Omit<EchoConfig, 'resolve' | 'type'> = {}) {\n return function (target: any, propertyKey: string, descriptor: EchoesPropertyDescriptor) {\n if (!descriptor.value) throw new Error(`You must pass resolver function to ${propertyKey}`)\n\n target.echoes = target.echoes || {}\n target.echoes[propertyKey] = echo({\n ...options,\n type: 'event',\n resolve: async (params, viewer) => {\n const instance: any = getInstance(target.service)\n return await instance[propertyKey](params, viewer)\n }\n })\n }\n}\n\nexport function getServiceEchoes(target: any): EchoesMap {\n if (!target.prototype) {\n throw new Error('You must pass a class to getServiceRoutes')\n }\n\n return target.prototype.echoes || {}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;ACEA,IAAMA,SAA8B,CAAC;AAErC,IAAA,iBAAeA;;;ACJf,IAAA,gBAAe;EACbC,OAAO;EACPC,SAAS;AACX;;;ACAe,SAAf,gBAAyBC,QAAc;AACrC,QAAMC,QAAOC,eAAOC,OAAOH,MAAAA;AAE3B,MAAI,CAACC,OAAM;AACT,UAAM,IAAIG,MAAM,cAAcJ,MAAAA,4BAAkC;EAClE;AAEA,MAAIC,MAAKI,SAASC,cAAMC,SAAS;AAC/B,UAAM,IAAIH,MAAM,cAAcJ,MAAAA,yBAA+B;EAC/D;AAEA,SAAOC;AACT;AAZA;;;ACHA,kCAAsB;AACtB,uBAAsB;AAEP,SAAf,kBAAyBO,MAAS;AAChC,QAAMC,aAASC,iBAAAA,SAAUF,IAAAA;AACzB,QAAMG,iBAAaC,4BAAAA,SAAUH,QAAQ;IAACI,gBAAgB;EAAI,CAAA;AAC1D,SAAOF;AACT;AAJA;;;ACHA,mBAAkB;;;ACClB,iBAA6B;AAEtB,SAASG,oBAAAA;AAHhB,MAAAC,KAAA;AAIE,QAAMC,WAASC,MAAAA,MAAAA,mCAAAA,IAAQC,aAARD,mBAAkBE,YAAOC,2BAAe,mBAAmB,iBAAA;AAC1E,MAAI,CAACJ,QAAQ;AACXK,YAAQC,KACN,mIAAA;EAEJ;AAEA,SAAON;AACT;AATgBF;;;ADAD,SAAf,qBAAyBS,MAAS;AAChC,QAAMC,WAAWC,kBAAAA;AACjB,QAAMC,SAAS,IAAIC,aAAAA,QAAM,SAAS,MAAA;AAClCD,SAAOE,WAAWJ,UAAU,MAAA;AAC5BE,SAAOG,OAAON,IAAAA;AACd,SAAOG,OAAOI,QAAQ,KAAA;AACxB;AANA;;;AEDe,SAAf,uBAAyBC,MAAWC,WAAiB;AACnD,QAAMC,qBAAqBC,qBAAaH,IAAAA;AACxC,MAAIE,uBAAuBD,WAAW;AACpC,UAAM,IAAIG,MAAM,0BAAA;EAClB;AACF;AALA;;;ACCA,kBAAoB;AAGpB,IAAA,0BAAe,wBAACC,gBACdC,mBAAM;EACJC,QAAQ;EACRC,MAAMH,QAAQI,SAASC,eAAe;EACtCC,YAAY;EACZC,mBAAmB;IACjBC,OAAO;EACT;EACA,MAAMC,QAAQC,KAAG;AACf,QAAI;AACF,YAAM,EAACC,MAAMC,UAAS,IAAIF,IAAIC;AAE9BE,6BAAeF,MAAMC,SAAAA;AAErB,YAAM,EAACV,QAAQY,iBAAgB,IAAIH;AAEnC,YAAMI,QAAOC,gBAAQd,MAAAA;AACrB,YAAMe,SAAS,MAAMF,MAAKG,UAAUJ,gBAAAA;AAEpC,aAAO;QACLH,MAAM;UACJM,QAAQE,kBAAUF,MAAAA;QACpB;MACF;IACF,SAASG,OAAO;AACd,UAAI,CAACA,MAAMC,SAAS;AAClBC,gBAAQF,MAAM,mCAAmCA,KAAAA;MACnD;AAEA,aAAO;QACLT,MAAM;UACJS,OAAOA,MAAMG;UACbC,WAAWJ,MAAMC,UAAUD,MAAMC,QAAO,IAAK;UAC7CI,mBAAmB,CAAC,CAACL,MAAMK;UAC3BC,aAAa,CAAC,CAACN,MAAMM;QACvB;MACF;IACF;EACF;AACF,CAAA,GAvCa;;;ACNf,qBAA4D;AAI5D,IAAMC,6BAA6B;AACnC,IAAMC,uCAAuC;AAC7C,IAAMC,2CAA2C;AACjD,IAAMC,sCAAsC;AAP5C;AAYA,IAAMC,gBAAN,WAAMA;EACJC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EAEAC,YAAYN,SAAwB;AAClC,SAAKD,QAAQ,IAAIQ,qBAAMP,QAAQQ,MAAM;AACrC,SAAKR,UAAUA;AACf,SAAKC,WAAW,KAAKF,MAAME,SAASD,QAAQC,QAAQ;AACpD,SAAKC,WAAW,KAAKH,MAAMG,SAASF,QAAQE,QAAQ;AACpD,SAAKC,SAASM,OAAOC,KAAKV,QAAQW,MAAM,EAAEC,OACxCC,CAAAA,QAAOb,QAAQW,OAAOE,GAAAA,EAAKC,SAASC,cAAMC,KAAK;EAEnD;EAEA,MAAMC,mCAAqD;AACzD,UAAMC,QAAQ,KAAKnB,MAAMmB,MAAK;AAC9B,QAAI;AACF,YAAMA,MAAMC,QAAO;AACnB,YAAMC,oBAAoB,MAAMF,MAAMG,eAAe;QAAC,KAAKrB,QAAQE,SAASoB;OAAQ;AACpF,YAAMC,QAAQH,kBAAkBI,OAAO,CAAA;AACvC,UAAID,MAAME,UAAU,SAAS;AAC3BC,gBAAQC,KAAK,0BAA0B,KAAK3B,QAAQE,SAASoB,OAAO,oBAAoB;AACxF,eAAO;MACT;AACA,YAAMM,iBAAiB,MAAMV,MAAMW,mBAAmB;QAAC1B,QAAQ,KAAKA;MAAM,CAAA;AAC1E,YAAM2B,kBAAkBF,eAAezB,OAAO4B,OAC5C,CAACC,KAAKC,UAAUD,MAAMC,MAAMC,WAAWC,QACvC,CAAA;AAEFT,cAAQC,KACN,0BAA0B,KAAK3B,QAAQE,SAASoB,OAAO,QAAQC,MAAMa,QAAQD,MAAM,gBAAgBL,eAAAA,aAA4B;AAEjI,YAAMO,kBACJ,KAAKrC,QAAQsC,4BAA4BzC;AAC3C,YAAM0C,sBAAsBC,KAAKC,KAAKX,kBAAkBO,eAAAA;AACxD,UAAIE,sBAAsBhB,MAAMa,QAAQD,QAAQ;AAC9CT,gBAAQC,KACN,0BAA0B,KAAK3B,QAAQE,SAASoB,OAAO,8BAA8BC,MAAMa,QAAQD,MAAM,IAAII,mBAAAA,WAA8B;AAE7I,eAAO;MACT;IACF,SAASG,OAAO;AACdhB,cAAQgB,MAAM,2DAA2DA,MAAMC,OAAO,EAAE;AACxF,aAAO;IACT,UAAA;AACE,YAAMzB,MAAM0B,WAAU,EAAGC,MAAMH,CAAAA,UAAAA;AAC7BhB,gBAAQgB,MAAM,6CAA6CA,MAAMC,OAAO,EAAE;MAC5E,CAAA;IACF;EACF;EAEA,MAAMG,oBAAoB;AACxB,UAAM,KAAK5C,SAASiB,QAAO;AAC3B,UAAM,KAAKjB,SAAS6C,UAAU;MAAC5C,QAAQ,KAAKA;IAAM,CAAA;AAClD,UAAM,KAAKD,SAAS8C,IAAI;MACtBC,gCACE,KAAKjD,QAAQiD,kCAAkCrD;MACjDsD,aAAaC,wBAAAA,WAAU,KAAKC,cAAcD,MAAAA,GAA7BA;IACf,CAAA;EACF;EAEA,MAAME,mBAAqC;AACzC,QAAI,MAAM,KAAKpC,iCAAgC,GAAI;AACjD,YAAM,KAAK6B,kBAAiB;AAC5B,aAAO;IACT;EACF;EAEA,MAAMQ,QAAQ;AACZ,QAAI,KAAKlD,QAAS;AAClB,UAAM,KAAKH,SAASkB,QAAO;AAC3B,SAAKf,UAAU,MAAM,KAAKiD,iBAAgB;AAC1C,QAAI,KAAKjD,QAAS;AAClBsB,YAAQC,KAAK,wEAAA;AACb,SAAKtB,WAAWkD,YAAY,YAAA;AAC1B,WAAKnD,UAAU,MAAM,KAAKiD,iBAAgB;AAC1C,UAAI,KAAKjD,QAASoD,eAAc,KAAKnD,QAAQ;IAC/C,GAAGV,uCAAuC,GAAA;EAC5C;EAEA,MAAM8D,OAAO;AACX/B,YAAQgC,KAAK,yBAAA;AACb,QAAI,KAAKrD,SAAUmD,eAAc,KAAKnD,QAAQ;AAC9C,QAAI,KAAKH,SAAU,OAAM,KAAKA,SAAS0C,WAAU;AACjD,QAAI,KAAK3C,SAAU,OAAM,KAAKA,SAAS2C,WAAU;EACnD;EAEA,MAAMQ,cAAcD,QAA4B;AAC9C,UAAMQ,QAAO,KAAK3D,QAAQW,OAAOwC,OAAOlB,KAAK;AAC7C,QAAI,CAAC0B,SAAQA,MAAK7C,SAASC,cAAMC,OAAO;AACtCU,cAAQgC,KAAK,oDAAoDP,OAAOlB,KAAK,eAAe;AAC5F;IACF;AAEA,QAAI2B,iBAAiB;AACrB,UAAMC,oBAAoBN,YAAY,YAAA;AACpC,YAAMJ,OAAOW,UAAS,EAAGjB,MAAMH,CAAAA,UAAAA;AAC7BhB,gBAAQgC,KAAK,oCAAoChB,MAAMC,OAAO,EAAE;MAClE,CAAA;AACAiB;AACA,UAAKA,iBAAiBlE,6BAA8B,OAAO,GAAG;AAC5DgC,gBAAQgC,KACN,gDAAgDP,OAAOlB,KAAK,IAAI2B,iBAAiBlE,0BAAAA,GAA6B;MAElH;IACF,GAAGA,6BAA6B,GAAA;AAEhC,QAAI;AACF,YAAMiE,MAAKI,UAAUZ,MAAAA,EAAQN,MAAMH,CAAAA,UAAS,KAAKsB,cAAcL,OAAMR,QAAQT,KAAAA,CAAAA;IAC/E,SAASA,OAAO;AACdhB,cAAQgB,MAAM,uCAAuCS,OAAOlB,KAAK,IAAIS,MAAMC,OAAO,EAAE;AACpF,YAAMD;IACR,UAAA;AACEc,oBAAcK,iBAAAA;IAChB;EACF;EAEA,MAAMG,cAAcL,OAAgBR,QAA4BT,OAAc;AAtIhF,QAAAuB,KAAA;AAuII,UAAM,EAACtB,SAASV,MAAK,IAAIkB;AACzB,UAAMe,UAAUC,OAAOC,WAASzB,MAAAA,MAAAA,mCAAS0B,YAAT1B,gBAAAA,IAAkBuB,YAAlBvB,mBAA2B2B,eAAc,KAAK,EAAA;AAC9E,QAAIX,MAAKY,6BAA6BC,UAAab,MAAKY,6BAA6B,MAAM;AACzF,YAAM7B;IACR;AACA,UAAM+B,aAAad,MAAKY,4BAA4B;AACpD,UAAMG,qBAAqBR,WAAWO;AACtC,UAAME,YAAYD,qBAAqB,OAAOzC,KAAAA,KAAUA;AACxD,UAAM,KAAKhC,SAAS2E,KAAK;MACvB3C,OAAO0C;MACPE,UAAU;QACR;UACEC,OAAOnC,QAAQmC,MAAMR,SAAQ;UAC7BD,SAAS;YACPH,SAASa,OAAOb,UAAU,CAAA;YAC1BxB,OAAOA,MAAMC;UACf;QACF;;IAEJ,CAAA;AAEA,QAAI+B,oBAAoB;AACtBhD,cAAQgB,MACN,mFAAmFiC,SAAAA,EAAW;IAElG,OAAO;AACLjD,cAAQgC,KACN,uCAAuChB,MAAMC,OAAO,8BAA8BgC,SAAAA,EAAW;IAEjG;EACF;AACF,GA1JM7E,4BAAN;AA4JA,IAAA,uBAAeA;;;ACpKf,IAAAkF,eAA4B;AAE5B,IAAIC,eAA6B;AAEjC,eAAA,aAA2CC,SAAsB;AAC/DC,iBAAOC,SAASF,QAAQE;AAExB,MAAIF,QAAQG,UAAU;AACpBF,mBAAOE,WAAWH,QAAQG;AAC1BC,oCAAcC,wBAAgBL,OAAAA,CAAAA;EAChC;AAEA,MAAIA,QAAQM,QAAQ;AAClBP,mBAAe,IAAIQ,qBAAaP,OAAAA;AAChC,UAAMD,aAAaS,MAAK;AACxBP,mBAAOQ,WAAWV,aAAaU;AAC/BR,mBAAOS,WAAWX,aAAaW;EACjC;AACF;AAd8BC;AAgB9B,eAAsBC,cAAAA;AACpB,MAAIb,cAAc;AAChBc,YAAQC,KAAK,mBAAA;AACb,UAAMf,aAAagB,KAAI;AACvBF,YAAQC,KAAK,gBAAA;EACf;AACF;AANsBF;;;ACjBtB,eAAA,QAAqDI,SAAgC;AACnF,MAAI,CAACC,eAAOC,UAAU;AACpB,UAAM,IAAIC,MAAM,yDAAA;EAClB;AAEA,QAAMC,UAAU;IACdC,QAAQL,QAAQK;EAClB;AAEA,SAAO,MAAMJ,eAAOC,SAASI,KAAK;IAChCC,MAAMP,QAAQO;IACdC,SAASR,QAAQQ;IACjBC,OAAOT,QAAQS;IACfC,UAAU;MACR;QACEC,OAAOC,kBAAUR,OAAAA;MACnB;;EAEJ,CAAA;AACF;AAnB8BS;;;ACPf,SAAf,oBAAyBC,sBAA4B;AACnD,MAAI;AACF,WAAOC,KAAK,MAAMD,uBAAuB,GAAA;EAC3C,SAASE,OAAO;AACd,UAAM,IAAIC,MAAM,kCAAA;EAClB;AACF;AANA;;;ACKA,IAAMC,OAAO,gCAASC,cAAcC,SAAmB;AACrD,SAAO;IACL,GAAGA;IACHC,WAAW,8BAAOC,gBAAAA;AAChB,YAAM,EAACC,QAAO,IAAID;AAElB,YAAME,OAAOC,oBAAYF,QAAQG,MAAMC,SAAQ,CAAA;AAE/C,YAAMC,UAAU;QACd,GAAGN;QACHE;MACF;AAEA,YAAMJ,QAAQS,QAAQL,KAAKM,UAAU,CAAC,GAAGF,OAAAA;IAC3C,GAXW;IAYXG,WAAW,8BAAOC,qBAAAA;AAChB,YAAMJ,UAAU,CAAC;AACjB,YAAME,SAASL,oBAAYO,gBAAAA;AAC3B,YAAMC,SAAS,MAAMb,QAAQS,QAAQC,UAAU,CAAC,GAAGF,OAAAA;AACnD,aAAOK;IACT,GALW;EAMb;AACF,GAtBa;AAwBbf,KAAKgB,QAAQA;AAEb,IAAA,eAAehB;;;AC7BA,SAAf,eAAyBiB,aAAmB;AAF5C,MAAAC,KAAA;AAGE,MAAID,YAAYE,WAAW,MAAA,EAAS,QAAOF;AAE3C,QAAMG,OAAMC,MAAAA,MAAAA,mCAAAA,IAAQC,aAARD,mBAAkBE,SAASN;AAEvC,MAAI,CAACG,KAAK;AACR,UAAM,IAAII,MAAM,6CAA6CP,WAAAA,EAAa;EAC5E;AAEA,SAAOG;AACT;AAVA;;;ACFA,mBAAkB;AAElB,qBAAiC;AAE1B,IAAMK,cAA4B,8BAAMC,YAAAA;AAC7C,QAAMC,SAAS,UAAMC,mCACnB,YAAA;AACE,WAAO,UAAMC,aAAAA,SAAM;MACjBC,QAAQ;MACRC,KAAKL,QAAQK;MACbC,SAASN,QAAQM;MACjBC,SAAS;QACP,cAAc;MAChB;MACAC,MAAMR,QAAQQ;IAChB,CAAA;EACF,GACAR,QAAQS,SACR,GAAA;AAGF,SAAO;IACLD,MAAMP,OAAOO;IACbE,YAAYT,OAAOU;EACrB;AACF,GArByC;;;ACQzC,oBAA8B;AAC9B,IAAAC,kBAAwB;AAExB,eAAA,QACEC,SAAgC;AAhBlC,MAAAC,KAAA;AAkBE,QAAM,EAACC,QAAQC,SAASC,OAAM,IAAIJ;AAClC,QAAMK,mBAAmBC,kBAAUF,MAAAA;AACnC,QAAMG,OAAO,oBAAIC,KAAAA;AACjB,QAAMC,OAAO;IAACP;IAAQC;IAASE;IAAkBE;EAAI;AACrD,QAAMG,YAAYC,qBAAaF,IAAAA;AAE/B,MAAI;AACF,UAAMG,iBAA6BC,MAAAA,MAAAA,mCAAAA,IAAQC,aAARD,mBAAkBE,gBAAeA;AACpE,UAAMC,iBAAoC;MACxCC,KAAKC,eAAOf,OAAAA;MACZgB,SAASnB,QAAQmB;MACjBC,SAASpB,QAAQoB;MACjBC,MAAM;QACJZ;QACAC;MACF;IACF;AACA,UAAMY,SAAS,MAAMV,aAAaI,cAAAA;AAElC,QAAIM,OAAOC,eAAe,KAAK;AAC7B,YAAM,IAAIC,MAAM,qBAAqBF,OAAOC,UAAU,EAAE;IAC1D;AAEA,UAAMF,OAA+BC,OAAOD;AAE5C,QAAIA,KAAKI,OAAO;AACd,YAAMC,OAAOL,KAAKM;AAClB,UAAID,MAAM;AACR,YAAIL,KAAKO,mBAAmB;AAC1B,gBAAM,IAAIC,8BAAgBH,KAAKI,gBAAgB;QACjD;AACA,YAAIT,KAAKU,aAAa;AACpB,gBAAM,IAAIC,0BAAUN,KAAKD,OAAOC,KAAKO,SAASP,KAAKQ,KAAK;QAC1D;MACF;AAEA,YAAM,IAAIV,MAAM,GAAGH,KAAKI,KAAK,EAAE;IACjC;AAEA,UAAMU,WAAWC,oBAAYf,KAAKC,MAAM;AACxC,WAAOa;EACT,SAASV,OAAO;AACd,QAAIA,MAAMY,aAAc,OAAMZ;AAE9B,UAAM,IAAID,MAAM,wCAAwCrB,OAAAA,IAAWD,MAAAA,KAAWuB,MAAMQ,OAAO,EAAE;EAC/F;AACF;AAjD8BK;;;ACf9B,sBAAmC;AAI5B,SAASC,SAAAA;AACd,SAAO,SAAUC,QAAW;AAC1BC,iCAAAA,EAAUD,MAAAA;AACVA,WAAOE,UAAUC,UAAUH;EAC7B;AACF;AALgBD;AAWT,SAASK,YAAYC,UAAgD,CAAC,GAAC;AAC5E,SAAO,SAAUL,QAAaM,aAAqBC,YAAoC;AACrF,QAAI,CAACA,WAAWC,MAAO,OAAM,IAAIC,MAAM,sCAAsCH,WAAAA,EAAa;AAE1FN,WAAOU,SAASV,OAAOU,UAAU,CAAC;AAClCV,WAAOU,OAAOJ,WAAAA,IAAeK,aAAK;MAChC,GAAGN;MACHO,MAAM;MACNC,SAAS,8BAAOC,QAAQC,WAAAA;AACtB,cAAMC,eAAgBC,6BAAYjB,OAAOG,OAAO;AAChD,eAAO,MAAMa,SAASV,WAAAA,EAAaQ,QAAQC,MAAAA;MAC7C,GAHS;IAIX,CAAA;EACF;AACF;AAdgBX;AAgBT,SAASc,UAAUb,UAAgD,CAAC,GAAC;AAC1E,SAAO,SAAUL,QAAaM,aAAqBC,YAAoC;AACrF,QAAI,CAACA,WAAWC,MAAO,OAAM,IAAIC,MAAM,sCAAsCH,WAAAA,EAAa;AAE1FN,WAAOU,SAASV,OAAOU,UAAU,CAAC;AAClCV,WAAOU,OAAOJ,WAAAA,IAAeK,aAAK;MAChC,GAAGN;MACHO,MAAM;MACNC,SAAS,8BAAOC,QAAQC,WAAAA;AACtB,cAAMC,eAAgBC,6BAAYjB,OAAOG,OAAO;AAChD,eAAO,MAAMa,SAASV,WAAAA,EAAaQ,QAAQC,MAAAA;MAC7C,GAHS;IAIX,CAAA;EACF;AACF;AAdgBG;AAgBT,SAASC,iBAAiBnB,QAAW;AAC1C,MAAI,CAACA,OAAOE,WAAW;AACrB,UAAM,IAAIO,MAAM,2CAAA;EAClB;AAEA,SAAOT,OAAOE,UAAUQ,UAAU,CAAC;AACrC;AANgBS;","names":["config","event","request","method","echo","config","echoes","Error","type","types","request","data","cloned","cloneDeep","serialized","serialize","ignoreFunction","getEchoesPassword","_a","secret","config","requests","key","internalGetEnv","console","warn","body","password","getEchoesPassword","shaObj","JSSHA","setHMACKey","update","getHMAC","body","signature","generatedSignature","getSignature","Error","options","route","method","path","requests","handlerPath","bodyParser","bodyParserOptions","limit","resolve","req","body","signature","checkSignature","serializedParams","echo","getEcho","result","onRequest","serialize","error","getInfo","console","message","errorInfo","isValidationError","isUserError","HEARTBEAT_INTERVAL_SECONDS","CHECK_JOIN_CONSUMER_INTERVAL_SECONDS","DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY","DEFAULT_MEMBERS_TO_PARTITIONS_RATIO","KafkaManager","kafka","options","producer","consumer","topics","started","interval","constructor","Kafka","client","Object","keys","echoes","filter","key","type","types","event","checkJoinConsumerGroupConditions","admin","connect","groupDescriptions","describeGroups","groupId","group","groups","state","console","info","topicsMetadata","fetchTopicMetadata","totalPartitions","reduce","acc","topic","partitions","length","members","partitionsRatio","membersToPartitionsRatio","partitionsThreshold","Math","ceil","error","message","disconnect","catch","joinConsumerGroup","subscribe","run","partitionsConsumedConcurrently","eachMessage","params","handleMessage","conditionalStart","start","setInterval","clearInterval","stop","warn","echo","intervalsCount","heartbeatInterval","heartbeat","onMessage","handleRetries","_a","retries","Number","parseInt","headers","toString","attemptsBeforeDeadLetter","undefined","maxRetries","exceededMaxRetries","nextTopic","send","messages","value","String","import_http","kafkaManager","options","config","echoes","requests","registerRoute","requestsHandler","client","KafkaManager","start","producer","consumer","startService","stopService","console","info","stop","options","config","producer","Error","payload","params","send","acks","timeout","topic","messages","value","serialize","publish","serializedJavascript","eval","error","Error","echo","createNewEcho","options","onMessage","messageData","message","data","deserialize","value","toString","context","resolve","params","onRequest","serializedParams","result","types","serviceName","_a","startsWith","url","config","requests","services","Error","makeRequest","options","result","executeWithRetries","axios","method","url","timeout","headers","data","retries","statusCode","status","import_helpers","options","_a","method","service","params","serializedParams","serialize","date","Date","body","signature","getSignature","requestMaker","config","requests","makeRequest","requestOptions","url","getURL","retries","timeout","data","result","statusCode","Error","error","info","errorInfo","isValidationError","ValidationError","validationErrors","isUserError","UserError","message","extra","response","deserialize","isOrionError","request","Echoes","target","Service","prototype","service","EchoRequest","options","propertyKey","descriptor","value","Error","echoes","echo","type","resolve","params","viewer","instance","getInstance","EchoEvent","getServiceEchoes"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/echo/types.ts","../src/requestsHandler/getEcho.ts","../src/publish/serialize.ts","../src/request/getSignature.ts","../src/request/getPassword.ts","../src/requestsHandler/checkSignature.ts","../src/requestsHandler/index.ts","../src/startService/KafkaManager.ts","../src/startService/index.ts","../src/publish/index.ts","../src/echo/deserialize.ts","../src/echo/index.ts","../src/request/getURL.ts","../src/request/makeRequest.ts","../src/request/index.ts","../src/service/index.ts"],"sourcesContent":["import startService, {stopService} from './startService'\nimport publish from './publish'\nimport echo from './echo'\nimport request from './request'\n\nexport * from './types'\nexport * from './service'\n\nexport {publish, startService, stopService, echo, request}\n","import {EchoesConfigHandler} from './types'\n\nconst config: EchoesConfigHandler = {}\n\nexport default config\n","export default {\n event: 'event',\n request: 'request'\n}\n","import config from '../config'\nimport types from '../echo/types'\n\nexport default function (method: string) {\n const echo = config.echoes[method]\n\n if (!echo) {\n throw new Error(`Echo named ${method} not found in this service`)\n }\n\n if (echo.type !== types.request) {\n throw new Error(`Echo named ${method} is not of type request`)\n }\n\n return echo\n}\n","import serialize from 'serialize-javascript'\nimport cloneDeep from 'lodash/cloneDeep'\n\nexport default function (data: any): string {\n const cloned = cloneDeep(data)\n const serialized = serialize(cloned, {ignoreFunction: true})\n return serialized\n}\n","import JSSHA from 'jssha'\nimport {getEchoesPassword} from './getPassword'\n\nexport default function (body: any): string {\n const password = getEchoesPassword()\n const shaObj = new JSSHA('SHA-1', 'TEXT')\n shaObj.setHMACKey(password, 'TEXT')\n shaObj.update(body)\n return shaObj.getHMAC('HEX')\n}\n","import config from '../config'\nimport {internalGetEnv} from '@orion-js/env'\n\nexport function getEchoesPassword() {\n const secret = config?.requests?.key || internalGetEnv('echoes_password', 'ECHOES_PASSWORD')\n if (!secret) {\n console.warn(\n 'Warning: no secret key found for echoes requests. Init echoes or set the env var \"echoes_password\" or process.env.ECHOES_PASSWORD'\n )\n }\n\n return secret\n}\n","import getSignature from '../request/getSignature'\n\nexport default function (body: any, signature: string) {\n const generatedSignature = getSignature(body)\n if (generatedSignature !== signature) {\n throw new Error('Echoes invalid signature')\n }\n}\n","import getEcho from './getEcho'\nimport serialize from '../publish/serialize'\nimport checkSignature from './checkSignature'\nimport {route} from '@orion-js/http'\nimport {EchoesOptions} from '../types'\n\nexport default (options: EchoesOptions) =>\n route({\n method: 'post',\n path: options.requests.handlerPath || '/echoes-services',\n bodyParser: 'json',\n bodyParserOptions: {\n limit: '10mb',\n },\n async resolve(req) {\n try {\n const {body, signature} = req.body\n\n checkSignature(body, signature)\n\n const {method, serializedParams} = body\n\n const echo = getEcho(method)\n const result = await echo.onRequest(serializedParams)\n\n return {\n body: {\n result: serialize(result),\n },\n }\n } catch (error) {\n if (!error.getInfo) {\n console.error('Error at echo requests handler:', error)\n }\n\n return {\n body: {\n error: error.message,\n errorInfo: error.getInfo ? error.getInfo() : null,\n isValidationError: !!error.isValidationError,\n isUserError: !!error.isUserError,\n },\n }\n }\n },\n })\n","import {Kafka, EachMessagePayload, Producer, Consumer} from 'kafkajs'\nimport types from '../echo/types'\nimport {EchoesOptions, EchoType} from '../types'\n\nconst HEARTBEAT_INTERVAL_SECONDS = 5 // This value must be less than the kafkajs session timeout\nconst CHECK_JOIN_CONSUMER_INTERVAL_SECONDS = 30\nconst DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY = 4 // How many partitions to consume concurrently, adjust this with the members to partitions ratio to avoid idle consumers.\nconst DEFAULT_MEMBERS_TO_PARTITIONS_RATIO = 1 // How many members are in comparison to partitions, this is used to determine if the consumer group has room for more members. Numbers over 1 leads to idle consumers. Numbers under 1 needs partitionsConsumedConcurrently to be more than 1.\n\n/**\n * Manages the Kafka connection and the consumers.\n */\nclass KafkaManager {\n kafka: Kafka\n options: EchoesOptions\n producer: Producer\n consumer: Consumer\n topics: string[]\n started: boolean\n interval: NodeJS.Timer\n\n constructor(options: EchoesOptions) {\n this.kafka = new Kafka(options.client)\n this.options = options\n this.producer = this.kafka.producer(options.producer)\n this.consumer = this.kafka.consumer(options.consumer)\n this.topics = Object.keys(options.echoes).filter(\n key => options.echoes[key].type === types.event,\n )\n }\n\n async checkJoinConsumerGroupConditions(): Promise<boolean> {\n const admin = this.kafka.admin()\n try {\n await admin.connect()\n const groupDescriptions = await admin.describeGroups([this.options.consumer.groupId])\n const group = groupDescriptions.groups[0]\n if (group.state === 'Empty') {\n console.info(`Echoes: Consumer group ${this.options.consumer.groupId} is empty, joining`)\n return true\n }\n const topicsMetadata = await admin.fetchTopicMetadata({topics: this.topics})\n const totalPartitions = topicsMetadata.topics.reduce(\n (acc, topic) => acc + topic.partitions.length,\n 0,\n )\n console.info(\n `Echoes: Consumer group ${this.options.consumer.groupId} has ${group.members.length} members and ${totalPartitions} partitions`,\n )\n const partitionsRatio =\n this.options.membersToPartitionsRatio || DEFAULT_MEMBERS_TO_PARTITIONS_RATIO\n const partitionsThreshold = Math.ceil(totalPartitions * partitionsRatio)\n if (partitionsThreshold > group.members.length) {\n console.info(\n `Echoes: Consumer group ${this.options.consumer.groupId} has room for more members ${group.members.length}/${partitionsThreshold}, joining`,\n )\n return true\n }\n } catch (error) {\n console.error(`Echoes: Error checking consumer group conditions, join: ${error.message}`)\n return true\n } finally {\n await admin.disconnect().catch(error => {\n console.error(`Echoes: Error disconnecting admin client: ${error.message}`)\n })\n }\n }\n\n async joinConsumerGroup() {\n await this.consumer.connect()\n await this.consumer.subscribe({topics: this.topics})\n await this.consumer.run({\n partitionsConsumedConcurrently:\n this.options.partitionsConsumedConcurrently || DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY,\n eachMessage: params => this.handleMessage(params),\n })\n }\n\n async conditionalStart(): Promise<boolean> {\n if (await this.checkJoinConsumerGroupConditions()) {\n await this.joinConsumerGroup()\n return true\n }\n }\n\n async start() {\n if (this.started) return\n await this.producer.connect()\n this.started = await this.conditionalStart()\n if (this.started) return\n console.info('Echoes: Delaying consumer group join, waiting for conditions to be met')\n this.interval = setInterval(async () => {\n this.started = await this.conditionalStart()\n if (this.started) clearInterval(this.interval)\n }, CHECK_JOIN_CONSUMER_INTERVAL_SECONDS * 1000)\n }\n\n async stop() {\n console.warn('Echoes: Stopping echoes')\n if (this.interval) clearInterval(this.interval)\n if (this.consumer) await this.consumer.disconnect()\n if (this.producer) await this.producer.disconnect()\n }\n\n async handleMessage(params: EachMessagePayload) {\n const echo = this.options.echoes[params.topic]\n if (!echo || echo.type !== types.event) {\n console.warn(`Echoes: Received a message for an unknown topic: ${params.topic}, ignoring it`)\n return\n }\n\n let intervalsCount = 0\n const heartbeatInterval = setInterval(async () => {\n await params.heartbeat().catch(error => {\n console.warn(`Echoes: Error sending heartbeat: ${error.message}`)\n })\n intervalsCount++\n if ((intervalsCount * HEARTBEAT_INTERVAL_SECONDS) % 30 === 0) {\n console.warn(\n `Echoes: Event is taking too long to process: ${params.topic} ${intervalsCount * HEARTBEAT_INTERVAL_SECONDS}s`,\n )\n }\n }, HEARTBEAT_INTERVAL_SECONDS * 1000)\n\n try {\n await echo.onMessage(params).catch(error => this.handleRetries(echo, params, error))\n } catch (error) {\n console.error(`Echoes: error processing a message: ${params.topic} ${error.message}`)\n throw error\n } finally {\n clearInterval(heartbeatInterval)\n }\n }\n\n async handleRetries(echo: EchoType, params: EachMessagePayload, error: Error) {\n const {message, topic} = params\n const retries = Number.parseInt(message?.headers?.retries?.toString() || '0', 10)\n if (echo.attemptsBeforeDeadLetter === undefined || echo.attemptsBeforeDeadLetter === null) {\n throw error\n }\n const maxRetries = echo.attemptsBeforeDeadLetter || 0\n const exceededMaxRetries = retries >= maxRetries\n const nextTopic = exceededMaxRetries ? `DLQ-${topic}` : topic\n await this.producer.send({\n topic: nextTopic,\n messages: [\n {\n value: message.value.toString(),\n headers: {\n retries: String(retries + 1),\n error: error.message,\n },\n },\n ],\n })\n\n if (exceededMaxRetries) {\n console.error(\n `Echoes: a message has reached the maximum number of retries, sending it to DLQ: ${nextTopic}`,\n )\n } else {\n console.warn(\n `Echoes: a retryable message failed \"${error.message}\", re-sending it to topic: ${nextTopic}`,\n )\n }\n }\n}\n\nexport default KafkaManager\n","import config from '../config'\nimport requestsHandler from '../requestsHandler'\nimport {EchoesOptions} from '../types'\nimport KafkaManager from './KafkaManager'\nimport {registerRoute} from '@orion-js/http'\n\nlet kafkaManager: KafkaManager = null\n\nexport default async function startService(options: EchoesOptions) {\n config.echoes = options.echoes\n\n if (options.requests) {\n config.requests = options.requests\n registerRoute(requestsHandler(options))\n }\n\n if (options.client) {\n kafkaManager = new KafkaManager(options)\n await kafkaManager.start()\n config.producer = kafkaManager.producer\n config.consumer = kafkaManager.consumer\n }\n}\n\nexport async function stopService() {\n if (kafkaManager) {\n console.info('Stoping echoes...')\n await kafkaManager.stop()\n console.info('Echoes stopped')\n }\n}\n","import config from '../config'\nimport {PublishOptions} from '../types'\nimport serialize from './serialize'\n\n/**\n * Publish\n */\nexport default async function publish<TParams = any>(options: PublishOptions<TParams>) {\n if (!config.producer) {\n throw new Error('You must initialize echoes configruation to use publish')\n }\n\n const payload = {\n params: options.params,\n }\n\n return await config.producer.send({\n acks: options.acks,\n timeout: options.timeout,\n topic: options.topic,\n messages: [\n {\n value: serialize(payload),\n },\n ],\n })\n}\n","export default function (serializedJavascript: string): any {\n try {\n return eval('(' + serializedJavascript + ')')\n } catch (error) {\n throw new Error('Error deserializing echo message')\n }\n}\n","import {EachMessagePayload} from 'kafkajs'\nimport {EchoType, EchoConfig} from '../types'\nimport deserialize from './deserialize'\nimport types from './types'\n\nconst echo = function createNewEcho(options: EchoConfig): EchoType {\n return {\n ...options,\n onMessage: async (messageData: EachMessagePayload) => {\n const {message} = messageData\n\n const data = deserialize(message.value.toString())\n\n const context = {\n ...messageData,\n data\n }\n\n await options.resolve(data.params || {}, context)\n },\n onRequest: async (serializedParams: string) => {\n const context = {}\n const params = deserialize(serializedParams)\n const result = await options.resolve(params || {}, context)\n return result\n }\n }\n}\n\necho.types = types\n\nexport default echo\n","import config from '../config'\n\nexport default function (serviceName: string): string {\n if (serviceName.startsWith('http')) return serviceName\n\n const url = config?.requests?.services[serviceName]\n\n if (!url) {\n throw new Error(`No URL found in echoes config for service ${serviceName}`)\n }\n\n return url\n}\n","import axios from 'axios'\nimport {RequestMaker} from '../types'\nimport {executeWithRetries} from '@orion-js/helpers'\n\nexport const makeRequest: RequestMaker = async options => {\n const result = await executeWithRetries(\n async () => {\n return await axios({\n method: 'post',\n url: options.url,\n timeout: options.timeout,\n headers: {\n 'User-Agent': 'Orionjs-Echoes/1.1'\n },\n data: options.data\n })\n },\n options.retries,\n 200\n )\n\n return {\n data: result.data as object,\n statusCode: result.status\n }\n}\n","import getURL from './getURL'\nimport getSignature from './getSignature'\nimport serialize from '../publish/serialize'\nimport deserialize from '../echo/deserialize'\nimport type {\n MakeRequestParams,\n RequestHandlerResponse,\n RequestMaker,\n RequestOptions,\n} from '../types'\nimport config from '../config'\nimport {makeRequest} from './makeRequest'\nimport {ValidationError} from '@orion-js/schema'\nimport {UserError} from '@orion-js/helpers'\n\nexport default async function request<TData = any, TParams = any>(\n options: RequestOptions<TParams>,\n): Promise<TData> {\n const {method, service, params} = options\n const serializedParams = serialize(params)\n const date = new Date()\n const body = {method, service, serializedParams, date}\n const signature = getSignature(body)\n\n try {\n const requestMaker: RequestMaker = config?.requests?.makeRequest || makeRequest\n const requestOptions: MakeRequestParams = {\n url: getURL(service),\n retries: options.retries,\n timeout: options.timeout,\n data: {\n body,\n signature,\n },\n }\n const result = await requestMaker(requestOptions)\n\n if (result.statusCode !== 200) {\n throw new Error(`Wrong status code ${result.statusCode}`)\n }\n\n const data: RequestHandlerResponse = result.data\n\n if (data.error) {\n const info = data.errorInfo\n if (info) {\n if (data.isValidationError) {\n throw new ValidationError(info.validationErrors)\n }\n if (data.isUserError) {\n throw new UserError(info.error, info.message, info.extra)\n }\n }\n\n throw new Error(`${data.error}`)\n }\n\n const response = deserialize(data.result)\n return response\n } catch (error) {\n if (error.isOrionError) throw error\n\n throw new Error(`Echoes request network error calling ${service}/${method}: ${error.message}`)\n }\n}\n","import {getInstance, Service} from '@orion-js/services'\nimport echo from '../echo'\nimport {EchoConfig, EchoesMap} from '../types'\n\nexport function Echoes(): ClassDecorator {\n return function (target: any) {\n Service()(target)\n target.prototype.service = target\n }\n}\n\nexport interface EchoesPropertyDescriptor extends Omit<PropertyDecorator, 'value'> {\n value?: EchoConfig['resolve']\n}\n\nexport function EchoRequest(options: Omit<EchoConfig, 'resolve' | 'type'> = {}) {\n return function (target: any, propertyKey: string, descriptor: EchoesPropertyDescriptor) {\n if (!descriptor.value) throw new Error(`You must pass resolver function to ${propertyKey}`)\n\n target.echoes = target.echoes || {}\n target.echoes[propertyKey] = echo({\n ...options,\n type: 'request',\n resolve: async (params, viewer) => {\n const instance: any = getInstance(target.service)\n return await instance[propertyKey](params, viewer)\n }\n })\n }\n}\n\nexport function EchoEvent(options: Omit<EchoConfig, 'resolve' | 'type'> = {}) {\n return function (target: any, propertyKey: string, descriptor: EchoesPropertyDescriptor) {\n if (!descriptor.value) throw new Error(`You must pass resolver function to ${propertyKey}`)\n\n target.echoes = target.echoes || {}\n target.echoes[propertyKey] = echo({\n ...options,\n type: 'event',\n resolve: async (params, viewer) => {\n const instance: any = getInstance(target.service)\n return await instance[propertyKey](params, viewer)\n }\n })\n }\n}\n\nexport function getServiceEchoes(target: any): EchoesMap {\n if (!target.prototype) {\n throw new Error('You must pass a class to getServiceRoutes')\n }\n\n return target.prototype.echoes || {}\n}\n"],"mappings":"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","names":["echo","cloneDeep","serialize","JSSHA","echo","echo","import_http","axios","import_helpers"]}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
-
|
|
4
1
|
// src/config.ts
|
|
5
2
|
var config = {};
|
|
6
3
|
var config_default = config;
|
|
@@ -22,19 +19,15 @@ function getEcho_default(method) {
|
|
|
22
19
|
}
|
|
23
20
|
return echo2;
|
|
24
21
|
}
|
|
25
|
-
__name(getEcho_default, "default");
|
|
26
22
|
|
|
27
23
|
// src/publish/serialize.ts
|
|
28
24
|
import serialize from "serialize-javascript";
|
|
29
25
|
import cloneDeep from "lodash/cloneDeep";
|
|
30
26
|
function serialize_default(data) {
|
|
31
27
|
const cloned = cloneDeep(data);
|
|
32
|
-
const serialized = serialize(cloned, {
|
|
33
|
-
ignoreFunction: true
|
|
34
|
-
});
|
|
28
|
+
const serialized = serialize(cloned, { ignoreFunction: true });
|
|
35
29
|
return serialized;
|
|
36
30
|
}
|
|
37
|
-
__name(serialize_default, "default");
|
|
38
31
|
|
|
39
32
|
// src/request/getSignature.ts
|
|
40
33
|
import JSSHA from "jssha";
|
|
@@ -42,14 +35,15 @@ import JSSHA from "jssha";
|
|
|
42
35
|
// src/request/getPassword.ts
|
|
43
36
|
import { internalGetEnv } from "@orion-js/env";
|
|
44
37
|
function getEchoesPassword() {
|
|
45
|
-
var
|
|
46
|
-
const secret = ((_b = (
|
|
38
|
+
var _a, _b;
|
|
39
|
+
const secret = ((_b = (_a = config_default) == null ? void 0 : _a.requests) == null ? void 0 : _b.key) || internalGetEnv("echoes_password", "ECHOES_PASSWORD");
|
|
47
40
|
if (!secret) {
|
|
48
|
-
console.warn(
|
|
41
|
+
console.warn(
|
|
42
|
+
'Warning: no secret key found for echoes requests. Init echoes or set the env var "echoes_password" or process.env.ECHOES_PASSWORD'
|
|
43
|
+
);
|
|
49
44
|
}
|
|
50
45
|
return secret;
|
|
51
46
|
}
|
|
52
|
-
__name(getEchoesPassword, "getEchoesPassword");
|
|
53
47
|
|
|
54
48
|
// src/request/getSignature.ts
|
|
55
49
|
function getSignature_default(body) {
|
|
@@ -59,7 +53,6 @@ function getSignature_default(body) {
|
|
|
59
53
|
shaObj.update(body);
|
|
60
54
|
return shaObj.getHMAC("HEX");
|
|
61
55
|
}
|
|
62
|
-
__name(getSignature_default, "default");
|
|
63
56
|
|
|
64
57
|
// src/requestsHandler/checkSignature.ts
|
|
65
58
|
function checkSignature_default(body, signature) {
|
|
@@ -68,11 +61,10 @@ function checkSignature_default(body, signature) {
|
|
|
68
61
|
throw new Error("Echoes invalid signature");
|
|
69
62
|
}
|
|
70
63
|
}
|
|
71
|
-
__name(checkSignature_default, "default");
|
|
72
64
|
|
|
73
65
|
// src/requestsHandler/index.ts
|
|
74
66
|
import { route } from "@orion-js/http";
|
|
75
|
-
var requestsHandler_default =
|
|
67
|
+
var requestsHandler_default = (options) => route({
|
|
76
68
|
method: "post",
|
|
77
69
|
path: options.requests.handlerPath || "/echoes-services",
|
|
78
70
|
bodyParser: "json",
|
|
@@ -105,7 +97,7 @@ var requestsHandler_default = /* @__PURE__ */ __name((options) => route({
|
|
|
105
97
|
};
|
|
106
98
|
}
|
|
107
99
|
}
|
|
108
|
-
})
|
|
100
|
+
});
|
|
109
101
|
|
|
110
102
|
// src/startService/KafkaManager.ts
|
|
111
103
|
import { Kafka } from "kafkajs";
|
|
@@ -113,8 +105,7 @@ var HEARTBEAT_INTERVAL_SECONDS = 5;
|
|
|
113
105
|
var CHECK_JOIN_CONSUMER_INTERVAL_SECONDS = 30;
|
|
114
106
|
var DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY = 4;
|
|
115
107
|
var DEFAULT_MEMBERS_TO_PARTITIONS_RATIO = 1;
|
|
116
|
-
var
|
|
117
|
-
var KafkaManager = (_a = class {
|
|
108
|
+
var KafkaManager = class {
|
|
118
109
|
kafka;
|
|
119
110
|
options;
|
|
120
111
|
producer;
|
|
@@ -127,29 +118,34 @@ var KafkaManager = (_a = class {
|
|
|
127
118
|
this.options = options;
|
|
128
119
|
this.producer = this.kafka.producer(options.producer);
|
|
129
120
|
this.consumer = this.kafka.consumer(options.consumer);
|
|
130
|
-
this.topics = Object.keys(options.echoes).filter(
|
|
121
|
+
this.topics = Object.keys(options.echoes).filter(
|
|
122
|
+
(key) => options.echoes[key].type === types_default.event
|
|
123
|
+
);
|
|
131
124
|
}
|
|
132
125
|
async checkJoinConsumerGroupConditions() {
|
|
133
126
|
const admin = this.kafka.admin();
|
|
134
127
|
try {
|
|
135
128
|
await admin.connect();
|
|
136
|
-
const groupDescriptions = await admin.describeGroups([
|
|
137
|
-
this.options.consumer.groupId
|
|
138
|
-
]);
|
|
129
|
+
const groupDescriptions = await admin.describeGroups([this.options.consumer.groupId]);
|
|
139
130
|
const group = groupDescriptions.groups[0];
|
|
140
131
|
if (group.state === "Empty") {
|
|
141
132
|
console.info(`Echoes: Consumer group ${this.options.consumer.groupId} is empty, joining`);
|
|
142
133
|
return true;
|
|
143
134
|
}
|
|
144
|
-
const topicsMetadata = await admin.fetchTopicMetadata({
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
135
|
+
const topicsMetadata = await admin.fetchTopicMetadata({ topics: this.topics });
|
|
136
|
+
const totalPartitions = topicsMetadata.topics.reduce(
|
|
137
|
+
(acc, topic) => acc + topic.partitions.length,
|
|
138
|
+
0
|
|
139
|
+
);
|
|
140
|
+
console.info(
|
|
141
|
+
`Echoes: Consumer group ${this.options.consumer.groupId} has ${group.members.length} members and ${totalPartitions} partitions`
|
|
142
|
+
);
|
|
149
143
|
const partitionsRatio = this.options.membersToPartitionsRatio || DEFAULT_MEMBERS_TO_PARTITIONS_RATIO;
|
|
150
144
|
const partitionsThreshold = Math.ceil(totalPartitions * partitionsRatio);
|
|
151
145
|
if (partitionsThreshold > group.members.length) {
|
|
152
|
-
console.info(
|
|
146
|
+
console.info(
|
|
147
|
+
`Echoes: Consumer group ${this.options.consumer.groupId} has room for more members ${group.members.length}/${partitionsThreshold}, joining`
|
|
148
|
+
);
|
|
153
149
|
return true;
|
|
154
150
|
}
|
|
155
151
|
} catch (error) {
|
|
@@ -163,12 +159,10 @@ var KafkaManager = (_a = class {
|
|
|
163
159
|
}
|
|
164
160
|
async joinConsumerGroup() {
|
|
165
161
|
await this.consumer.connect();
|
|
166
|
-
await this.consumer.subscribe({
|
|
167
|
-
topics: this.topics
|
|
168
|
-
});
|
|
162
|
+
await this.consumer.subscribe({ topics: this.topics });
|
|
169
163
|
await this.consumer.run({
|
|
170
164
|
partitionsConsumedConcurrently: this.options.partitionsConsumedConcurrently || DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY,
|
|
171
|
-
eachMessage:
|
|
165
|
+
eachMessage: (params) => this.handleMessage(params)
|
|
172
166
|
});
|
|
173
167
|
}
|
|
174
168
|
async conditionalStart() {
|
|
@@ -207,7 +201,9 @@ var KafkaManager = (_a = class {
|
|
|
207
201
|
});
|
|
208
202
|
intervalsCount++;
|
|
209
203
|
if (intervalsCount * HEARTBEAT_INTERVAL_SECONDS % 30 === 0) {
|
|
210
|
-
console.warn(
|
|
204
|
+
console.warn(
|
|
205
|
+
`Echoes: Event is taking too long to process: ${params.topic} ${intervalsCount * HEARTBEAT_INTERVAL_SECONDS}s`
|
|
206
|
+
);
|
|
211
207
|
}
|
|
212
208
|
}, HEARTBEAT_INTERVAL_SECONDS * 1e3);
|
|
213
209
|
try {
|
|
@@ -220,9 +216,9 @@ var KafkaManager = (_a = class {
|
|
|
220
216
|
}
|
|
221
217
|
}
|
|
222
218
|
async handleRetries(echo2, params, error) {
|
|
223
|
-
var
|
|
219
|
+
var _a, _b;
|
|
224
220
|
const { message, topic } = params;
|
|
225
|
-
const retries = Number.parseInt(((_b = (
|
|
221
|
+
const retries = Number.parseInt(((_b = (_a = message == null ? void 0 : message.headers) == null ? void 0 : _a.retries) == null ? void 0 : _b.toString()) || "0", 10);
|
|
226
222
|
if (echo2.attemptsBeforeDeadLetter === void 0 || echo2.attemptsBeforeDeadLetter === null) {
|
|
227
223
|
throw error;
|
|
228
224
|
}
|
|
@@ -242,12 +238,16 @@ var KafkaManager = (_a = class {
|
|
|
242
238
|
]
|
|
243
239
|
});
|
|
244
240
|
if (exceededMaxRetries) {
|
|
245
|
-
console.error(
|
|
241
|
+
console.error(
|
|
242
|
+
`Echoes: a message has reached the maximum number of retries, sending it to DLQ: ${nextTopic}`
|
|
243
|
+
);
|
|
246
244
|
} else {
|
|
247
|
-
console.warn(
|
|
245
|
+
console.warn(
|
|
246
|
+
`Echoes: a retryable message failed "${error.message}", re-sending it to topic: ${nextTopic}`
|
|
247
|
+
);
|
|
248
248
|
}
|
|
249
249
|
}
|
|
250
|
-
}
|
|
250
|
+
};
|
|
251
251
|
var KafkaManager_default = KafkaManager;
|
|
252
252
|
|
|
253
253
|
// src/startService/index.ts
|
|
@@ -266,7 +266,6 @@ async function startService(options) {
|
|
|
266
266
|
config_default.consumer = kafkaManager.consumer;
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
|
-
__name(startService, "startService");
|
|
270
269
|
async function stopService() {
|
|
271
270
|
if (kafkaManager) {
|
|
272
271
|
console.info("Stoping echoes...");
|
|
@@ -274,7 +273,6 @@ async function stopService() {
|
|
|
274
273
|
console.info("Echoes stopped");
|
|
275
274
|
}
|
|
276
275
|
}
|
|
277
|
-
__name(stopService, "stopService");
|
|
278
276
|
|
|
279
277
|
// src/publish/index.ts
|
|
280
278
|
async function publish(options) {
|
|
@@ -295,7 +293,6 @@ async function publish(options) {
|
|
|
295
293
|
]
|
|
296
294
|
});
|
|
297
295
|
}
|
|
298
|
-
__name(publish, "publish");
|
|
299
296
|
|
|
300
297
|
// src/echo/deserialize.ts
|
|
301
298
|
function deserialize_default(serializedJavascript) {
|
|
@@ -305,13 +302,12 @@ function deserialize_default(serializedJavascript) {
|
|
|
305
302
|
throw new Error("Error deserializing echo message");
|
|
306
303
|
}
|
|
307
304
|
}
|
|
308
|
-
__name(deserialize_default, "default");
|
|
309
305
|
|
|
310
306
|
// src/echo/index.ts
|
|
311
|
-
var echo =
|
|
307
|
+
var echo = function createNewEcho(options) {
|
|
312
308
|
return {
|
|
313
309
|
...options,
|
|
314
|
-
onMessage:
|
|
310
|
+
onMessage: async (messageData) => {
|
|
315
311
|
const { message } = messageData;
|
|
316
312
|
const data = deserialize_default(message.value.toString());
|
|
317
313
|
const context = {
|
|
@@ -319,68 +315,66 @@ var echo = /* @__PURE__ */ __name(function createNewEcho(options) {
|
|
|
319
315
|
data
|
|
320
316
|
};
|
|
321
317
|
await options.resolve(data.params || {}, context);
|
|
322
|
-
},
|
|
323
|
-
onRequest:
|
|
318
|
+
},
|
|
319
|
+
onRequest: async (serializedParams) => {
|
|
324
320
|
const context = {};
|
|
325
321
|
const params = deserialize_default(serializedParams);
|
|
326
322
|
const result = await options.resolve(params || {}, context);
|
|
327
323
|
return result;
|
|
328
|
-
}
|
|
324
|
+
}
|
|
329
325
|
};
|
|
330
|
-
}
|
|
326
|
+
};
|
|
331
327
|
echo.types = types_default;
|
|
332
328
|
var echo_default = echo;
|
|
333
329
|
|
|
334
330
|
// src/request/getURL.ts
|
|
335
331
|
function getURL_default(serviceName) {
|
|
336
|
-
var
|
|
332
|
+
var _a, _b;
|
|
337
333
|
if (serviceName.startsWith("http")) return serviceName;
|
|
338
|
-
const url = (_b = (
|
|
334
|
+
const url = (_b = (_a = config_default) == null ? void 0 : _a.requests) == null ? void 0 : _b.services[serviceName];
|
|
339
335
|
if (!url) {
|
|
340
336
|
throw new Error(`No URL found in echoes config for service ${serviceName}`);
|
|
341
337
|
}
|
|
342
338
|
return url;
|
|
343
339
|
}
|
|
344
|
-
__name(getURL_default, "default");
|
|
345
340
|
|
|
346
341
|
// src/request/makeRequest.ts
|
|
347
342
|
import axios from "axios";
|
|
348
343
|
import { executeWithRetries } from "@orion-js/helpers";
|
|
349
|
-
var makeRequest =
|
|
350
|
-
const result = await executeWithRetries(
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
344
|
+
var makeRequest = async (options) => {
|
|
345
|
+
const result = await executeWithRetries(
|
|
346
|
+
async () => {
|
|
347
|
+
return await axios({
|
|
348
|
+
method: "post",
|
|
349
|
+
url: options.url,
|
|
350
|
+
timeout: options.timeout,
|
|
351
|
+
headers: {
|
|
352
|
+
"User-Agent": "Orionjs-Echoes/1.1"
|
|
353
|
+
},
|
|
354
|
+
data: options.data
|
|
355
|
+
});
|
|
356
|
+
},
|
|
357
|
+
options.retries,
|
|
358
|
+
200
|
|
359
|
+
);
|
|
361
360
|
return {
|
|
362
361
|
data: result.data,
|
|
363
362
|
statusCode: result.status
|
|
364
363
|
};
|
|
365
|
-
}
|
|
364
|
+
};
|
|
366
365
|
|
|
367
366
|
// src/request/index.ts
|
|
368
367
|
import { ValidationError } from "@orion-js/schema";
|
|
369
368
|
import { UserError } from "@orion-js/helpers";
|
|
370
369
|
async function request(options) {
|
|
371
|
-
var
|
|
370
|
+
var _a, _b;
|
|
372
371
|
const { method, service, params } = options;
|
|
373
372
|
const serializedParams = serialize_default(params);
|
|
374
373
|
const date = /* @__PURE__ */ new Date();
|
|
375
|
-
const body = {
|
|
376
|
-
method,
|
|
377
|
-
service,
|
|
378
|
-
serializedParams,
|
|
379
|
-
date
|
|
380
|
-
};
|
|
374
|
+
const body = { method, service, serializedParams, date };
|
|
381
375
|
const signature = getSignature_default(body);
|
|
382
376
|
try {
|
|
383
|
-
const requestMaker = ((_b = (
|
|
377
|
+
const requestMaker = ((_b = (_a = config_default) == null ? void 0 : _a.requests) == null ? void 0 : _b.makeRequest) || makeRequest;
|
|
384
378
|
const requestOptions = {
|
|
385
379
|
url: getURL_default(service),
|
|
386
380
|
retries: options.retries,
|
|
@@ -414,7 +408,6 @@ async function request(options) {
|
|
|
414
408
|
throw new Error(`Echoes request network error calling ${service}/${method}: ${error.message}`);
|
|
415
409
|
}
|
|
416
410
|
}
|
|
417
|
-
__name(request, "request");
|
|
418
411
|
|
|
419
412
|
// src/service/index.ts
|
|
420
413
|
import { getInstance, Service } from "@orion-js/services";
|
|
@@ -424,7 +417,6 @@ function Echoes() {
|
|
|
424
417
|
target.prototype.service = target;
|
|
425
418
|
};
|
|
426
419
|
}
|
|
427
|
-
__name(Echoes, "Echoes");
|
|
428
420
|
function EchoRequest(options = {}) {
|
|
429
421
|
return function(target, propertyKey, descriptor) {
|
|
430
422
|
if (!descriptor.value) throw new Error(`You must pass resolver function to ${propertyKey}`);
|
|
@@ -432,14 +424,13 @@ function EchoRequest(options = {}) {
|
|
|
432
424
|
target.echoes[propertyKey] = echo_default({
|
|
433
425
|
...options,
|
|
434
426
|
type: "request",
|
|
435
|
-
resolve:
|
|
427
|
+
resolve: async (params, viewer) => {
|
|
436
428
|
const instance = getInstance(target.service);
|
|
437
429
|
return await instance[propertyKey](params, viewer);
|
|
438
|
-
}
|
|
430
|
+
}
|
|
439
431
|
});
|
|
440
432
|
};
|
|
441
433
|
}
|
|
442
|
-
__name(EchoRequest, "EchoRequest");
|
|
443
434
|
function EchoEvent(options = {}) {
|
|
444
435
|
return function(target, propertyKey, descriptor) {
|
|
445
436
|
if (!descriptor.value) throw new Error(`You must pass resolver function to ${propertyKey}`);
|
|
@@ -447,21 +438,19 @@ function EchoEvent(options = {}) {
|
|
|
447
438
|
target.echoes[propertyKey] = echo_default({
|
|
448
439
|
...options,
|
|
449
440
|
type: "event",
|
|
450
|
-
resolve:
|
|
441
|
+
resolve: async (params, viewer) => {
|
|
451
442
|
const instance = getInstance(target.service);
|
|
452
443
|
return await instance[propertyKey](params, viewer);
|
|
453
|
-
}
|
|
444
|
+
}
|
|
454
445
|
});
|
|
455
446
|
};
|
|
456
447
|
}
|
|
457
|
-
__name(EchoEvent, "EchoEvent");
|
|
458
448
|
function getServiceEchoes(target) {
|
|
459
449
|
if (!target.prototype) {
|
|
460
450
|
throw new Error("You must pass a class to getServiceRoutes");
|
|
461
451
|
}
|
|
462
452
|
return target.prototype.echoes || {};
|
|
463
453
|
}
|
|
464
|
-
__name(getServiceEchoes, "getServiceEchoes");
|
|
465
454
|
export {
|
|
466
455
|
EchoEvent,
|
|
467
456
|
EchoRequest,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts","../src/echo/types.ts","../src/requestsHandler/getEcho.ts","../src/publish/serialize.ts","../src/request/getSignature.ts","../src/request/getPassword.ts","../src/requestsHandler/checkSignature.ts","../src/requestsHandler/index.ts","../src/startService/KafkaManager.ts","../src/startService/index.ts","../src/publish/index.ts","../src/echo/deserialize.ts","../src/echo/index.ts","../src/request/getURL.ts","../src/request/makeRequest.ts","../src/request/index.ts","../src/service/index.ts"],"sourcesContent":["import {EchoesConfigHandler} from './types'\n\nconst config: EchoesConfigHandler = {}\n\nexport default config\n","export default {\n event: 'event',\n request: 'request'\n}\n","import config from '../config'\nimport types from '../echo/types'\n\nexport default function (method: string) {\n const echo = config.echoes[method]\n\n if (!echo) {\n throw new Error(`Echo named ${method} not found in this service`)\n }\n\n if (echo.type !== types.request) {\n throw new Error(`Echo named ${method} is not of type request`)\n }\n\n return echo\n}\n","import serialize from 'serialize-javascript'\nimport cloneDeep from 'lodash/cloneDeep'\n\nexport default function (data: any): string {\n const cloned = cloneDeep(data)\n const serialized = serialize(cloned, {ignoreFunction: true})\n return serialized\n}\n","import JSSHA from 'jssha'\nimport {getEchoesPassword} from './getPassword'\n\nexport default function (body: any): string {\n const password = getEchoesPassword()\n const shaObj = new JSSHA('SHA-1', 'TEXT')\n shaObj.setHMACKey(password, 'TEXT')\n shaObj.update(body)\n return shaObj.getHMAC('HEX')\n}\n","import config from '../config'\nimport {internalGetEnv} from '@orion-js/env'\n\nexport function getEchoesPassword() {\n const secret = config?.requests?.key || internalGetEnv('echoes_password', 'ECHOES_PASSWORD')\n if (!secret) {\n console.warn(\n 'Warning: no secret key found for echoes requests. Init echoes or set the env var \"echoes_password\" or process.env.ECHOES_PASSWORD'\n )\n }\n\n return secret\n}\n","import getSignature from '../request/getSignature'\n\nexport default function (body: any, signature: string) {\n const generatedSignature = getSignature(body)\n if (generatedSignature !== signature) {\n throw new Error('Echoes invalid signature')\n }\n}\n","import getEcho from './getEcho'\nimport serialize from '../publish/serialize'\nimport checkSignature from './checkSignature'\nimport {route} from '@orion-js/http'\nimport {EchoesOptions} from '../types'\n\nexport default (options: EchoesOptions) =>\n route({\n method: 'post',\n path: options.requests.handlerPath || '/echoes-services',\n bodyParser: 'json',\n bodyParserOptions: {\n limit: '10mb',\n },\n async resolve(req) {\n try {\n const {body, signature} = req.body\n\n checkSignature(body, signature)\n\n const {method, serializedParams} = body\n\n const echo = getEcho(method)\n const result = await echo.onRequest(serializedParams)\n\n return {\n body: {\n result: serialize(result),\n },\n }\n } catch (error) {\n if (!error.getInfo) {\n console.error('Error at echo requests handler:', error)\n }\n\n return {\n body: {\n error: error.message,\n errorInfo: error.getInfo ? error.getInfo() : null,\n isValidationError: !!error.isValidationError,\n isUserError: !!error.isUserError,\n },\n }\n }\n },\n })\n","import {Kafka, EachMessagePayload, Producer, Consumer} from 'kafkajs'\nimport types from '../echo/types'\nimport {EchoesOptions, EchoType} from '../types'\n\nconst HEARTBEAT_INTERVAL_SECONDS = 5 // This value must be less than the kafkajs session timeout\nconst CHECK_JOIN_CONSUMER_INTERVAL_SECONDS = 30\nconst DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY = 4 // How many partitions to consume concurrently, adjust this with the members to partitions ratio to avoid idle consumers.\nconst DEFAULT_MEMBERS_TO_PARTITIONS_RATIO = 1 // How many members are in comparison to partitions, this is used to determine if the consumer group has room for more members. Numbers over 1 leads to idle consumers. Numbers under 1 needs partitionsConsumedConcurrently to be more than 1.\n\n/**\n * Manages the Kafka connection and the consumers.\n */\nclass KafkaManager {\n kafka: Kafka\n options: EchoesOptions\n producer: Producer\n consumer: Consumer\n topics: string[]\n started: boolean\n interval: NodeJS.Timer\n\n constructor(options: EchoesOptions) {\n this.kafka = new Kafka(options.client)\n this.options = options\n this.producer = this.kafka.producer(options.producer)\n this.consumer = this.kafka.consumer(options.consumer)\n this.topics = Object.keys(options.echoes).filter(\n key => options.echoes[key].type === types.event,\n )\n }\n\n async checkJoinConsumerGroupConditions(): Promise<boolean> {\n const admin = this.kafka.admin()\n try {\n await admin.connect()\n const groupDescriptions = await admin.describeGroups([this.options.consumer.groupId])\n const group = groupDescriptions.groups[0]\n if (group.state === 'Empty') {\n console.info(`Echoes: Consumer group ${this.options.consumer.groupId} is empty, joining`)\n return true\n }\n const topicsMetadata = await admin.fetchTopicMetadata({topics: this.topics})\n const totalPartitions = topicsMetadata.topics.reduce(\n (acc, topic) => acc + topic.partitions.length,\n 0,\n )\n console.info(\n `Echoes: Consumer group ${this.options.consumer.groupId} has ${group.members.length} members and ${totalPartitions} partitions`,\n )\n const partitionsRatio =\n this.options.membersToPartitionsRatio || DEFAULT_MEMBERS_TO_PARTITIONS_RATIO\n const partitionsThreshold = Math.ceil(totalPartitions * partitionsRatio)\n if (partitionsThreshold > group.members.length) {\n console.info(\n `Echoes: Consumer group ${this.options.consumer.groupId} has room for more members ${group.members.length}/${partitionsThreshold}, joining`,\n )\n return true\n }\n } catch (error) {\n console.error(`Echoes: Error checking consumer group conditions, join: ${error.message}`)\n return true\n } finally {\n await admin.disconnect().catch(error => {\n console.error(`Echoes: Error disconnecting admin client: ${error.message}`)\n })\n }\n }\n\n async joinConsumerGroup() {\n await this.consumer.connect()\n await this.consumer.subscribe({topics: this.topics})\n await this.consumer.run({\n partitionsConsumedConcurrently:\n this.options.partitionsConsumedConcurrently || DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY,\n eachMessage: params => this.handleMessage(params),\n })\n }\n\n async conditionalStart(): Promise<boolean> {\n if (await this.checkJoinConsumerGroupConditions()) {\n await this.joinConsumerGroup()\n return true\n }\n }\n\n async start() {\n if (this.started) return\n await this.producer.connect()\n this.started = await this.conditionalStart()\n if (this.started) return\n console.info('Echoes: Delaying consumer group join, waiting for conditions to be met')\n this.interval = setInterval(async () => {\n this.started = await this.conditionalStart()\n if (this.started) clearInterval(this.interval)\n }, CHECK_JOIN_CONSUMER_INTERVAL_SECONDS * 1000)\n }\n\n async stop() {\n console.warn('Echoes: Stopping echoes')\n if (this.interval) clearInterval(this.interval)\n if (this.consumer) await this.consumer.disconnect()\n if (this.producer) await this.producer.disconnect()\n }\n\n async handleMessage(params: EachMessagePayload) {\n const echo = this.options.echoes[params.topic]\n if (!echo || echo.type !== types.event) {\n console.warn(`Echoes: Received a message for an unknown topic: ${params.topic}, ignoring it`)\n return\n }\n\n let intervalsCount = 0\n const heartbeatInterval = setInterval(async () => {\n await params.heartbeat().catch(error => {\n console.warn(`Echoes: Error sending heartbeat: ${error.message}`)\n })\n intervalsCount++\n if ((intervalsCount * HEARTBEAT_INTERVAL_SECONDS) % 30 === 0) {\n console.warn(\n `Echoes: Event is taking too long to process: ${params.topic} ${intervalsCount * HEARTBEAT_INTERVAL_SECONDS}s`,\n )\n }\n }, HEARTBEAT_INTERVAL_SECONDS * 1000)\n\n try {\n await echo.onMessage(params).catch(error => this.handleRetries(echo, params, error))\n } catch (error) {\n console.error(`Echoes: error processing a message: ${params.topic} ${error.message}`)\n throw error\n } finally {\n clearInterval(heartbeatInterval)\n }\n }\n\n async handleRetries(echo: EchoType, params: EachMessagePayload, error: Error) {\n const {message, topic} = params\n const retries = Number.parseInt(message?.headers?.retries?.toString() || '0', 10)\n if (echo.attemptsBeforeDeadLetter === undefined || echo.attemptsBeforeDeadLetter === null) {\n throw error\n }\n const maxRetries = echo.attemptsBeforeDeadLetter || 0\n const exceededMaxRetries = retries >= maxRetries\n const nextTopic = exceededMaxRetries ? `DLQ-${topic}` : topic\n await this.producer.send({\n topic: nextTopic,\n messages: [\n {\n value: message.value.toString(),\n headers: {\n retries: String(retries + 1),\n error: error.message,\n },\n },\n ],\n })\n\n if (exceededMaxRetries) {\n console.error(\n `Echoes: a message has reached the maximum number of retries, sending it to DLQ: ${nextTopic}`,\n )\n } else {\n console.warn(\n `Echoes: a retryable message failed \"${error.message}\", re-sending it to topic: ${nextTopic}`,\n )\n }\n }\n}\n\nexport default KafkaManager\n","import config from '../config'\nimport requestsHandler from '../requestsHandler'\nimport {EchoesOptions} from '../types'\nimport KafkaManager from './KafkaManager'\nimport {registerRoute} from '@orion-js/http'\n\nlet kafkaManager: KafkaManager = null\n\nexport default async function startService(options: EchoesOptions) {\n config.echoes = options.echoes\n\n if (options.requests) {\n config.requests = options.requests\n registerRoute(requestsHandler(options))\n }\n\n if (options.client) {\n kafkaManager = new KafkaManager(options)\n await kafkaManager.start()\n config.producer = kafkaManager.producer\n config.consumer = kafkaManager.consumer\n }\n}\n\nexport async function stopService() {\n if (kafkaManager) {\n console.info('Stoping echoes...')\n await kafkaManager.stop()\n console.info('Echoes stopped')\n }\n}\n","import config from '../config'\nimport {PublishOptions} from '../types'\nimport serialize from './serialize'\n\n/**\n * Publish\n */\nexport default async function publish<TParams = any>(options: PublishOptions<TParams>) {\n if (!config.producer) {\n throw new Error('You must initialize echoes configruation to use publish')\n }\n\n const payload = {\n params: options.params,\n }\n\n return await config.producer.send({\n acks: options.acks,\n timeout: options.timeout,\n topic: options.topic,\n messages: [\n {\n value: serialize(payload),\n },\n ],\n })\n}\n","export default function (serializedJavascript: string): any {\n try {\n return eval('(' + serializedJavascript + ')')\n } catch (error) {\n throw new Error('Error deserializing echo message')\n }\n}\n","import {EachMessagePayload} from 'kafkajs'\nimport {EchoType, EchoConfig} from '../types'\nimport deserialize from './deserialize'\nimport types from './types'\n\nconst echo = function createNewEcho(options: EchoConfig): EchoType {\n return {\n ...options,\n onMessage: async (messageData: EachMessagePayload) => {\n const {message} = messageData\n\n const data = deserialize(message.value.toString())\n\n const context = {\n ...messageData,\n data\n }\n\n await options.resolve(data.params || {}, context)\n },\n onRequest: async (serializedParams: string) => {\n const context = {}\n const params = deserialize(serializedParams)\n const result = await options.resolve(params || {}, context)\n return result\n }\n }\n}\n\necho.types = types\n\nexport default echo\n","import config from '../config'\n\nexport default function (serviceName: string): string {\n if (serviceName.startsWith('http')) return serviceName\n\n const url = config?.requests?.services[serviceName]\n\n if (!url) {\n throw new Error(`No URL found in echoes config for service ${serviceName}`)\n }\n\n return url\n}\n","import axios from 'axios'\nimport {RequestMaker} from '../types'\nimport {executeWithRetries} from '@orion-js/helpers'\n\nexport const makeRequest: RequestMaker = async options => {\n const result = await executeWithRetries(\n async () => {\n return await axios({\n method: 'post',\n url: options.url,\n timeout: options.timeout,\n headers: {\n 'User-Agent': 'Orionjs-Echoes/1.1'\n },\n data: options.data\n })\n },\n options.retries,\n 200\n )\n\n return {\n data: result.data as object,\n statusCode: result.status\n }\n}\n","import getURL from './getURL'\nimport getSignature from './getSignature'\nimport serialize from '../publish/serialize'\nimport deserialize from '../echo/deserialize'\nimport type {\n MakeRequestParams,\n RequestHandlerResponse,\n RequestMaker,\n RequestOptions,\n} from '../types'\nimport config from '../config'\nimport {makeRequest} from './makeRequest'\nimport {ValidationError} from '@orion-js/schema'\nimport {UserError} from '@orion-js/helpers'\n\nexport default async function request<TData = any, TParams = any>(\n options: RequestOptions<TParams>,\n): Promise<TData> {\n const {method, service, params} = options\n const serializedParams = serialize(params)\n const date = new Date()\n const body = {method, service, serializedParams, date}\n const signature = getSignature(body)\n\n try {\n const requestMaker: RequestMaker = config?.requests?.makeRequest || makeRequest\n const requestOptions: MakeRequestParams = {\n url: getURL(service),\n retries: options.retries,\n timeout: options.timeout,\n data: {\n body,\n signature,\n },\n }\n const result = await requestMaker(requestOptions)\n\n if (result.statusCode !== 200) {\n throw new Error(`Wrong status code ${result.statusCode}`)\n }\n\n const data: RequestHandlerResponse = result.data\n\n if (data.error) {\n const info = data.errorInfo\n if (info) {\n if (data.isValidationError) {\n throw new ValidationError(info.validationErrors)\n }\n if (data.isUserError) {\n throw new UserError(info.error, info.message, info.extra)\n }\n }\n\n throw new Error(`${data.error}`)\n }\n\n const response = deserialize(data.result)\n return response\n } catch (error) {\n if (error.isOrionError) throw error\n\n throw new Error(`Echoes request network error calling ${service}/${method}: ${error.message}`)\n }\n}\n","import {getInstance, Service} from '@orion-js/services'\nimport echo from '../echo'\nimport {EchoConfig, EchoesMap} from '../types'\n\nexport function Echoes(): ClassDecorator {\n return function (target: any) {\n Service()(target)\n target.prototype.service = target\n }\n}\n\nexport interface EchoesPropertyDescriptor extends Omit<PropertyDecorator, 'value'> {\n value?: EchoConfig['resolve']\n}\n\nexport function EchoRequest(options: Omit<EchoConfig, 'resolve' | 'type'> = {}) {\n return function (target: any, propertyKey: string, descriptor: EchoesPropertyDescriptor) {\n if (!descriptor.value) throw new Error(`You must pass resolver function to ${propertyKey}`)\n\n target.echoes = target.echoes || {}\n target.echoes[propertyKey] = echo({\n ...options,\n type: 'request',\n resolve: async (params, viewer) => {\n const instance: any = getInstance(target.service)\n return await instance[propertyKey](params, viewer)\n }\n })\n }\n}\n\nexport function EchoEvent(options: Omit<EchoConfig, 'resolve' | 'type'> = {}) {\n return function (target: any, propertyKey: string, descriptor: EchoesPropertyDescriptor) {\n if (!descriptor.value) throw new Error(`You must pass resolver function to ${propertyKey}`)\n\n target.echoes = target.echoes || {}\n target.echoes[propertyKey] = echo({\n ...options,\n type: 'event',\n resolve: async (params, viewer) => {\n const instance: any = getInstance(target.service)\n return await instance[propertyKey](params, viewer)\n }\n })\n }\n}\n\nexport function getServiceEchoes(target: any): EchoesMap {\n if (!target.prototype) {\n throw new Error('You must pass a class to getServiceRoutes')\n }\n\n return target.prototype.echoes || {}\n}\n"],"mappings":"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","names":["config","event","request","method","echo","config","echoes","Error","type","types","request","serialize","cloneDeep","data","cloned","cloneDeep","serialized","serialize","ignoreFunction","JSSHA","internalGetEnv","getEchoesPassword","_a","secret","config","requests","key","internalGetEnv","console","warn","body","password","getEchoesPassword","shaObj","JSSHA","setHMACKey","update","getHMAC","body","signature","generatedSignature","getSignature","Error","route","options","route","method","path","requests","handlerPath","bodyParser","bodyParserOptions","limit","resolve","req","body","signature","checkSignature","serializedParams","echo","getEcho","result","onRequest","serialize","error","getInfo","console","message","errorInfo","isValidationError","isUserError","Kafka","HEARTBEAT_INTERVAL_SECONDS","CHECK_JOIN_CONSUMER_INTERVAL_SECONDS","DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY","DEFAULT_MEMBERS_TO_PARTITIONS_RATIO","KafkaManager","kafka","options","producer","consumer","topics","started","interval","constructor","Kafka","client","Object","keys","echoes","filter","key","type","types","event","checkJoinConsumerGroupConditions","admin","connect","groupDescriptions","describeGroups","groupId","group","groups","state","console","info","topicsMetadata","fetchTopicMetadata","totalPartitions","reduce","acc","topic","partitions","length","members","partitionsRatio","membersToPartitionsRatio","partitionsThreshold","Math","ceil","error","message","disconnect","catch","joinConsumerGroup","subscribe","run","partitionsConsumedConcurrently","eachMessage","params","handleMessage","conditionalStart","start","setInterval","clearInterval","stop","warn","echo","intervalsCount","heartbeatInterval","heartbeat","onMessage","handleRetries","_a","retries","Number","parseInt","headers","toString","attemptsBeforeDeadLetter","undefined","maxRetries","exceededMaxRetries","nextTopic","send","messages","value","String","registerRoute","kafkaManager","options","config","echoes","requests","registerRoute","requestsHandler","client","KafkaManager","start","producer","consumer","startService","stopService","console","info","stop","options","config","producer","Error","payload","params","send","acks","timeout","topic","messages","value","serialize","publish","serializedJavascript","eval","error","Error","echo","createNewEcho","options","onMessage","messageData","message","data","deserialize","value","toString","context","resolve","params","onRequest","serializedParams","result","types","serviceName","_a","startsWith","url","config","requests","services","Error","axios","executeWithRetries","makeRequest","options","result","executeWithRetries","axios","method","url","timeout","headers","data","retries","statusCode","status","ValidationError","UserError","options","_a","method","service","params","serializedParams","serialize","date","Date","body","signature","getSignature","requestMaker","config","requests","makeRequest","requestOptions","url","getURL","retries","timeout","data","result","statusCode","Error","error","info","errorInfo","isValidationError","ValidationError","validationErrors","isUserError","UserError","message","extra","response","deserialize","isOrionError","request","getInstance","Service","Echoes","target","Service","prototype","service","EchoRequest","options","propertyKey","descriptor","value","Error","echoes","echo","type","resolve","params","viewer","instance","getInstance","EchoEvent","getServiceEchoes"]}
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/echo/types.ts","../src/requestsHandler/getEcho.ts","../src/publish/serialize.ts","../src/request/getSignature.ts","../src/request/getPassword.ts","../src/requestsHandler/checkSignature.ts","../src/requestsHandler/index.ts","../src/startService/KafkaManager.ts","../src/startService/index.ts","../src/publish/index.ts","../src/echo/deserialize.ts","../src/echo/index.ts","../src/request/getURL.ts","../src/request/makeRequest.ts","../src/request/index.ts","../src/service/index.ts"],"sourcesContent":["import {EchoesConfigHandler} from './types'\n\nconst config: EchoesConfigHandler = {}\n\nexport default config\n","export default {\n event: 'event',\n request: 'request'\n}\n","import config from '../config'\nimport types from '../echo/types'\n\nexport default function (method: string) {\n const echo = config.echoes[method]\n\n if (!echo) {\n throw new Error(`Echo named ${method} not found in this service`)\n }\n\n if (echo.type !== types.request) {\n throw new Error(`Echo named ${method} is not of type request`)\n }\n\n return echo\n}\n","import serialize from 'serialize-javascript'\nimport cloneDeep from 'lodash/cloneDeep'\n\nexport default function (data: any): string {\n const cloned = cloneDeep(data)\n const serialized = serialize(cloned, {ignoreFunction: true})\n return serialized\n}\n","import JSSHA from 'jssha'\nimport {getEchoesPassword} from './getPassword'\n\nexport default function (body: any): string {\n const password = getEchoesPassword()\n const shaObj = new JSSHA('SHA-1', 'TEXT')\n shaObj.setHMACKey(password, 'TEXT')\n shaObj.update(body)\n return shaObj.getHMAC('HEX')\n}\n","import config from '../config'\nimport {internalGetEnv} from '@orion-js/env'\n\nexport function getEchoesPassword() {\n const secret = config?.requests?.key || internalGetEnv('echoes_password', 'ECHOES_PASSWORD')\n if (!secret) {\n console.warn(\n 'Warning: no secret key found for echoes requests. Init echoes or set the env var \"echoes_password\" or process.env.ECHOES_PASSWORD'\n )\n }\n\n return secret\n}\n","import getSignature from '../request/getSignature'\n\nexport default function (body: any, signature: string) {\n const generatedSignature = getSignature(body)\n if (generatedSignature !== signature) {\n throw new Error('Echoes invalid signature')\n }\n}\n","import getEcho from './getEcho'\nimport serialize from '../publish/serialize'\nimport checkSignature from './checkSignature'\nimport {route} from '@orion-js/http'\nimport {EchoesOptions} from '../types'\n\nexport default (options: EchoesOptions) =>\n route({\n method: 'post',\n path: options.requests.handlerPath || '/echoes-services',\n bodyParser: 'json',\n bodyParserOptions: {\n limit: '10mb',\n },\n async resolve(req) {\n try {\n const {body, signature} = req.body\n\n checkSignature(body, signature)\n\n const {method, serializedParams} = body\n\n const echo = getEcho(method)\n const result = await echo.onRequest(serializedParams)\n\n return {\n body: {\n result: serialize(result),\n },\n }\n } catch (error) {\n if (!error.getInfo) {\n console.error('Error at echo requests handler:', error)\n }\n\n return {\n body: {\n error: error.message,\n errorInfo: error.getInfo ? error.getInfo() : null,\n isValidationError: !!error.isValidationError,\n isUserError: !!error.isUserError,\n },\n }\n }\n },\n })\n","import {Kafka, EachMessagePayload, Producer, Consumer} from 'kafkajs'\nimport types from '../echo/types'\nimport {EchoesOptions, EchoType} from '../types'\n\nconst HEARTBEAT_INTERVAL_SECONDS = 5 // This value must be less than the kafkajs session timeout\nconst CHECK_JOIN_CONSUMER_INTERVAL_SECONDS = 30\nconst DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY = 4 // How many partitions to consume concurrently, adjust this with the members to partitions ratio to avoid idle consumers.\nconst DEFAULT_MEMBERS_TO_PARTITIONS_RATIO = 1 // How many members are in comparison to partitions, this is used to determine if the consumer group has room for more members. Numbers over 1 leads to idle consumers. Numbers under 1 needs partitionsConsumedConcurrently to be more than 1.\n\n/**\n * Manages the Kafka connection and the consumers.\n */\nclass KafkaManager {\n kafka: Kafka\n options: EchoesOptions\n producer: Producer\n consumer: Consumer\n topics: string[]\n started: boolean\n interval: NodeJS.Timer\n\n constructor(options: EchoesOptions) {\n this.kafka = new Kafka(options.client)\n this.options = options\n this.producer = this.kafka.producer(options.producer)\n this.consumer = this.kafka.consumer(options.consumer)\n this.topics = Object.keys(options.echoes).filter(\n key => options.echoes[key].type === types.event,\n )\n }\n\n async checkJoinConsumerGroupConditions(): Promise<boolean> {\n const admin = this.kafka.admin()\n try {\n await admin.connect()\n const groupDescriptions = await admin.describeGroups([this.options.consumer.groupId])\n const group = groupDescriptions.groups[0]\n if (group.state === 'Empty') {\n console.info(`Echoes: Consumer group ${this.options.consumer.groupId} is empty, joining`)\n return true\n }\n const topicsMetadata = await admin.fetchTopicMetadata({topics: this.topics})\n const totalPartitions = topicsMetadata.topics.reduce(\n (acc, topic) => acc + topic.partitions.length,\n 0,\n )\n console.info(\n `Echoes: Consumer group ${this.options.consumer.groupId} has ${group.members.length} members and ${totalPartitions} partitions`,\n )\n const partitionsRatio =\n this.options.membersToPartitionsRatio || DEFAULT_MEMBERS_TO_PARTITIONS_RATIO\n const partitionsThreshold = Math.ceil(totalPartitions * partitionsRatio)\n if (partitionsThreshold > group.members.length) {\n console.info(\n `Echoes: Consumer group ${this.options.consumer.groupId} has room for more members ${group.members.length}/${partitionsThreshold}, joining`,\n )\n return true\n }\n } catch (error) {\n console.error(`Echoes: Error checking consumer group conditions, join: ${error.message}`)\n return true\n } finally {\n await admin.disconnect().catch(error => {\n console.error(`Echoes: Error disconnecting admin client: ${error.message}`)\n })\n }\n }\n\n async joinConsumerGroup() {\n await this.consumer.connect()\n await this.consumer.subscribe({topics: this.topics})\n await this.consumer.run({\n partitionsConsumedConcurrently:\n this.options.partitionsConsumedConcurrently || DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY,\n eachMessage: params => this.handleMessage(params),\n })\n }\n\n async conditionalStart(): Promise<boolean> {\n if (await this.checkJoinConsumerGroupConditions()) {\n await this.joinConsumerGroup()\n return true\n }\n }\n\n async start() {\n if (this.started) return\n await this.producer.connect()\n this.started = await this.conditionalStart()\n if (this.started) return\n console.info('Echoes: Delaying consumer group join, waiting for conditions to be met')\n this.interval = setInterval(async () => {\n this.started = await this.conditionalStart()\n if (this.started) clearInterval(this.interval)\n }, CHECK_JOIN_CONSUMER_INTERVAL_SECONDS * 1000)\n }\n\n async stop() {\n console.warn('Echoes: Stopping echoes')\n if (this.interval) clearInterval(this.interval)\n if (this.consumer) await this.consumer.disconnect()\n if (this.producer) await this.producer.disconnect()\n }\n\n async handleMessage(params: EachMessagePayload) {\n const echo = this.options.echoes[params.topic]\n if (!echo || echo.type !== types.event) {\n console.warn(`Echoes: Received a message for an unknown topic: ${params.topic}, ignoring it`)\n return\n }\n\n let intervalsCount = 0\n const heartbeatInterval = setInterval(async () => {\n await params.heartbeat().catch(error => {\n console.warn(`Echoes: Error sending heartbeat: ${error.message}`)\n })\n intervalsCount++\n if ((intervalsCount * HEARTBEAT_INTERVAL_SECONDS) % 30 === 0) {\n console.warn(\n `Echoes: Event is taking too long to process: ${params.topic} ${intervalsCount * HEARTBEAT_INTERVAL_SECONDS}s`,\n )\n }\n }, HEARTBEAT_INTERVAL_SECONDS * 1000)\n\n try {\n await echo.onMessage(params).catch(error => this.handleRetries(echo, params, error))\n } catch (error) {\n console.error(`Echoes: error processing a message: ${params.topic} ${error.message}`)\n throw error\n } finally {\n clearInterval(heartbeatInterval)\n }\n }\n\n async handleRetries(echo: EchoType, params: EachMessagePayload, error: Error) {\n const {message, topic} = params\n const retries = Number.parseInt(message?.headers?.retries?.toString() || '0', 10)\n if (echo.attemptsBeforeDeadLetter === undefined || echo.attemptsBeforeDeadLetter === null) {\n throw error\n }\n const maxRetries = echo.attemptsBeforeDeadLetter || 0\n const exceededMaxRetries = retries >= maxRetries\n const nextTopic = exceededMaxRetries ? `DLQ-${topic}` : topic\n await this.producer.send({\n topic: nextTopic,\n messages: [\n {\n value: message.value.toString(),\n headers: {\n retries: String(retries + 1),\n error: error.message,\n },\n },\n ],\n })\n\n if (exceededMaxRetries) {\n console.error(\n `Echoes: a message has reached the maximum number of retries, sending it to DLQ: ${nextTopic}`,\n )\n } else {\n console.warn(\n `Echoes: a retryable message failed \"${error.message}\", re-sending it to topic: ${nextTopic}`,\n )\n }\n }\n}\n\nexport default KafkaManager\n","import config from '../config'\nimport requestsHandler from '../requestsHandler'\nimport {EchoesOptions} from '../types'\nimport KafkaManager from './KafkaManager'\nimport {registerRoute} from '@orion-js/http'\n\nlet kafkaManager: KafkaManager = null\n\nexport default async function startService(options: EchoesOptions) {\n config.echoes = options.echoes\n\n if (options.requests) {\n config.requests = options.requests\n registerRoute(requestsHandler(options))\n }\n\n if (options.client) {\n kafkaManager = new KafkaManager(options)\n await kafkaManager.start()\n config.producer = kafkaManager.producer\n config.consumer = kafkaManager.consumer\n }\n}\n\nexport async function stopService() {\n if (kafkaManager) {\n console.info('Stoping echoes...')\n await kafkaManager.stop()\n console.info('Echoes stopped')\n }\n}\n","import config from '../config'\nimport {PublishOptions} from '../types'\nimport serialize from './serialize'\n\n/**\n * Publish\n */\nexport default async function publish<TParams = any>(options: PublishOptions<TParams>) {\n if (!config.producer) {\n throw new Error('You must initialize echoes configruation to use publish')\n }\n\n const payload = {\n params: options.params,\n }\n\n return await config.producer.send({\n acks: options.acks,\n timeout: options.timeout,\n topic: options.topic,\n messages: [\n {\n value: serialize(payload),\n },\n ],\n })\n}\n","export default function (serializedJavascript: string): any {\n try {\n return eval('(' + serializedJavascript + ')')\n } catch (error) {\n throw new Error('Error deserializing echo message')\n }\n}\n","import {EachMessagePayload} from 'kafkajs'\nimport {EchoType, EchoConfig} from '../types'\nimport deserialize from './deserialize'\nimport types from './types'\n\nconst echo = function createNewEcho(options: EchoConfig): EchoType {\n return {\n ...options,\n onMessage: async (messageData: EachMessagePayload) => {\n const {message} = messageData\n\n const data = deserialize(message.value.toString())\n\n const context = {\n ...messageData,\n data\n }\n\n await options.resolve(data.params || {}, context)\n },\n onRequest: async (serializedParams: string) => {\n const context = {}\n const params = deserialize(serializedParams)\n const result = await options.resolve(params || {}, context)\n return result\n }\n }\n}\n\necho.types = types\n\nexport default echo\n","import config from '../config'\n\nexport default function (serviceName: string): string {\n if (serviceName.startsWith('http')) return serviceName\n\n const url = config?.requests?.services[serviceName]\n\n if (!url) {\n throw new Error(`No URL found in echoes config for service ${serviceName}`)\n }\n\n return url\n}\n","import axios from 'axios'\nimport {RequestMaker} from '../types'\nimport {executeWithRetries} from '@orion-js/helpers'\n\nexport const makeRequest: RequestMaker = async options => {\n const result = await executeWithRetries(\n async () => {\n return await axios({\n method: 'post',\n url: options.url,\n timeout: options.timeout,\n headers: {\n 'User-Agent': 'Orionjs-Echoes/1.1'\n },\n data: options.data\n })\n },\n options.retries,\n 200\n )\n\n return {\n data: result.data as object,\n statusCode: result.status\n }\n}\n","import getURL from './getURL'\nimport getSignature from './getSignature'\nimport serialize from '../publish/serialize'\nimport deserialize from '../echo/deserialize'\nimport type {\n MakeRequestParams,\n RequestHandlerResponse,\n RequestMaker,\n RequestOptions,\n} from '../types'\nimport config from '../config'\nimport {makeRequest} from './makeRequest'\nimport {ValidationError} from '@orion-js/schema'\nimport {UserError} from '@orion-js/helpers'\n\nexport default async function request<TData = any, TParams = any>(\n options: RequestOptions<TParams>,\n): Promise<TData> {\n const {method, service, params} = options\n const serializedParams = serialize(params)\n const date = new Date()\n const body = {method, service, serializedParams, date}\n const signature = getSignature(body)\n\n try {\n const requestMaker: RequestMaker = config?.requests?.makeRequest || makeRequest\n const requestOptions: MakeRequestParams = {\n url: getURL(service),\n retries: options.retries,\n timeout: options.timeout,\n data: {\n body,\n signature,\n },\n }\n const result = await requestMaker(requestOptions)\n\n if (result.statusCode !== 200) {\n throw new Error(`Wrong status code ${result.statusCode}`)\n }\n\n const data: RequestHandlerResponse = result.data\n\n if (data.error) {\n const info = data.errorInfo\n if (info) {\n if (data.isValidationError) {\n throw new ValidationError(info.validationErrors)\n }\n if (data.isUserError) {\n throw new UserError(info.error, info.message, info.extra)\n }\n }\n\n throw new Error(`${data.error}`)\n }\n\n const response = deserialize(data.result)\n return response\n } catch (error) {\n if (error.isOrionError) throw error\n\n throw new Error(`Echoes request network error calling ${service}/${method}: ${error.message}`)\n }\n}\n","import {getInstance, Service} from '@orion-js/services'\nimport echo from '../echo'\nimport {EchoConfig, EchoesMap} from '../types'\n\nexport function Echoes(): ClassDecorator {\n return function (target: any) {\n Service()(target)\n target.prototype.service = target\n }\n}\n\nexport interface EchoesPropertyDescriptor extends Omit<PropertyDecorator, 'value'> {\n value?: EchoConfig['resolve']\n}\n\nexport function EchoRequest(options: Omit<EchoConfig, 'resolve' | 'type'> = {}) {\n return function (target: any, propertyKey: string, descriptor: EchoesPropertyDescriptor) {\n if (!descriptor.value) throw new Error(`You must pass resolver function to ${propertyKey}`)\n\n target.echoes = target.echoes || {}\n target.echoes[propertyKey] = echo({\n ...options,\n type: 'request',\n resolve: async (params, viewer) => {\n const instance: any = getInstance(target.service)\n return await instance[propertyKey](params, viewer)\n }\n })\n }\n}\n\nexport function EchoEvent(options: Omit<EchoConfig, 'resolve' | 'type'> = {}) {\n return function (target: any, propertyKey: string, descriptor: EchoesPropertyDescriptor) {\n if (!descriptor.value) throw new Error(`You must pass resolver function to ${propertyKey}`)\n\n target.echoes = target.echoes || {}\n target.echoes[propertyKey] = echo({\n ...options,\n type: 'event',\n resolve: async (params, viewer) => {\n const instance: any = getInstance(target.service)\n return await instance[propertyKey](params, viewer)\n }\n })\n }\n}\n\nexport function getServiceEchoes(target: any): EchoesMap {\n if (!target.prototype) {\n throw new Error('You must pass a class to getServiceRoutes')\n }\n\n return target.prototype.echoes || {}\n}\n"],"mappings":";AAEA,IAAM,SAA8B,CAAC;AAErC,IAAO,iBAAQ;;;ACJf,IAAO,gBAAQ;AAAA,EACb,OAAO;AAAA,EACP,SAAS;AACX;;;ACAe,SAAR,gBAAkB,QAAgB;AACvC,QAAMA,QAAO,eAAO,OAAO,MAAM;AAEjC,MAAI,CAACA,OAAM;AACT,UAAM,IAAI,MAAM,cAAc,MAAM,4BAA4B;AAAA,EAClE;AAEA,MAAIA,MAAK,SAAS,cAAM,SAAS;AAC/B,UAAM,IAAI,MAAM,cAAc,MAAM,yBAAyB;AAAA,EAC/D;AAEA,SAAOA;AACT;;;ACfA,OAAO,eAAe;AACtB,OAAO,eAAe;AAEP,SAAR,kBAAkB,MAAmB;AAC1C,QAAM,SAAS,UAAU,IAAI;AAC7B,QAAM,aAAa,UAAU,QAAQ,EAAC,gBAAgB,KAAI,CAAC;AAC3D,SAAO;AACT;;;ACPA,OAAO,WAAW;;;ACClB,SAAQ,sBAAqB;AAEtB,SAAS,oBAAoB;AAHpC;AAIE,QAAM,WAAS,iDAAQ,aAAR,mBAAkB,QAAO,eAAe,mBAAmB,iBAAiB;AAC3F,MAAI,CAAC,QAAQ;AACX,YAAQ;AAAA,MACN;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;ADTe,SAAR,qBAAkB,MAAmB;AAC1C,QAAM,WAAW,kBAAkB;AACnC,QAAM,SAAS,IAAI,MAAM,SAAS,MAAM;AACxC,SAAO,WAAW,UAAU,MAAM;AAClC,SAAO,OAAO,IAAI;AAClB,SAAO,OAAO,QAAQ,KAAK;AAC7B;;;AEPe,SAAR,uBAAkB,MAAW,WAAmB;AACrD,QAAM,qBAAqB,qBAAa,IAAI;AAC5C,MAAI,uBAAuB,WAAW;AACpC,UAAM,IAAI,MAAM,0BAA0B;AAAA,EAC5C;AACF;;;ACJA,SAAQ,aAAY;AAGpB,IAAO,0BAAQ,CAAC,YACd,MAAM;AAAA,EACJ,QAAQ;AAAA,EACR,MAAM,QAAQ,SAAS,eAAe;AAAA,EACtC,YAAY;AAAA,EACZ,mBAAmB;AAAA,IACjB,OAAO;AAAA,EACT;AAAA,EACA,MAAM,QAAQ,KAAK;AACjB,QAAI;AACF,YAAM,EAAC,MAAM,UAAS,IAAI,IAAI;AAE9B,6BAAe,MAAM,SAAS;AAE9B,YAAM,EAAC,QAAQ,iBAAgB,IAAI;AAEnC,YAAMC,QAAO,gBAAQ,MAAM;AAC3B,YAAM,SAAS,MAAMA,MAAK,UAAU,gBAAgB;AAEpD,aAAO;AAAA,QACL,MAAM;AAAA,UACJ,QAAQ,kBAAU,MAAM;AAAA,QAC1B;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,UAAI,CAAC,MAAM,SAAS;AAClB,gBAAQ,MAAM,mCAAmC,KAAK;AAAA,MACxD;AAEA,aAAO;AAAA,QACL,MAAM;AAAA,UACJ,OAAO,MAAM;AAAA,UACb,WAAW,MAAM,UAAU,MAAM,QAAQ,IAAI;AAAA,UAC7C,mBAAmB,CAAC,CAAC,MAAM;AAAA,UAC3B,aAAa,CAAC,CAAC,MAAM;AAAA,QACvB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF,CAAC;;;AC7CH,SAAQ,aAAoD;AAI5D,IAAM,6BAA6B;AACnC,IAAM,uCAAuC;AAC7C,IAAM,2CAA2C;AACjD,IAAM,sCAAsC;AAK5C,IAAM,eAAN,MAAmB;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,SAAwB;AAClC,SAAK,QAAQ,IAAI,MAAM,QAAQ,MAAM;AACrC,SAAK,UAAU;AACf,SAAK,WAAW,KAAK,MAAM,SAAS,QAAQ,QAAQ;AACpD,SAAK,WAAW,KAAK,MAAM,SAAS,QAAQ,QAAQ;AACpD,SAAK,SAAS,OAAO,KAAK,QAAQ,MAAM,EAAE;AAAA,MACxC,SAAO,QAAQ,OAAO,GAAG,EAAE,SAAS,cAAM;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,MAAM,mCAAqD;AACzD,UAAM,QAAQ,KAAK,MAAM,MAAM;AAC/B,QAAI;AACF,YAAM,MAAM,QAAQ;AACpB,YAAM,oBAAoB,MAAM,MAAM,eAAe,CAAC,KAAK,QAAQ,SAAS,OAAO,CAAC;AACpF,YAAM,QAAQ,kBAAkB,OAAO,CAAC;AACxC,UAAI,MAAM,UAAU,SAAS;AAC3B,gBAAQ,KAAK,0BAA0B,KAAK,QAAQ,SAAS,OAAO,oBAAoB;AACxF,eAAO;AAAA,MACT;AACA,YAAM,iBAAiB,MAAM,MAAM,mBAAmB,EAAC,QAAQ,KAAK,OAAM,CAAC;AAC3E,YAAM,kBAAkB,eAAe,OAAO;AAAA,QAC5C,CAAC,KAAK,UAAU,MAAM,MAAM,WAAW;AAAA,QACvC;AAAA,MACF;AACA,cAAQ;AAAA,QACN,0BAA0B,KAAK,QAAQ,SAAS,OAAO,QAAQ,MAAM,QAAQ,MAAM,gBAAgB,eAAe;AAAA,MACpH;AACA,YAAM,kBACJ,KAAK,QAAQ,4BAA4B;AAC3C,YAAM,sBAAsB,KAAK,KAAK,kBAAkB,eAAe;AACvE,UAAI,sBAAsB,MAAM,QAAQ,QAAQ;AAC9C,gBAAQ;AAAA,UACN,0BAA0B,KAAK,QAAQ,SAAS,OAAO,8BAA8B,MAAM,QAAQ,MAAM,IAAI,mBAAmB;AAAA,QAClI;AACA,eAAO;AAAA,MACT;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,2DAA2D,MAAM,OAAO,EAAE;AACxF,aAAO;AAAA,IACT,UAAE;AACA,YAAM,MAAM,WAAW,EAAE,MAAM,WAAS;AACtC,gBAAQ,MAAM,6CAA6C,MAAM,OAAO,EAAE;AAAA,MAC5E,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,oBAAoB;AACxB,UAAM,KAAK,SAAS,QAAQ;AAC5B,UAAM,KAAK,SAAS,UAAU,EAAC,QAAQ,KAAK,OAAM,CAAC;AACnD,UAAM,KAAK,SAAS,IAAI;AAAA,MACtB,gCACE,KAAK,QAAQ,kCAAkC;AAAA,MACjD,aAAa,YAAU,KAAK,cAAc,MAAM;AAAA,IAClD,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,mBAAqC;AACzC,QAAI,MAAM,KAAK,iCAAiC,GAAG;AACjD,YAAM,KAAK,kBAAkB;AAC7B,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ;AACZ,QAAI,KAAK,QAAS;AAClB,UAAM,KAAK,SAAS,QAAQ;AAC5B,SAAK,UAAU,MAAM,KAAK,iBAAiB;AAC3C,QAAI,KAAK,QAAS;AAClB,YAAQ,KAAK,wEAAwE;AACrF,SAAK,WAAW,YAAY,YAAY;AACtC,WAAK,UAAU,MAAM,KAAK,iBAAiB;AAC3C,UAAI,KAAK,QAAS,eAAc,KAAK,QAAQ;AAAA,IAC/C,GAAG,uCAAuC,GAAI;AAAA,EAChD;AAAA,EAEA,MAAM,OAAO;AACX,YAAQ,KAAK,yBAAyB;AACtC,QAAI,KAAK,SAAU,eAAc,KAAK,QAAQ;AAC9C,QAAI,KAAK,SAAU,OAAM,KAAK,SAAS,WAAW;AAClD,QAAI,KAAK,SAAU,OAAM,KAAK,SAAS,WAAW;AAAA,EACpD;AAAA,EAEA,MAAM,cAAc,QAA4B;AAC9C,UAAMC,QAAO,KAAK,QAAQ,OAAO,OAAO,KAAK;AAC7C,QAAI,CAACA,SAAQA,MAAK,SAAS,cAAM,OAAO;AACtC,cAAQ,KAAK,oDAAoD,OAAO,KAAK,eAAe;AAC5F;AAAA,IACF;AAEA,QAAI,iBAAiB;AACrB,UAAM,oBAAoB,YAAY,YAAY;AAChD,YAAM,OAAO,UAAU,EAAE,MAAM,WAAS;AACtC,gBAAQ,KAAK,oCAAoC,MAAM,OAAO,EAAE;AAAA,MAClE,CAAC;AACD;AACA,UAAK,iBAAiB,6BAA8B,OAAO,GAAG;AAC5D,gBAAQ;AAAA,UACN,gDAAgD,OAAO,KAAK,IAAI,iBAAiB,0BAA0B;AAAA,QAC7G;AAAA,MACF;AAAA,IACF,GAAG,6BAA6B,GAAI;AAEpC,QAAI;AACF,YAAMA,MAAK,UAAU,MAAM,EAAE,MAAM,WAAS,KAAK,cAAcA,OAAM,QAAQ,KAAK,CAAC;AAAA,IACrF,SAAS,OAAO;AACd,cAAQ,MAAM,uCAAuC,OAAO,KAAK,IAAI,MAAM,OAAO,EAAE;AACpF,YAAM;AAAA,IACR,UAAE;AACA,oBAAc,iBAAiB;AAAA,IACjC;AAAA,EACF;AAAA,EAEA,MAAM,cAAcA,OAAgB,QAA4B,OAAc;AAtIhF;AAuII,UAAM,EAAC,SAAS,MAAK,IAAI;AACzB,UAAM,UAAU,OAAO,WAAS,8CAAS,YAAT,mBAAkB,YAAlB,mBAA2B,eAAc,KAAK,EAAE;AAChF,QAAIA,MAAK,6BAA6B,UAAaA,MAAK,6BAA6B,MAAM;AACzF,YAAM;AAAA,IACR;AACA,UAAM,aAAaA,MAAK,4BAA4B;AACpD,UAAM,qBAAqB,WAAW;AACtC,UAAM,YAAY,qBAAqB,OAAO,KAAK,KAAK;AACxD,UAAM,KAAK,SAAS,KAAK;AAAA,MACvB,OAAO;AAAA,MACP,UAAU;AAAA,QACR;AAAA,UACE,OAAO,QAAQ,MAAM,SAAS;AAAA,UAC9B,SAAS;AAAA,YACP,SAAS,OAAO,UAAU,CAAC;AAAA,YAC3B,OAAO,MAAM;AAAA,UACf;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAED,QAAI,oBAAoB;AACtB,cAAQ;AAAA,QACN,mFAAmF,SAAS;AAAA,MAC9F;AAAA,IACF,OAAO;AACL,cAAQ;AAAA,QACN,uCAAuC,MAAM,OAAO,8BAA8B,SAAS;AAAA,MAC7F;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAO,uBAAQ;;;ACpKf,SAAQ,qBAAoB;AAE5B,IAAI,eAA6B;AAEjC,eAAO,aAAoC,SAAwB;AACjE,iBAAO,SAAS,QAAQ;AAExB,MAAI,QAAQ,UAAU;AACpB,mBAAO,WAAW,QAAQ;AAC1B,kBAAc,wBAAgB,OAAO,CAAC;AAAA,EACxC;AAEA,MAAI,QAAQ,QAAQ;AAClB,mBAAe,IAAI,qBAAa,OAAO;AACvC,UAAM,aAAa,MAAM;AACzB,mBAAO,WAAW,aAAa;AAC/B,mBAAO,WAAW,aAAa;AAAA,EACjC;AACF;AAEA,eAAsB,cAAc;AAClC,MAAI,cAAc;AAChB,YAAQ,KAAK,mBAAmB;AAChC,UAAM,aAAa,KAAK;AACxB,YAAQ,KAAK,gBAAgB;AAAA,EAC/B;AACF;;;ACvBA,eAAO,QAA8C,SAAkC;AACrF,MAAI,CAAC,eAAO,UAAU;AACpB,UAAM,IAAI,MAAM,yDAAyD;AAAA,EAC3E;AAEA,QAAM,UAAU;AAAA,IACd,QAAQ,QAAQ;AAAA,EAClB;AAEA,SAAO,MAAM,eAAO,SAAS,KAAK;AAAA,IAChC,MAAM,QAAQ;AAAA,IACd,SAAS,QAAQ;AAAA,IACjB,OAAO,QAAQ;AAAA,IACf,UAAU;AAAA,MACR;AAAA,QACE,OAAO,kBAAU,OAAO;AAAA,MAC1B;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;AC1Be,SAAR,oBAAkB,sBAAmC;AAC1D,MAAI;AACF,WAAO,KAAK,MAAM,uBAAuB,GAAG;AAAA,EAC9C,SAAS,OAAO;AACd,UAAM,IAAI,MAAM,kCAAkC;AAAA,EACpD;AACF;;;ACDA,IAAM,OAAO,SAAS,cAAc,SAA+B;AACjE,SAAO;AAAA,IACL,GAAG;AAAA,IACH,WAAW,OAAO,gBAAoC;AACpD,YAAM,EAAC,QAAO,IAAI;AAElB,YAAM,OAAO,oBAAY,QAAQ,MAAM,SAAS,CAAC;AAEjD,YAAM,UAAU;AAAA,QACd,GAAG;AAAA,QACH;AAAA,MACF;AAEA,YAAM,QAAQ,QAAQ,KAAK,UAAU,CAAC,GAAG,OAAO;AAAA,IAClD;AAAA,IACA,WAAW,OAAO,qBAA6B;AAC7C,YAAM,UAAU,CAAC;AACjB,YAAM,SAAS,oBAAY,gBAAgB;AAC3C,YAAM,SAAS,MAAM,QAAQ,QAAQ,UAAU,CAAC,GAAG,OAAO;AAC1D,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,KAAK,QAAQ;AAEb,IAAO,eAAQ;;;AC7BA,SAAR,eAAkB,aAA6B;AAFtD;AAGE,MAAI,YAAY,WAAW,MAAM,EAAG,QAAO;AAE3C,QAAM,OAAM,iDAAQ,aAAR,mBAAkB,SAAS;AAEvC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,6CAA6C,WAAW,EAAE;AAAA,EAC5E;AAEA,SAAO;AACT;;;ACZA,OAAO,WAAW;AAElB,SAAQ,0BAAyB;AAE1B,IAAM,cAA4B,OAAM,YAAW;AACxD,QAAM,SAAS,MAAM;AAAA,IACnB,YAAY;AACV,aAAO,MAAM,MAAM;AAAA,QACjB,QAAQ;AAAA,QACR,KAAK,QAAQ;AAAA,QACb,SAAS,QAAQ;AAAA,QACjB,SAAS;AAAA,UACP,cAAc;AAAA,QAChB;AAAA,QACA,MAAM,QAAQ;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM,OAAO;AAAA,IACb,YAAY,OAAO;AAAA,EACrB;AACF;;;ACbA,SAAQ,uBAAsB;AAC9B,SAAQ,iBAAgB;AAExB,eAAO,QACL,SACgB;AAjBlB;AAkBE,QAAM,EAAC,QAAQ,SAAS,OAAM,IAAI;AAClC,QAAM,mBAAmB,kBAAU,MAAM;AACzC,QAAM,OAAO,oBAAI,KAAK;AACtB,QAAM,OAAO,EAAC,QAAQ,SAAS,kBAAkB,KAAI;AACrD,QAAM,YAAY,qBAAa,IAAI;AAEnC,MAAI;AACF,UAAM,iBAA6B,iDAAQ,aAAR,mBAAkB,gBAAe;AACpE,UAAM,iBAAoC;AAAA,MACxC,KAAK,eAAO,OAAO;AAAA,MACnB,SAAS,QAAQ;AAAA,MACjB,SAAS,QAAQ;AAAA,MACjB,MAAM;AAAA,QACJ;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,UAAM,SAAS,MAAM,aAAa,cAAc;AAEhD,QAAI,OAAO,eAAe,KAAK;AAC7B,YAAM,IAAI,MAAM,qBAAqB,OAAO,UAAU,EAAE;AAAA,IAC1D;AAEA,UAAM,OAA+B,OAAO;AAE5C,QAAI,KAAK,OAAO;AACd,YAAM,OAAO,KAAK;AAClB,UAAI,MAAM;AACR,YAAI,KAAK,mBAAmB;AAC1B,gBAAM,IAAI,gBAAgB,KAAK,gBAAgB;AAAA,QACjD;AACA,YAAI,KAAK,aAAa;AACpB,gBAAM,IAAI,UAAU,KAAK,OAAO,KAAK,SAAS,KAAK,KAAK;AAAA,QAC1D;AAAA,MACF;AAEA,YAAM,IAAI,MAAM,GAAG,KAAK,KAAK,EAAE;AAAA,IACjC;AAEA,UAAM,WAAW,oBAAY,KAAK,MAAM;AACxC,WAAO;AAAA,EACT,SAAS,OAAO;AACd,QAAI,MAAM,aAAc,OAAM;AAE9B,UAAM,IAAI,MAAM,wCAAwC,OAAO,IAAI,MAAM,KAAK,MAAM,OAAO,EAAE;AAAA,EAC/F;AACF;;;AChEA,SAAQ,aAAa,eAAc;AAI5B,SAAS,SAAyB;AACvC,SAAO,SAAU,QAAa;AAC5B,YAAQ,EAAE,MAAM;AAChB,WAAO,UAAU,UAAU;AAAA,EAC7B;AACF;AAMO,SAAS,YAAY,UAAgD,CAAC,GAAG;AAC9E,SAAO,SAAU,QAAa,aAAqB,YAAsC;AACvF,QAAI,CAAC,WAAW,MAAO,OAAM,IAAI,MAAM,sCAAsC,WAAW,EAAE;AAE1F,WAAO,SAAS,OAAO,UAAU,CAAC;AAClC,WAAO,OAAO,WAAW,IAAI,aAAK;AAAA,MAChC,GAAG;AAAA,MACH,MAAM;AAAA,MACN,SAAS,OAAO,QAAQ,WAAW;AACjC,cAAM,WAAgB,YAAY,OAAO,OAAO;AAChD,eAAO,MAAM,SAAS,WAAW,EAAE,QAAQ,MAAM;AAAA,MACnD;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEO,SAAS,UAAU,UAAgD,CAAC,GAAG;AAC5E,SAAO,SAAU,QAAa,aAAqB,YAAsC;AACvF,QAAI,CAAC,WAAW,MAAO,OAAM,IAAI,MAAM,sCAAsC,WAAW,EAAE;AAE1F,WAAO,SAAS,OAAO,UAAU,CAAC;AAClC,WAAO,OAAO,WAAW,IAAI,aAAK;AAAA,MAChC,GAAG;AAAA,MACH,MAAM;AAAA,MACN,SAAS,OAAO,QAAQ,WAAW;AACjC,cAAM,WAAgB,YAAY,OAAO,OAAO;AAChD,eAAO,MAAM,SAAS,WAAW,EAAE,QAAQ,MAAM;AAAA,MACnD;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEO,SAAS,iBAAiB,QAAwB;AACvD,MAAI,CAAC,OAAO,WAAW;AACrB,UAAM,IAAI,MAAM,2CAA2C;AAAA,EAC7D;AAEA,SAAO,OAAO,UAAU,UAAU,CAAC;AACrC;","names":["echo","echo","echo"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orion-js/echoes",
|
|
3
|
-
"version": "4.0.0-next.
|
|
3
|
+
"version": "4.0.0-next.3",
|
|
4
4
|
"main": "./dist/index.cjs",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
"kafkajs": "^2.2.4",
|
|
15
15
|
"lodash": "^4.17.21",
|
|
16
16
|
"serialize-javascript": "^6.0.0",
|
|
17
|
-
"@orion-js/env": "4.0.0-next.
|
|
18
|
-
"@orion-js/helpers": "4.0.0-next.
|
|
19
|
-
"@orion-js/
|
|
20
|
-
"@orion-js/schema": "4.0.0-next.
|
|
21
|
-
"@orion-js/
|
|
17
|
+
"@orion-js/env": "4.0.0-next.3",
|
|
18
|
+
"@orion-js/helpers": "4.0.0-next.3",
|
|
19
|
+
"@orion-js/services": "4.0.0-next.3",
|
|
20
|
+
"@orion-js/schema": "4.0.0-next.3",
|
|
21
|
+
"@orion-js/http": "4.0.0-next.3"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@types/supertest": "2.0.11",
|